1 /*
2  * Copyright (c) 2017-2018 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: 2017-2018 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 
38 alias suuid_t = immutable(ubyte)[17];
39 
40 alias tick_t = size_t;
41 
42 alias block_t = ushort;
43 
44 alias item_t = size_t;
45 
46 
47 /**
48  * Informations about the software, like name, codename,
49  * versions and protocols used.
50  */
51 const struct Software {
52 	
53 	@disable this();
54 	
55 	/**
56 	 * Formatted name of the software.
57 	 * It should be used for display and usage purposes.
58 	 * Example:
59 	 * ---
60 	 * writeln("You're running ", Software.name, " based on SEL");
61 	 * ---
62 	 */
63 	enum string name = "Selery";
64 	
65 	/**
66 	 * Lowercase name of the software.
67 	 * Example:
68 	 * ---
69 	 * assert(Software.name.toLower == Software.lname);
70 	 * ---
71 	 */
72 	enum string lname = name.toLower;
73 	
74 	/**
75 	 * Website of the software.
76 	 * Source code should be at website/source and downloads
77 	 * at website/downloads.
78 	 * Example:
79 	 * ---
80 	 * download("http://" ~ Software.website ~ "/downloads/1.0.0.sa", "1.0.0.sa");
81 	 * ---
82 	 */
83 	enum string website = "";
84 	
85 	/**
86 	 * Codename and representations related to the version or
87 	 * the group of versions of the software.
88 	 * Used only for display purposes.
89 	 */
90 	enum string codename = "Cookie";
91 	
92 	/// ditto
93 	enum string codenameEmoji = "🍪";
94 	
95 	/// ditto
96 	enum string fullCodename = codename ~ " (" ~ codenameEmoji ~ ")";
97 	
98 	/**
99 	 * Version of the software.
100 	 */
101 	enum ubyte major = 0;
102 	
103 	/// ditto
104 	enum ubyte minor = 1;
105 	
106 	/// ditto
107 	enum ubyte patch = 1;
108 	
109 	/// ditto
110 	enum ubyte[3] versions = [major, minor, patch];
111 	
112 	/**
113 	 * Version of the software in format major.minor.patch following the
114 	 * $(HTTP http://semver.org, Semantic Version 2.0.0) (for example
115 	 * `1.1.0`) for display purposes.
116 	 */
117 	enum string displayVersion = to!string(major) ~ "." ~ to!string(minor) ~ "." ~ to!string(patch);
118 	
119 	/**
120 	 * Full version of the software prefixed with a `v` and suffixed
121 	 * with a build version if the version is not stable.
122 	 */
123 	enum string fullVersion = "v" ~ displayVersion;
124 	
125 	/**
126 	 * Display name of the software that contains both the software name
127 	 * and the version in the format name/version (for example `Selery/0.0.1`).
128 	 */
129 	enum string display = name ~ "/" ~ displayVersion;
130 
131 	enum string simpleDisplay = name ~ " " ~ to!string(major) ~ "." ~ to!string(minor) ~ (patch != 0 ? "." ~ to!string(patch) : "");
132 	
133 	/**
134 	 * Version of the api used by the software. It's used to check the
135 	 * compatibility with plugins.
136 	 */
137 	enum ubyte api = 1;
138 
139 	public static JSONValue toJSON() {
140 		JSONValue[string] ret;
141 		foreach(member ; TypeTuple!("name", "website", "displayVersion", "fullVersion", "codename", "display", "api")) {
142 			ret[member] = JSONValue(mixin(member));
143 		}
144 		ret["version"] = ["major": major, "minor": minor, "patch": patch];
145 		return JSONValue(ret);
146 	}
147 	
148 }
149 
150 /// Protocols supported by the software.
151 enum uint[] supportedBedrockProtocols = [137, 141, 150, 160];
152 
153 /// ditto
154 enum uint[] supportedJavaProtocols = [210, 315, 316, 335, 338, 340];
155 
156 /// Newest protocol supported.
157 enum newestBedrockProtocol = supportedBedrockProtocols[$-1];
158 
159 /// ditto
160 enum newestJavaProtocol = supportedJavaProtocols[$-1];
161 
162 /// Latest protocols (latest version e.g 1.2.*).
163 enum uint[] latestBedrockProtocols = [137, 141, 150, 160];
164 
165 /// ditto
166 enum uint[] latestJavaProtocols = [335, 338, 340];
167 
168 /// Tuples with the supported protocols.
169 alias SupportedBedrockProtocols = ProtocolsImpl!(supportedBedrockProtocols);
170 
171 /// ditto
172 alias SupportedJavaProtocols = ProtocolsImpl!(supportedJavaProtocols);
173 
174 private template ProtocolsImpl(uint[] protocols, E...) {
175 	static if(protocols.length) {
176 		alias ProtocolsImpl = ProtocolsImpl!(protocols[1..$], E, protocols[0]);
177 	} else {
178 		alias ProtocolsImpl = E;
179 	}
180 }
181 
182 uint[] validateProtocols(ref uint[] protocols, uint[] accepted, uint[] default_) {
183 	uint[] ret;
184 	foreach(protocol ; protocols) {
185 		if(accepted.canFind(protocol)) ret ~= protocol;
186 	}
187 	return (protocols = (ret.length ? ret : default_));
188 }
189 
190 version(D_Ddoc) {
191 
192 	/// Indicates whether the software has been tested on the current OS
193 	enum bool __supported = true;
194 
195 } else {
196 
197 	version(Windows) enum bool __supported = true;
198 	else version(linux) enum bool __supported = true;
199 	else version(FreeBSD) enum bool __supported = false;
200 	else version(OSX) enum bool __supported = false;
201 	else version(Android) enum bool __supported = false;
202 	else enum bool __supported = false;
203 
204 }