1 /*
2  * Copyright (c) 2017-2019 sel-project
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in all
12  * copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20  * SOFTWARE.
21  *
22  */
23 /**
24  * Copyright: Copyright (c) 2017-2019 sel-project
25  * License: MIT
26  * Authors: Kripth
27  * Source: $(HTTP github.com/sel-project/selery/source/selery/about.d, selery/about.d)
28  */
29 module selery.about;
30 
31 import std.algorithm : sort, reverse, canFind;
32 import std.conv : to;
33 import std.json : JSONValue;
34 import std..string : toLower, split, join, startsWith;
35 import std.typetuple : TypeTuple;
36 
37 alias suuid_t = immutable(ubyte)[17];
38 
39 alias tick_t = size_t;
40 
41 alias block_t = ushort;
42 
43 alias item_t = size_t;
44 
45 /**
46  * Informations about the software, like name, codename,
47  * versions and protocols used.
48  */
49 const struct Software {
50 	
51 	@disable this();
52 	
53 	/**
54 	 * Formatted name of the software.
55 	 * It should be used for display and usage purposes.
56 	 * Example:
57 	 * ---
58 	 * writeln("You're running ", Software.name, " based on SEL");
59 	 * ---
60 	 */
61 	enum string name = "Selery";
62 	
63 	/**
64 	 * Lowercase name of the software.
65 	 * Example:
66 	 * ---
67 	 * assert(Software.name.toLower == Software.lname);
68 	 * ---
69 	 */
70 	enum string lname = name.toLower;
71 	
72 	/**
73 	 * Website of the software.
74 	 * Source code should be at website/source and downloads
75 	 * at website/downloads.
76 	 * Example:
77 	 * ---
78 	 * download("http://" ~ Software.website ~ "/downloads/1.0.0.sa", "1.0.0.sa");
79 	 * ---
80 	 */
81 	enum string website = "";
82 	
83 	/**
84 	 * Codename and representations related to the version or
85 	 * the group of versions of the software.
86 	 * Used only for display purposes.
87 	 */
88 	enum string codename = "Cookie";
89 	
90 	/// ditto
91 	enum string codenameEmoji = "🍪";
92 	
93 	/// ditto
94 	enum string fullCodename = codename ~ " (" ~ codenameEmoji ~ ")";
95 	
96 	/**
97 	 * Version of the software.
98 	 */
99 	enum ubyte major = 0;
100 	
101 	/// ditto
102 	enum ubyte minor = 3;
103 	
104 	/// ditto
105 	enum ubyte patch = 0;
106 	
107 	/// ditto
108 	enum ubyte[3] versions = [major, minor, patch];
109 	
110 	/**
111 	 * Version of the software in format major.minor.patch following the
112 	 * $(HTTP http://semver.org, Semantic Version 2.0.0) (for example
113 	 * `1.1.0`) for display purposes.
114 	 */
115 	enum string displayVersion = to!string(major) ~ "." ~ to!string(minor) ~ "." ~ to!string(patch);
116 	
117 	/**
118 	 * Full version of the software prefixed with a `v` and suffixed
119 	 * with a build version if the version is not stable.
120 	 */
121 	enum string fullVersion = "v" ~ displayVersion;
122 	
123 	/**
124 	 * Display name of the software that contains both the software name
125 	 * and the version in the format name/version (for example `Selery/0.0.1`).
126 	 */
127 	enum string display = name ~ "/" ~ displayVersion;
128 
129 	enum string simpleDisplay = name ~ " " ~ to!string(major) ~ "." ~ to!string(minor) ~ (patch != 0 ? "." ~ to!string(patch) : "");
130 	
131 	/+/**
132 	 * Version of the api used by the software. It's used to check the
133 	 * compatibility with plugins.
134 	 */
135 	enum ubyte api = 1;+/
136 
137 	public static JSONValue toJSON() {
138 		JSONValue[string] ret;
139 		foreach(member ; TypeTuple!("name", /*"website",*/ "displayVersion", "fullVersion", "codename", "display")) {
140 			ret[member] = JSONValue(mixin(member));
141 		}
142 		ret["version"] = ["major": major, "minor": minor, "patch": patch];
143 		return JSONValue(ret);
144 	}
145 	
146 }
147 
148 /// Protocols supported by the software.
149 enum uint[] supportedBedrockProtocols = [137, 141, 150, 160];
150 
151 /// ditto
152 enum uint[] supportedJavaProtocols = [210, 315, 316, 335, 338, 340];
153 
154 /// Newest protocol supported.
155 enum newestBedrockProtocol = supportedBedrockProtocols[$-1];
156 
157 /// ditto
158 enum newestJavaProtocol = supportedJavaProtocols[$-1];
159 
160 /// Latest protocols (latest version e.g 1.2.*).
161 enum uint[] latestBedrockProtocols = [137, 141, 150, 160];
162 
163 /// ditto
164 enum uint[] latestJavaProtocols = [335, 338, 340];
165 
166 /// Tuples with the supported protocols.
167 alias SupportedBedrockProtocols = ProtocolsImpl!(supportedBedrockProtocols);
168 
169 /// ditto
170 alias SupportedJavaProtocols = ProtocolsImpl!(supportedJavaProtocols);
171 
172 private template ProtocolsImpl(uint[] protocols, E...) {
173 	static if(protocols.length) {
174 		alias ProtocolsImpl = ProtocolsImpl!(protocols[1..$], E, protocols[0]);
175 	} else {
176 		alias ProtocolsImpl = E;
177 	}
178 }
179 
180 uint[] validateProtocols(ref uint[] protocols, uint[] accepted, uint[] default_) {
181 	uint[] ret;
182 	foreach(protocol ; protocols) {
183 		if(accepted.canFind(protocol)) ret ~= protocol;
184 	}
185 	return (protocols = (ret.length ? ret : default_));
186 }
187 
188 version(D_Ddoc) {
189 
190 	/// Indicates whether the software has been tested on the current OS
191 	enum bool __supported = true;
192 
193 } else {
194 
195 	version(Windows) enum bool __supported = true;
196 	else version(linux) enum bool __supported = true;
197 	else version(FreeBSD) enum bool __supported = false;
198 	else version(OSX) enum bool __supported = false;
199 	else version(Android) enum bool __supported = false;
200 	else enum bool __supported = false;
201 
202 }