mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-10-14 21:22:49 +00:00
Implement Realms support (#1533)
Resolve #51 * Realms: update to new API; fix HTTP Get * Realms: suggested changes Co-authored-by: ORelio <ORelio@users.noreply.github.com> * Realms: suggested changes Co-authored-by: ORelio <ORelio@users.noreply.github.com> * Add negative number support for JSON parser * Nice print realms worlds result * Option to join Realms world with world ID * Suggested changes Co-authored-by: ORelio <ORelio@users.noreply.github.com> * Failure handle Co-authored-by: ORelio <ORelio@users.noreply.github.com> * world id paired with index * fix text * Clean up the code a bit * Add setting for displaying Realms worlds * Rename Realms worlds setting * Put messages into translation file Co-authored-by: Zizhen Lian <zizhlian@umd.edu> Co-authored-by: ORelio <ORelio@users.noreply.github.com> Co-authored-by: ReinforceZwei <39955851+ReinforceZwei@users.noreply.github.com>
This commit is contained in:
parent
d7089c534f
commit
621e5e2200
6 changed files with 129 additions and 11 deletions
|
|
@ -137,10 +137,10 @@ namespace MinecraftClient
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//Number
|
//Number
|
||||||
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.':
|
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.': case '-':
|
||||||
data = new JSONData(JSONData.DataType.String);
|
data = new JSONData(JSONData.DataType.String);
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
while ((toparse[cursorpos] >= '0' && toparse[cursorpos] <= '9') || toparse[cursorpos] == '.')
|
while ((toparse[cursorpos] >= '0' && toparse[cursorpos] <= '9') || toparse[cursorpos] == '.' || toparse[cursorpos] == '-')
|
||||||
{
|
{
|
||||||
sb.Append(toparse[cursorpos]);
|
sb.Append(toparse[cursorpos]);
|
||||||
cursorpos++;
|
cursorpos++;
|
||||||
|
|
|
||||||
|
|
@ -219,6 +219,7 @@ namespace MinecraftClient
|
||||||
if (result == ProtocolHandler.LoginResult.Success)
|
if (result == ProtocolHandler.LoginResult.Success)
|
||||||
{
|
{
|
||||||
Settings.Username = session.PlayerName;
|
Settings.Username = session.PlayerName;
|
||||||
|
bool isRealms = false;
|
||||||
|
|
||||||
if (Settings.ConsoleTitle != "")
|
if (Settings.ConsoleTitle != "")
|
||||||
Console.Title = Settings.ExpandVars(Settings.ConsoleTitle);
|
Console.Title = Settings.ExpandVars(Settings.ConsoleTitle);
|
||||||
|
|
@ -229,12 +230,45 @@ namespace MinecraftClient
|
||||||
if (Settings.DebugMessages)
|
if (Settings.DebugMessages)
|
||||||
Translations.WriteLine("debug.session_id", session.ID);
|
Translations.WriteLine("debug.session_id", session.ID);
|
||||||
|
|
||||||
//ProtocolHandler.RealmsListWorlds(Settings.Username, PlayerID, sessionID); //TODO REMOVE
|
List<string> availableWorlds = new List<string>();
|
||||||
|
if (Settings.MinecraftRealmsEnabled && !String.IsNullOrEmpty(session.ID))
|
||||||
|
availableWorlds = ProtocolHandler.RealmsListWorlds(Settings.Username, session.PlayerID, session.ID);
|
||||||
|
|
||||||
if (Settings.ServerIP == "")
|
if (Settings.ServerIP == "")
|
||||||
{
|
{
|
||||||
Translations.Write("mcc.ip");
|
Translations.Write("mcc.ip");
|
||||||
Settings.SetServerIP(Console.ReadLine());
|
string addressInput = Console.ReadLine();
|
||||||
|
if (addressInput.StartsWith("realms:"))
|
||||||
|
{
|
||||||
|
if (Settings.MinecraftRealmsEnabled)
|
||||||
|
{
|
||||||
|
if (availableWorlds.Count == 0)
|
||||||
|
{
|
||||||
|
HandleFailure(Translations.Get("error.realms.access_denied"), false, ChatBot.DisconnectReason.LoginRejected);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int worldIndex = Convert.ToUInt16(addressInput.Split(':')[1]);
|
||||||
|
string worldId = availableWorlds[worldIndex];
|
||||||
|
string RealmsAddress = ProtocolHandler.GetRealmsWorldServerAddress(worldId, Settings.Username, session.PlayerID, session.ID);
|
||||||
|
if (RealmsAddress != "")
|
||||||
|
{
|
||||||
|
addressInput = RealmsAddress;
|
||||||
|
isRealms = true;
|
||||||
|
Settings.ServerVersion = MCHighestVersion;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HandleFailure(Translations.Get("error.realms.server_unavailable"), false, ChatBot.DisconnectReason.LoginRejected);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HandleFailure(Translations.Get("error.realms.disabled"), false, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Settings.SetServerIP(addressInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Get server version
|
//Get server version
|
||||||
|
|
@ -259,7 +293,7 @@ namespace MinecraftClient
|
||||||
}
|
}
|
||||||
|
|
||||||
//Retrieve server info if version is not manually set OR if need to retrieve Forge information
|
//Retrieve server info if version is not manually set OR if need to retrieve Forge information
|
||||||
if (protocolversion == 0 || Settings.ServerAutodetectForge || (Settings.ServerForceForge && !ProtocolHandler.ProtocolMayForceForge(protocolversion)))
|
if (!isRealms && (protocolversion == 0 || Settings.ServerAutodetectForge || (Settings.ServerForceForge && !ProtocolHandler.ProtocolMayForceForge(protocolversion))))
|
||||||
{
|
{
|
||||||
if (protocolversion != 0)
|
if (protocolversion != 0)
|
||||||
Translations.WriteLine("mcc.forge");
|
Translations.WriteLine("mcc.forge");
|
||||||
|
|
@ -272,7 +306,7 @@ namespace MinecraftClient
|
||||||
}
|
}
|
||||||
|
|
||||||
//Force-enable Forge support?
|
//Force-enable Forge support?
|
||||||
if (Settings.ServerForceForge && forgeInfo == null)
|
if (!isRealms && Settings.ServerForceForge && forgeInfo == null)
|
||||||
{
|
{
|
||||||
if (ProtocolHandler.ProtocolMayForceForge(protocolversion))
|
if (ProtocolHandler.ProtocolMayForceForge(protocolversion))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -675,14 +675,88 @@ namespace MinecraftClient.Protocol
|
||||||
catch { return false; }
|
catch { return false; }
|
||||||
}
|
}
|
||||||
|
|
||||||
//Test method currently not working
|
/// <summary>
|
||||||
//See https://github.com/ORelio/Minecraft-Console-Client/issues/51
|
/// Retrieve available Realms worlds of a player and display them
|
||||||
public static void RealmsListWorlds(string username, string uuid, string accesstoken)
|
/// </summary>
|
||||||
|
/// <param name="username">Player Minecraft username</param>
|
||||||
|
/// <param name="uuid">Player UUID</param>
|
||||||
|
/// <param name="accesstoken">Access token</param>
|
||||||
|
/// <returns>List of ID of available Realms worlds</returns>
|
||||||
|
public static List<string> RealmsListWorlds(string username, string uuid, string accesstoken)
|
||||||
{
|
{
|
||||||
string result = "";
|
string result = "";
|
||||||
string cookies = String.Format("sid=token:{0}:{1};user={2};version={3}", accesstoken, uuid, username, Program.MCHighestVersion);
|
string cookies = String.Format("sid=token:{0}:{1};user={2};version={3}", accesstoken, uuid, username, Program.MCHighestVersion);
|
||||||
DoHTTPSGet("mcoapi.minecraft.net", "/worlds", cookies, ref result);
|
DoHTTPSGet("pc.realms.minecraft.net", "/worlds", cookies, ref result);
|
||||||
Console.WriteLine(result);
|
Json.JSONData realmsWorlds = Json.ParseJson(result);
|
||||||
|
List<string> realmsWorldsResult = new List<string>(); // Store world ID
|
||||||
|
if (realmsWorlds.Properties.ContainsKey("servers")
|
||||||
|
&& realmsWorlds.Properties["servers"].Type == Json.JSONData.DataType.Array
|
||||||
|
&& realmsWorlds.Properties["servers"].DataArray.Count > 0)
|
||||||
|
{
|
||||||
|
List<string> availableWorlds = new List<string>(); // Store string to print
|
||||||
|
int index = 0;
|
||||||
|
foreach (Json.JSONData realmsServer in realmsWorlds.Properties["servers"].DataArray)
|
||||||
|
{
|
||||||
|
if (realmsServer.Properties.ContainsKey("name")
|
||||||
|
&& realmsServer.Properties.ContainsKey("owner")
|
||||||
|
&& realmsServer.Properties.ContainsKey("id")
|
||||||
|
&& realmsServer.Properties.ContainsKey("daysLeft"))
|
||||||
|
{
|
||||||
|
int daysLeft;
|
||||||
|
if (int.TryParse(realmsServer.Properties["daysLeft"].StringValue, out daysLeft))
|
||||||
|
{
|
||||||
|
if (daysLeft > 0)
|
||||||
|
{
|
||||||
|
availableWorlds.Add(String.Format("[{0}] {2} ({3}) - {1}",
|
||||||
|
index++,
|
||||||
|
realmsServer.Properties["id"].StringValue,
|
||||||
|
realmsServer.Properties["name"].StringValue,
|
||||||
|
realmsServer.Properties["owner"].StringValue));
|
||||||
|
realmsWorldsResult.Add(realmsServer.Properties["id"].StringValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (availableWorlds.Count > 0)
|
||||||
|
{
|
||||||
|
Translations.WriteLine("mcc.realms_available");
|
||||||
|
foreach (var world in availableWorlds)
|
||||||
|
ConsoleIO.WriteLine(world);
|
||||||
|
Translations.WriteLine("mcc.realms_join");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return realmsWorldsResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the server address of a Realms world by world ID
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="worldId">The world ID of the Realms world</param>
|
||||||
|
/// <param name="username">Player Minecraft username</param>
|
||||||
|
/// <param name="uuid">Player UUID</param>
|
||||||
|
/// <param name="accesstoken">Access token</param>
|
||||||
|
/// <returns>Server address (host:port) or empty string if failure</returns>
|
||||||
|
public static string GetRealmsWorldServerAddress(string worldId, string username, string uuid, string accesstoken)
|
||||||
|
{
|
||||||
|
string result = "";
|
||||||
|
string cookies = String.Format("sid=token:{0}:{1};user={2};version={3}", accesstoken, uuid, username, Program.MCHighestVersion);
|
||||||
|
int statusCode = DoHTTPSGet("pc.realms.minecraft.net", "/worlds/v1/" + worldId + "/join/pc", cookies, ref result);
|
||||||
|
if (statusCode == 200)
|
||||||
|
{
|
||||||
|
Json.JSONData serverAddress = Json.ParseJson(result);
|
||||||
|
if (serverAddress.Properties.ContainsKey("address"))
|
||||||
|
return serverAddress.Properties["address"].StringValue;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Translations.WriteLine("error.realms.ip_error");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Translations.WriteLine("error.realms.access_denied");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -705,6 +779,7 @@ namespace MinecraftClient.Protocol
|
||||||
http_request.Add("Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7");
|
http_request.Add("Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7");
|
||||||
http_request.Add("Connection: close");
|
http_request.Add("Connection: close");
|
||||||
http_request.Add("");
|
http_request.Add("");
|
||||||
|
http_request.Add("");
|
||||||
return DoHTTPSRequest(http_request, host, ref result);
|
return DoHTTPSRequest(http_request, host, ref result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ exitonfailure=false # Disable pauses on error, for using MCC in n
|
||||||
scriptcache=true # Cache compiled scripts for faster load on low-end devices
|
scriptcache=true # Cache compiled scripts for faster load on low-end devices
|
||||||
timestamps=false # Prepend timestamps to chat messages
|
timestamps=false # Prepend timestamps to chat messages
|
||||||
autorespawn=false # Toggle auto respawn if client player was dead (make sure your spawn point is safe)
|
autorespawn=false # Toggle auto respawn if client player was dead (make sure your spawn point is safe)
|
||||||
|
minecraftrealms=true # Enable support for joining Minecraft Realms worlds
|
||||||
|
|
||||||
[Logging]
|
[Logging]
|
||||||
# Only affect the messages on console.
|
# Only affect the messages on console.
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,8 @@ mcc.session_fail=Failed to check session.
|
||||||
mcc.server_protocol=§8Server version : {0} (protocol v{1})
|
mcc.server_protocol=§8Server version : {0} (protocol v{1})
|
||||||
mcc.with_forge=, with Forge
|
mcc.with_forge=, with Forge
|
||||||
mcc.handshake=§8Handshake successful. (Server ID: {0})
|
mcc.handshake=§8Handshake successful. (Server ID: {0})
|
||||||
|
mcc.realms_available=You have access to the following Realms worlds
|
||||||
|
mcc.realms_join=Use realms:index as server IP to join the Realms world
|
||||||
|
|
||||||
|
|
||||||
[debug]
|
[debug]
|
||||||
|
|
@ -82,6 +84,10 @@ error.forge_encrypt=§8Forge StartEncryption Handshake did not complete successf
|
||||||
error.setting.str2int=Failed to convert '{0}' into an int. Please check your settings.
|
error.setting.str2int=Failed to convert '{0}' into an int. Please check your settings.
|
||||||
error.http_code=§8Got error code from server: {0}
|
error.http_code=§8Got error code from server: {0}
|
||||||
error.auth=§8Got error code from server while refreshing authentication: {0}
|
error.auth=§8Got error code from server while refreshing authentication: {0}
|
||||||
|
error.realms.ip_error=Cannot retrieve the server IP of your Realms world
|
||||||
|
error.realms.access_denied=This Realms world does not exist or access was denied
|
||||||
|
error.realms.server_unavailable=Realms server may require some time to start up. Please retry again later.
|
||||||
|
error.realms.disabled=Trying to join a Realms world but Realms support is disabled in config
|
||||||
|
|
||||||
[internal command]
|
[internal command]
|
||||||
# MCC internal help command
|
# MCC internal help command
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,7 @@ namespace MinecraftClient
|
||||||
public static bool ResolveSrvRecordsShortTimeout = true;
|
public static bool ResolveSrvRecordsShortTimeout = true;
|
||||||
public static bool EntityHandling = false;
|
public static bool EntityHandling = false;
|
||||||
public static bool AutoRespawn = false;
|
public static bool AutoRespawn = false;
|
||||||
|
public static bool MinecraftRealmsEnabled = true;
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
public enum FilterModeEnum { Blacklist, Whitelist }
|
public enum FilterModeEnum { Blacklist, Whitelist }
|
||||||
|
|
@ -308,6 +309,7 @@ namespace MinecraftClient
|
||||||
case "autorespawn": AutoRespawn = str2bool(argValue); break;
|
case "autorespawn": AutoRespawn = str2bool(argValue); break;
|
||||||
// Backward compatible so people can still enable debug with old config format
|
// Backward compatible so people can still enable debug with old config format
|
||||||
case "debugmessages": DebugMessages = str2bool(argValue); break;
|
case "debugmessages": DebugMessages = str2bool(argValue); break;
|
||||||
|
case "minecraftrealms": MinecraftRealmsEnabled = str2bool(argValue); break;
|
||||||
|
|
||||||
case "botowners":
|
case "botowners":
|
||||||
Bots_Owners.Clear();
|
Bots_Owners.Clear();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue