proper mojang api

This commit is contained in:
bixilon 2020-06-09 21:18:01 +02:00
parent 55231a5a65
commit b8a0e74434
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
18 changed files with 552 additions and 110 deletions

View File

@ -15,4 +15,5 @@ package de.bixilon.minosoft;
public class Config {
public static String homeDir;
public static String configFileName = "game.yml";
}

View File

@ -15,18 +15,21 @@ package de.bixilon.minosoft;
import de.bixilon.minosoft.config.Configuration;
import de.bixilon.minosoft.config.GameConfiguration;
import de.bixilon.minosoft.game.datatypes.Player;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.logging.LogLevel;
import de.bixilon.minosoft.objects.Account;
import de.bixilon.minosoft.objects.Player;
import de.bixilon.minosoft.mojang.api.MojangAccount;
import de.bixilon.minosoft.protocol.network.Connection;
import de.bixilon.minosoft.util.OSUtil;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
public class Minosoft {
static Configuration config;
static List<MojangAccount> accountList;
public static void main(String[] args) {
// int log thread
@ -36,7 +39,7 @@ public class Minosoft {
setConfigFolder();
Log.info("Reading config file...");
try {
config = new Configuration("game.yml");
config = new Configuration(Config.configFileName);
} catch (IOException e) {
Log.fatal("Failed to load config file!");
e.printStackTrace();
@ -46,8 +49,21 @@ public class Minosoft {
// set log level from config
Log.setLevel(LogLevel.byName(config.getString(GameConfiguration.GENERAL_LOG_LEVEL)));
checkClientToken();
Connection c = new Connection(config.getString("debug.host"), config.getInteger("debug.port"));
c.setPlayer(new Player(new Account(config.getString("debug.username"), config.getString("debug.password"))));
accountList = config.getMojangAccounts();
if (accountList.size() == 0) {
throw new RuntimeException("No accounts in config file!");
//MojangAccount account = MojangAuthentication.login("email", "password");
}
MojangAccount account = accountList.get(0);
if (!account.refreshToken()) {
// could not login
System.exit(1);
}
account.saveToConfig();
c.setPlayer(new Player(account));
c.connect();
}
@ -79,4 +95,11 @@ public class Minosoft {
public static Configuration getConfig() {
return config;
}
public static void checkClientToken() {
if (config.getString(GameConfiguration.CLIENT_TOKEN) == null || config.getString(GameConfiguration.CLIENT_TOKEN).equals("randomGenerated")) {
config.putString(GameConfiguration.CLIENT_TOKEN, UUID.randomUUID().toString());
config.saveToFile(Config.configFileName);
}
}
}

View File

@ -11,7 +11,7 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.objects;
package de.bixilon.minosoft;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import org.json.JSONObject;

View File

@ -14,12 +14,13 @@
package de.bixilon.minosoft.config;
import de.bixilon.minosoft.Config;
import de.bixilon.minosoft.mojang.api.MojangAccount;
import org.yaml.snakeyaml.Yaml;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.LinkedHashMap;
import java.util.*;
public class Configuration {
LinkedHashMap<String, Object> config;
@ -69,6 +70,38 @@ public class Configuration {
}
public void putBoolean(ConfigEnum config, boolean value) {
putBoolean(config.getPath(), value);
}
public void putBoolean(String path, boolean value) {
put(path, value);
}
public void putInteger(ConfigEnum config, int value) {
putInteger(config.getPath(), value);
}
public void putInteger(String path, int value) {
put(path, value);
}
public void putString(ConfigEnum config, String value) {
putString(config.getPath(), value);
}
public void putString(String path, String value) {
put(path, value);
}
public void putMojangAccount(MojangAccount account) {
String basePath = String.format("account.accounts.%s.", account.getUserId());
putString(basePath + "accessToken", account.getAccessToken());
putString(basePath + "uuid", account.getUUID().toString());
putString(basePath + "userName", account.getMojangUserName());
putString(basePath + "playerName", account.getPlayerName());
}
public Object get(String path) {
if (path.contains(".")) {
// split
@ -78,9 +111,54 @@ public class Configuration {
//noinspection unchecked
temp = (LinkedHashMap<String, Object>) temp.get(spilt[i]);
}
if (temp == null) {
return null;
}
return temp.get(spilt[spilt.length - 1]);
}
return config.get(path);
}
public void put(String path, Serializable value) {
if (path.contains(".")) {
// split
String[] spilt = path.split("\\.");
LinkedHashMap<String, Object> temp = config;
for (int i = 0; i < spilt.length - 1; i++) {
if (temp.get(spilt[i]) == null) {
// not yet existing, creating it
temp.put(spilt[i], new LinkedHashMap<String, Object>());
}
temp = (LinkedHashMap<String, Object>) temp.get(spilt[i]);
}
temp.put(spilt[spilt.length - 1], value);
return;
}
config.put(path, value);
}
public void saveToFile(String filename) {
Yaml yaml = new Yaml();
FileWriter writer = null;
try {
writer = new FileWriter(Config.homeDir + "config/" + filename);
} catch (IOException e) {
e.printStackTrace();
return;
}
yaml.dump(config, writer);
}
public List<MojangAccount> getMojangAccounts() {
List<MojangAccount> accounts = new ArrayList<>();
LinkedHashMap<String, Object> objects = (LinkedHashMap<String, Object>) get("account.accounts");
for (Map.Entry<String, Object> set : objects.entrySet()) {
LinkedHashMap<String, Object> entry = (LinkedHashMap<String, Object>) set.getValue();
accounts.add(new MojangAccount((String) entry.get("accessToken"), set.getKey(), UUID.fromString((String) entry.get("uuid")), (String) entry.get("playerName"), (String) entry.get("mojangUserName")));
}
return accounts;
}
}

View File

@ -17,7 +17,8 @@ public enum GameConfiguration implements ConfigEnum {
CONFIG_VERSION("version"),
GAME_RENDER_DISTANCE("game.render-distance"),
NETWORK_FAKE_CLIENT_BRAND("network.fake-client-brand"),
GENERAL_LOG_LEVEL("general.log-level");
GENERAL_LOG_LEVEL("general.log-level"),
CLIENT_TOKEN("account.clientToken");
final String path;

View File

@ -11,20 +11,18 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.objects;
package de.bixilon.minosoft.game.datatypes;
import de.bixilon.minosoft.game.datatypes.GameMode;
import de.bixilon.minosoft.game.datatypes.Slot;
import de.bixilon.minosoft.game.datatypes.Slots;
import de.bixilon.minosoft.game.datatypes.entities.Location;
import de.bixilon.minosoft.game.datatypes.entities.meta.HumanMetaData;
import de.bixilon.minosoft.game.datatypes.world.World;
import de.bixilon.minosoft.mojang.api.MojangAccount;
import java.util.HashMap;
import java.util.UUID;
public class Player {
final Account acc;
final MojangAccount acc;
float health;
short food;
float saturation;
@ -39,9 +37,8 @@ public class Player {
HashMap<Slots.Inventory, Slot> inventory = new HashMap<>();
boolean spawnConfirmed = false;
public Player(Account acc) {
public Player(MojangAccount acc) {
this.acc = acc;
acc.login();
}
public String getPlayerName() {
@ -52,7 +49,7 @@ public class Player {
return acc.getUUID();
}
public Account getAccount() {
public MojangAccount getAccount() {
return this.acc;
}

View File

@ -0,0 +1,89 @@
/*
* Codename Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.mojang.api;
import de.bixilon.minosoft.Config;
import de.bixilon.minosoft.Minosoft;
import de.bixilon.minosoft.util.Util;
import org.json.JSONObject;
import java.util.UUID;
public class MojangAccount {
String accessToken;
String userId;
UUID uuid;
String playerName;
String mojangUserName;
public MojangAccount(JSONObject json) {
this.accessToken = json.getString("accessToken");
JSONObject profile = json.getJSONObject("selectedProfile");
this.uuid = Util.formatUUID(profile.getString("id"));
this.playerName = profile.getString("name");
JSONObject mojang = json.getJSONObject("user");
this.userId = mojang.getString("id");
this.mojangUserName = mojang.getString("username");
}
public MojangAccount(String accessToken, String userId, UUID uuid, String playerName, String mojangUserName) {
this.accessToken = accessToken;
this.userId = userId;
this.uuid = uuid;
this.playerName = playerName;
this.mojangUserName = mojangUserName;
}
public void join(String serverId) {
MojangAuthentication.joinServer(this, serverId);
}
public boolean refreshToken() {
String accessToken = MojangAuthentication.refresh(this.accessToken);
if (accessToken == null) {
return false;
}
this.accessToken = accessToken;
return true;
}
public UUID getUUID() {
return this.uuid;
}
public String getPlayerName() {
return this.playerName;
}
public String getAccessToken() {
return accessToken;
}
public String getMojangUserName() {
return mojangUserName;
}
public String getUserId() {
return userId;
}
public void saveToConfig() {
Minosoft.getConfig().putMojangAccount(this);
Minosoft.getConfig().saveToFile(Config.configFileName);
}
}

View File

@ -0,0 +1,97 @@
/*
* Codename Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.mojang.api;
import de.bixilon.minosoft.Minosoft;
import de.bixilon.minosoft.config.GameConfiguration;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.util.HTTP;
import org.json.JSONObject;
import java.net.http.HttpResponse;
public class MojangAuthentication {
public static MojangAccount login(String clientToken, String username, String password) {
JSONObject payload = new JSONObject();
payload.put("agent", new JSONObject().put("name", "Minecraft").put("version", 1));
payload.put("username", username);
payload.put("password", password);
payload.put("clientToken", clientToken);
payload.put("requestUser", true);
HttpResponse<String> response = HTTP.postJson(MojangURLs.LOGIN.getUrl(), payload);
if (response == null) {
Log.mojang(String.format("Failed to login with username %s", username));
return null;
}
JSONObject jsonResponse = new JSONObject(response.body());
if (response.statusCode() != 200) {
Log.mojang(String.format("Failed to login with error code %d: %s", response.statusCode(), jsonResponse.getString("errorMessage")));
return null;
}
// now it is okay
return new MojangAccount(jsonResponse);
}
public static MojangAccount login(String username, String password) {
return login(Minosoft.getConfig().getString(GameConfiguration.CLIENT_TOKEN), username, password);
}
public static void joinServer(MojangAccount account, String serverId) {
JSONObject payload = new JSONObject();
payload.put("accessToken", account.getAccessToken());
payload.put("selectedProfile", account.getUUID().toString().replace("-", ""));
payload.put("serverId", serverId);
HttpResponse<String> response = HTTP.postJson(MojangURLs.JOIN.toString(), payload);
if (response == null) {
Log.mojang(String.format("Failed to join server: %s", serverId));
return;
}
JSONObject jsonResponse = new JSONObject(response.body());
if (response.statusCode() != 204) {
Log.mojang(String.format("Failed to join server with error code %d: %s", response.statusCode(), jsonResponse.getString("errorMessage")));
return;
}
// joined
Log.mojang("Joined server successfully");
}
public static String refresh(String clientToken, String accessToken) {
JSONObject payload = new JSONObject();
payload.put("accessToken", accessToken);
payload.put("clientToken", clientToken);
HttpResponse<String> response = HTTP.postJson(MojangURLs.REFRESH.getUrl(), payload);
if (response == null) {
Log.mojang("Failed to refresh session");
return null;
}
JSONObject jsonResponse = new JSONObject(response.body());
if (response.statusCode() != 200) {
Log.mojang(String.format("Failed to refresh session with error code %d: %s", response.statusCode(), jsonResponse.getString("errorMessage")));
return null;
}
// now it is okay
return jsonResponse.getString("accessToken");
}
public static String refresh(String accessToken) {
return refresh(Minosoft.getConfig().getString(GameConfiguration.CLIENT_TOKEN), accessToken);
}
}

View File

@ -0,0 +1,51 @@
/*
* Codename Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.mojang.api;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.util.HTTP;
import de.bixilon.minosoft.util.Util;
import java.net.http.HttpResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class MojangBlockedServers {
public static List<String> getBlockedServers() {
HttpResponse<String> response = HTTP.get(MojangURLs.BLOCKED_SERVERS.getUrl());
if (response == null) {
Log.mojang("Failed to fetch blocked servers");
return null;
}
if (response.statusCode() != 200) {
Log.mojang(String.format("Failed to fetch blocked server error code %d", response.statusCode()));
return null;
}
// now it is hopefully okay
return new ArrayList<>(Arrays.asList(response.body().split("\n")));
}
public boolean isServerBlocked(List<String> list, String hostname) {
for (String hash : list) {
if (hash.equals(Util.sha1(hostname))) {
return true;
}
// ToDo: check subdomains and ip addresses
}
return false;
}
}

View File

@ -0,0 +1,115 @@
/*
* Codename Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.mojang.api;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.util.HTTP;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.net.http.HttpResponse;
import java.util.HashMap;
import java.util.Iterator;
public class MojangStatus {
public static HashMap<Services, ServiceStatus> getStatus() {
HttpResponse<String> response = HTTP.get(MojangURLs.STATUS.getUrl());
if (response == null) {
Log.mojang("Failed to fetch Status");
return getUnknownStatusMap();
}
if (response.statusCode() != 200) {
Log.mojang(String.format("Failed to fetch Status with error code %d", response.statusCode()));
return getUnknownStatusMap();
}
// now it is hopefully okay
HashMap<Services, ServiceStatus> ret = new HashMap<>();
try {
JSONArray json = new JSONArray(response.body());
for (int i = 0; i < json.length(); i++) {
JSONObject innerJson = json.getJSONObject(i);
Iterator<String> keys = innerJson.keys();
while (keys.hasNext()) {
String key = keys.next();
Services service = Services.byKey(key);
ret.put(service, ServiceStatus.byKey(innerJson.getString(key)));
}
}
if (ret.size() != Services.values().length) {
// new service or old one removed, technically an error
return ret;
}
return ret;
} catch (NullPointerException | JSONException e) {
e.printStackTrace();
return getUnknownStatusMap();
}
}
static HashMap<Services, ServiceStatus> getUnknownStatusMap() {
HashMap<Services, ServiceStatus> ret = new HashMap<>();
for (Services service : Services.values()) {
ret.put(service, ServiceStatus.UNKNOWN);
}
return ret;
}
enum Services {
MINECRAFT_NET("minecraft.net"),
ACCOUNT("account.mojang.com"),
AUTH("auth.mojang.com"),
AUTHENTICATION_SERVER("authserver.mojang.com"),
SESSION_SERVER("sessionserver.mojang.com"),
API("api.mojang.com"),
TEXTURES("textures.minecraft.net"),
MOJANG_COM("mojang.com");
final String key;
Services(String key) {
this.key = key;
}
public static Services byKey(String key) {
for (Services s : values()) {
if (s.getKey().equals(key)) {
return s;
}
}
return null;
}
public String getKey() {
return key;
}
}
enum ServiceStatus {
GREEN,
YELLOW,
RED,
UNKNOWN;
public static ServiceStatus byKey(String key) {
for (ServiceStatus s : values()) {
if (s.name().equals(key)) {
return s;
}
}
return UNKNOWN;
}
}
}

View File

@ -0,0 +1,46 @@
/*
* Codename Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.mojang.api;
public enum MojangURLs {
STATUS("https://status.mojang.com/check"),
BLOCKED_SERVERS("https://sessionserver.mojang.com/blockedservers"),
LOGIN("https://authserver.mojang.com/authenticate"),
JOIN("https://sessionserver.mojang.com/session/minecraft/join"),
REFRESH("https://authserver.mojang.com/refresh");
final String url;
MojangURLs(String url) {
this.url = url;
}
public static MojangURLs byUrl(String key) {
for (MojangURLs s : values()) {
if (s.getUrl().equals(key)) {
return s;
}
}
return null;
}
public String getUrl() {
return url;
}
@Override
public String toString() {
return url;
}
}

View File

@ -1,86 +0,0 @@
/*
* Codename Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.objects;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.util.HTTP;
import de.bixilon.minosoft.util.Util;
import org.json.JSONObject;
import java.net.http.HttpResponse;
import java.util.UUID;
public class Account {
final String username;
final String password;
String playerName;
String token;
UUID uuid;
public Account(String username, String password) {
this.username = username;
this.password = password;
}
public void login() {
JSONObject payload = new JSONObject();
payload.put("agent", new JSONObject().put("name", "Minecraft").put("version", 1));
payload.put("username", username);
payload.put("password", password);
// ToDo not in main thread
HttpResponse<String> response = HTTP.postJson("https://authserver.mojang.com/authenticate", payload);
if (response == null || response.statusCode() != 200) {
assert response != null;
Log.info(String.format("[Mojang API] Login failed with username=%s (%s)", username, response.statusCode()));
return;
}
Log.info(String.format("[Mojang API] Login successful with username=%s", username));
// login good
JSONObject raw = new JSONObject(response.body());
token = raw.getString("accessToken");
uuid = Util.formatUUID(raw.getJSONObject("selectedProfile").getString("id"));
playerName = raw.getJSONObject("selectedProfile").getString("name");
}
public void join(String serverId) {
JSONObject payload = new JSONObject();
payload.put("accessToken", token);
payload.put("selectedProfile", getUUID().toString().replace("-", ""));
payload.put("serverId", serverId);
// ToDo not in main thread
HttpResponse<String> response = HTTP.postJson("https://sessionserver.mojang.com/session/minecraft/join", payload);
if (response == null || response.statusCode() != 204) {
assert response != null;
Log.info("[Mojang API] Login to join server!");
return;
}
Log.info("[Mojang API] Joined server successfully");
}
public UUID getUUID() {
return this.uuid;
}
public String getPlayerName() {
return this.playerName;
}
}

View File

@ -13,8 +13,8 @@
package de.bixilon.minosoft.protocol.network;
import de.bixilon.minosoft.game.datatypes.Player;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.objects.Player;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
import de.bixilon.minosoft.protocol.packets.ServerboundPacket;
import de.bixilon.minosoft.protocol.packets.serverbound.handshaking.PacketHandshake;

View File

@ -13,8 +13,8 @@
package de.bixilon.minosoft.protocol.packets.clientbound.status;
import de.bixilon.minosoft.ServerListPing;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.objects.ServerListPing;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
import de.bixilon.minosoft.protocol.protocol.InPacketBuffer;
import de.bixilon.minosoft.protocol.protocol.PacketHandler;

View File

@ -13,8 +13,8 @@
package de.bixilon.minosoft.protocol.packets.serverbound.login;
import de.bixilon.minosoft.game.datatypes.Player;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.objects.Player;
import de.bixilon.minosoft.protocol.packets.ServerboundPacket;
import de.bixilon.minosoft.protocol.protocol.OutPacketBuffer;
import de.bixilon.minosoft.protocol.protocol.Packets;

View File

@ -31,8 +31,20 @@ public class HTTP {
.header("Content-Type", "application/json")
.build();
try {
return client.send(request,
HttpResponse.BodyHandlers.ofString());
return client.send(request, HttpResponse.BodyHandlers.ofString());
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
return null;
}
public static HttpResponse<String> get(String url) {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.build();
try {
return client.send(request, HttpResponse.BodyHandlers.ofString());
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}

View File

@ -18,6 +18,9 @@ import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;
import java.util.regex.Pattern;
import java.util.zip.DataFormatException;
@ -77,4 +80,17 @@ public class Util {
}
return outputStream.toByteArray();
}
public static String sha1(String string) {
try {
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(string.getBytes(StandardCharsets.UTF_8));
return new String(crypt.digest());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
}

View File

@ -11,9 +11,11 @@ game:
network:
fake-client-brand: false # if true, minosoft will tell the server that this is unmodified vanilla. if false, it will tell "minosoft".
# this will be removed soon
account:
clientToken: "randomGenerated"
accounts:
# this will be removed soon, only for debugging (pre alpha stage): some features are not implemented yet -/-
debug:
host: "127.0.0.1"
port: 25565
username: "Player"
password: "secret123"
port: 25565