mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2025-10-14 21:22:49 +00:00
Add basic location handling
- Retrieve player location from the server - Send back player location from the server - Requires that a specific setting is enabled - Should allow items to be picked up by the player - May also trigger some anti chead plugins
This commit is contained in:
parent
5654871a57
commit
72bd485e67
11 changed files with 319 additions and 17 deletions
|
|
@ -458,7 +458,7 @@ namespace MinecraftClient
|
|||
|
||||
protected void ReconnectToTheServer(int ExtraAttempts = 3)
|
||||
{
|
||||
McTcpClient.AttemptsLeft = ExtraAttempts;
|
||||
McTcpClient.ReconnectionAttemptsLeft = ExtraAttempts;
|
||||
Program.Restart();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,14 +25,14 @@ namespace MinecraftClient.ChatBots
|
|||
{
|
||||
attempts = retries;
|
||||
if (attempts == -1) { attempts = int.MaxValue; }
|
||||
McTcpClient.AttemptsLeft = attempts;
|
||||
McTcpClient.ReconnectionAttemptsLeft = attempts;
|
||||
delay = DelayBeforeRelog;
|
||||
if (delay < 1) { delay = 1; }
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
McTcpClient.AttemptsLeft = attempts;
|
||||
McTcpClient.ReconnectionAttemptsLeft = attempts;
|
||||
if (System.IO.File.Exists(Settings.AutoRelog_KickMessagesFile))
|
||||
{
|
||||
dictionary = System.IO.File.ReadAllLines(Settings.AutoRelog_KickMessagesFile);
|
||||
|
|
@ -55,7 +55,7 @@ namespace MinecraftClient.ChatBots
|
|||
{
|
||||
LogToConsole("Waiting " + delay + " seconds before reconnecting...");
|
||||
System.Threading.Thread.Sleep(delay * 1000);
|
||||
McTcpClient.AttemptsLeft = attempts;
|
||||
McTcpClient.ReconnectionAttemptsLeft = attempts;
|
||||
ReconnectToTheServer();
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
159
MinecraftClient/Mapping/Location.cs
Normal file
159
MinecraftClient/Mapping/Location.cs
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace MinecraftClient.Mapping
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a location into a Minecraft world
|
||||
/// </summary>
|
||||
public struct Location
|
||||
{
|
||||
/// <summary>
|
||||
/// The X Coordinate
|
||||
/// </summary>
|
||||
public double X;
|
||||
|
||||
/// <summary>
|
||||
/// The Y Coordinate (vertical)
|
||||
/// </summary>
|
||||
public double Y;
|
||||
|
||||
/// <summary>
|
||||
/// The Z coordinate
|
||||
/// </summary>
|
||||
public double Z;
|
||||
|
||||
/// <summary>
|
||||
/// Get location with zeroed coordinates
|
||||
/// </summary>
|
||||
public static Location Zero
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Location(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new location
|
||||
/// </summary>
|
||||
public Location(double x, double y, double z)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Z = z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare two locations. Locations are equals if the integer part of their coordinates are equals.
|
||||
/// </summary>
|
||||
/// <param name="obj">Object to compare to</param>
|
||||
/// <returns>TRUE if the locations are equals</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (obj is Location)
|
||||
{
|
||||
return ((int)this.X) == ((int)((Location)obj).X)
|
||||
&& ((int)this.Y) == ((int)((Location)obj).Y)
|
||||
&& ((int)this.Z) == ((int)((Location)obj).Z);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a representation of the location as unsigned long
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A modulo will be applied if the location is outside the following ranges:
|
||||
/// X: -33,554,432 to +33,554,431
|
||||
/// Y: -2,048 to +2,047
|
||||
/// Z: -33,554,432 to +33,554,431
|
||||
/// </remarks>
|
||||
/// <returns>Location representation as ulong</returns>
|
||||
|
||||
public ulong GetLongRepresentation()
|
||||
{
|
||||
return ((((ulong)X) & 0x3FFFFFF) << 38) | ((((ulong)Y) & 0xFFF) << 26) | (((ulong)Z) & 0x3FFFFFF);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a location from an unsigned long.
|
||||
/// </summary>
|
||||
/// <returns>Location represented by the ulong</returns>
|
||||
|
||||
public static Location FromLongRepresentation(ulong location)
|
||||
{
|
||||
return new Location(location >> 38, (location >> 26) & 0xFFF, location << 38 >> 38);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare two locations. Locations are equals if the integer part of their coordinates are equals.
|
||||
/// </summary>
|
||||
/// <param name="loc1">First location to compare</param>
|
||||
/// <param name="loc2">Second location to compare</param>
|
||||
/// <returns>TRUE if the locations are equals</returns>
|
||||
public static bool operator == (Location loc1, Location loc2)
|
||||
{
|
||||
if (loc1 == null && loc2 == null)
|
||||
return true;
|
||||
if (loc1 == null || loc2 == null)
|
||||
return false;
|
||||
return loc1.Equals(loc2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare two locations. Locations are not equals if the integer part of their coordinates are not equals.
|
||||
/// </summary>
|
||||
/// <param name="loc1">First location to compare</param>
|
||||
/// <param name="loc2">Second location to compare</param>
|
||||
/// <returns>TRUE if the locations are equals</returns>
|
||||
public static bool operator != (Location loc1, Location loc2)
|
||||
{
|
||||
if (loc1 == null && loc2 == null)
|
||||
return true;
|
||||
if (loc1 == null || loc2 == null)
|
||||
return false;
|
||||
return !loc1.Equals(loc2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sums two locations and returns the result.
|
||||
/// </summary>
|
||||
/// <exception cref="NullReferenceException">
|
||||
/// Thrown if one of the provided location is null
|
||||
/// </exception>
|
||||
/// <param name="loc1">First location to sum</param>
|
||||
/// <param name="loc2">Second location to sum</param>
|
||||
/// <returns>Sum of the two locations</returns>
|
||||
public static Location operator + (Location loc1, Location loc2)
|
||||
{
|
||||
return new Location
|
||||
(
|
||||
loc1.X + loc2.X,
|
||||
loc1.Y + loc2.Y,
|
||||
loc1.Z + loc2.Z
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DO NOT USE. Defined to comply with C# requirements requiring a GetHashCode() when overriding Equals() or ==
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A modulo will be applied if the location is outside the following ranges:
|
||||
/// X: -4096 to +4095
|
||||
/// Y: -32 to +31
|
||||
/// Z: -4096 to +4095
|
||||
/// </remarks>
|
||||
/// <returns>A simplified version of the location</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return (((int)X) & ~((~0) << 13)) << 19
|
||||
| (((int)Y) & ~((~0) << 13)) << 13
|
||||
| (((int)Z) & ~((~0) << 06)) << 00;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ using System.Net;
|
|||
using MinecraftClient.Protocol;
|
||||
using MinecraftClient.Proxy;
|
||||
using MinecraftClient.Protocol.Handlers.Forge;
|
||||
using MinecraftClient.Mapping;
|
||||
|
||||
namespace MinecraftClient
|
||||
{
|
||||
|
|
@ -18,16 +19,20 @@ namespace MinecraftClient
|
|||
|
||||
public class McTcpClient : IMinecraftComHandler
|
||||
{
|
||||
private static List<string> cmd_names = new List<string>();
|
||||
private static Dictionary<string, Command> cmds = new Dictionary<string, Command>();
|
||||
private List<ChatBot> bots = new List<ChatBot>();
|
||||
public static int ReconnectionAttemptsLeft = 0;
|
||||
|
||||
private static readonly List<string> cmd_names = new List<string>();
|
||||
private static readonly Dictionary<string, Command> cmds = new Dictionary<string, Command>();
|
||||
private readonly Dictionary<Guid, string> onlinePlayers = new Dictionary<Guid, string>();
|
||||
private static List<ChatBots.Script> scripts_on_hold = new List<ChatBots.Script>();
|
||||
|
||||
private readonly List<ChatBot> bots = new List<ChatBot>();
|
||||
private static readonly List<ChatBots.Script> scripts_on_hold = new List<ChatBots.Script>();
|
||||
public void BotLoad(ChatBot b) { b.SetHandler(this); bots.Add(b); b.Initialize(); Settings.SingleCommand = ""; }
|
||||
public void BotUnLoad(ChatBot b) { bots.RemoveAll(item => object.ReferenceEquals(item, b)); }
|
||||
public void BotClear() { bots.Clear(); }
|
||||
|
||||
public static int AttemptsLeft = 0;
|
||||
private Location location;
|
||||
private int updateTicks = 0;
|
||||
|
||||
private string host;
|
||||
private int port;
|
||||
|
|
@ -40,6 +45,7 @@ namespace MinecraftClient
|
|||
public string GetUsername() { return username; }
|
||||
public string GetUserUUID() { return uuid; }
|
||||
public string GetSessionID() { return sessionid; }
|
||||
public Location GetCurrentLocation() { return location; }
|
||||
|
||||
TcpClient client;
|
||||
IMinecraftCom handler;
|
||||
|
|
@ -162,10 +168,10 @@ namespace MinecraftClient
|
|||
|
||||
if (retry)
|
||||
{
|
||||
if (AttemptsLeft > 0)
|
||||
if (ReconnectionAttemptsLeft > 0)
|
||||
{
|
||||
ConsoleIO.WriteLogLine("Waiting 5 seconds (" + AttemptsLeft + " attempts left)...");
|
||||
Thread.Sleep(5000); AttemptsLeft--; Program.Restart();
|
||||
ConsoleIO.WriteLogLine("Waiting 5 seconds (" + ReconnectionAttemptsLeft + " attempts left)...");
|
||||
Thread.Sleep(5000); ReconnectionAttemptsLeft--; Program.Restart();
|
||||
}
|
||||
else if (!singlecommand && Settings.interactiveMode)
|
||||
{
|
||||
|
|
@ -330,6 +336,34 @@ namespace MinecraftClient
|
|||
handler.SendBrandInfo(Settings.BrandInfo.Trim());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the server sends a new player location,
|
||||
/// or if a ChatBot whishes to update the player's location.
|
||||
/// </summary>
|
||||
/// <param name="location">The new location</param>
|
||||
/// <param name="relative">If true, the location is relative to the current location</param>
|
||||
|
||||
public void UpdateLocation(Location location, bool relative)
|
||||
{
|
||||
if (relative)
|
||||
{
|
||||
this.location += location;
|
||||
}
|
||||
else this.location = location;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the server sends a new player location,
|
||||
/// or if a ChatBot whishes to update the player's location.
|
||||
/// </summary>
|
||||
/// <param name="location">The new location</param>
|
||||
/// <param name="relative">If true, the location is relative to the current location</param>
|
||||
|
||||
public void UpdateLocation(Location location)
|
||||
{
|
||||
UpdateLocation(location, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Received some text from the server
|
||||
/// </summary>
|
||||
|
|
@ -409,6 +443,16 @@ namespace MinecraftClient
|
|||
else throw; //ThreadAbortException should not be caught
|
||||
}
|
||||
}
|
||||
|
||||
if (Settings.TerrainAndMovements)
|
||||
{
|
||||
if (updateTicks >= 10)
|
||||
{
|
||||
handler.SendLocationUpdate(location, true); //TODO handle onGround once terrain data is available
|
||||
updateTicks = 0;
|
||||
}
|
||||
updateTicks++;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -152,6 +152,7 @@
|
|||
<Compile Include="Proxy\Handlers\Utils.cs" />
|
||||
<Compile Include="Settings.cs" />
|
||||
<Compile Include="Commands\List.cs" />
|
||||
<Compile Include="Mapping\Location.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include=".NETFramework,Version=v4.0,Profile=Client">
|
||||
|
|
|
|||
|
|
@ -19,7 +19,11 @@ namespace MinecraftClient
|
|||
{
|
||||
private static McTcpClient Client;
|
||||
public static string[] startupargs;
|
||||
|
||||
public const string Version = "1.8.2";
|
||||
public const string MCLowestVersion = "1.4.6";
|
||||
public const string MCHighestVersion = "1.8.8";
|
||||
|
||||
private static Thread offlinePrompt = null;
|
||||
private static bool useMcVersionOnce = false;
|
||||
|
||||
|
|
@ -29,7 +33,7 @@ namespace MinecraftClient
|
|||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("Console Client for MC 1.4.6 to 1.8.8 - v" + Version + " - By ORelio & Contributors");
|
||||
Console.WriteLine("Console Client for MC {0} to {1} - v{2} - By ORelio & Contributors", MCLowestVersion, MCHighestVersion, Version);
|
||||
|
||||
//Basic Input/Output ?
|
||||
if (args.Length >= 1 && args[args.Length - 1] == "BasicIO")
|
||||
|
|
@ -138,6 +142,8 @@ namespace MinecraftClient
|
|||
|
||||
Console.WriteLine("Success. (session ID: " + sessionID + ')');
|
||||
|
||||
//ProtocolHandler.RealmsListWorlds(Settings.Username, UUID, sessionID); //TODO REMOVE
|
||||
|
||||
if (Settings.ServerIP == "")
|
||||
{
|
||||
Console.Write("Server IP : ");
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ using System.Threading;
|
|||
using MinecraftClient.Crypto;
|
||||
using MinecraftClient.Proxy;
|
||||
using System.Security.Cryptography;
|
||||
using MinecraftClient.Mapping;
|
||||
|
||||
namespace MinecraftClient.Protocol.Handlers
|
||||
{
|
||||
|
|
@ -615,6 +616,11 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
return false; //Only supported since MC 1.7
|
||||
}
|
||||
|
||||
public bool SendLocationUpdate(Location location, bool onGround)
|
||||
{
|
||||
return false; //Currently not implemented
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send a plugin channel packet to the server.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ using MinecraftClient.Crypto;
|
|||
using MinecraftClient.Proxy;
|
||||
using System.Security.Cryptography;
|
||||
using MinecraftClient.Protocol.Handlers.Forge;
|
||||
using MinecraftClient.Mapping;
|
||||
|
||||
namespace MinecraftClient.Protocol.Handlers
|
||||
{
|
||||
|
|
@ -162,6 +163,23 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
catch (IndexOutOfRangeException) { /* No message type */ }
|
||||
handler.OnTextReceived(ChatParser.ParseText(message));
|
||||
break;
|
||||
case 0x08:
|
||||
if (Settings.TerrainAndMovements)
|
||||
{
|
||||
double x = readNextDouble(ref packetData);
|
||||
double y = readNextDouble(ref packetData);
|
||||
double z = readNextDouble(ref packetData);
|
||||
|
||||
byte locMask = readNextByte(ref packetData);
|
||||
Location location = handler.GetCurrentLocation();
|
||||
|
||||
location.X = (locMask & 1 << 0) != 0 ? location.X + x : x;
|
||||
location.Y = (locMask & 1 << 1) != 0 ? location.Y + y : y;
|
||||
location.Z = (locMask & 1 << 2) != 0 ? location.Z + z : z;
|
||||
|
||||
handler.UpdateLocation(location);
|
||||
}
|
||||
break;
|
||||
case 0x38: //Player List update
|
||||
if (protocolversion >= MC18Version)
|
||||
{
|
||||
|
|
@ -509,6 +527,18 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
return readData(len, ref cache);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a double from a cache of bytes and remove it from the cache
|
||||
/// </summary>
|
||||
/// <returns>The double value</returns>
|
||||
|
||||
private static double readNextDouble(ref byte[] cache)
|
||||
{
|
||||
byte[] rawValue = readData(8, ref cache);
|
||||
Array.Reverse(rawValue); //Endianness
|
||||
return BitConverter.ToDouble(rawValue, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read an integer from the network
|
||||
/// </summary>
|
||||
|
|
@ -602,6 +632,19 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
return bytes.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get byte array representing a double
|
||||
/// </summary>
|
||||
/// <param name="array">Array to process</param>
|
||||
/// <returns>Array ready to send</returns>
|
||||
|
||||
private byte[] getDouble(double number)
|
||||
{
|
||||
byte[] theDouble = BitConverter.GetBytes(number);
|
||||
Array.Reverse(theDouble); //Endianness
|
||||
return theDouble;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get byte array with length information prepended to it
|
||||
/// </summary>
|
||||
|
|
@ -931,6 +974,29 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
return SendPluginChannelPacket("MC|Brand", getString(brandInfo));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send a location update to the server
|
||||
/// </summary>
|
||||
/// <param name="location">The new location of the player</param>
|
||||
/// <param name="onGround">True if the player is on the ground</param>
|
||||
/// <returns>True if the location update was successfully sent</returns>
|
||||
|
||||
public bool SendLocationUpdate(Location location, bool onGround)
|
||||
{
|
||||
if (Settings.TerrainAndMovements)
|
||||
{
|
||||
try
|
||||
{
|
||||
SendPacket(0x04, concatBytes(
|
||||
getDouble(location.X), getDouble(location.X), getDouble(location.X),
|
||||
new byte[] { onGround ? (byte)1 : (byte)0 }));
|
||||
return true;
|
||||
}
|
||||
catch (SocketException) { return false; }
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send a plugin channel packet (0x17) to the server, compression and encryption will be handled automatically
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using System.Text;
|
||||
using MinecraftClient.Crypto;
|
||||
using MinecraftClient.Mapping;
|
||||
|
||||
namespace MinecraftClient.Protocol
|
||||
{
|
||||
|
|
@ -45,7 +46,7 @@ namespace MinecraftClient.Protocol
|
|||
bool SendRespawnPacket();
|
||||
|
||||
/// <summary>
|
||||
/// Tell the server what client is being used to connect to the server
|
||||
/// Inform the server of the client being used to connect
|
||||
/// </summary>
|
||||
/// <param name="brandInfo">Client string describing the client</param>
|
||||
/// <returns>True if brand info was successfully sent</returns>
|
||||
|
|
@ -53,10 +54,17 @@ namespace MinecraftClient.Protocol
|
|||
bool SendBrandInfo(string brandInfo);
|
||||
|
||||
/// <summary>
|
||||
/// Send a plugin channel packet to the server.
|
||||
///
|
||||
/// http://dinnerbone.com/blog/2012/01/13/minecraft-plugin-channels-messaging/
|
||||
/// Send a location update telling that we moved to that location
|
||||
/// </summary>
|
||||
/// <param name="location">The new location</param>
|
||||
/// <returns>True if packet was successfully sent</returns>
|
||||
|
||||
bool SendLocationUpdate(Location location, bool onGround);
|
||||
|
||||
/// <summary>
|
||||
/// Send a plugin channel packet to the server.
|
||||
/// </summary>
|
||||
/// <see href="http://dinnerbone.com/blog/2012/01/13/minecraft-plugin-channels-messaging/" />
|
||||
/// <param name="channel">Channel to send packet on</param>
|
||||
/// <param name="data">packet Data</param>
|
||||
/// <returns>True if message was successfully sent</returns>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using MinecraftClient.Mapping;
|
||||
|
||||
namespace MinecraftClient.Protocol
|
||||
{
|
||||
|
|
@ -22,6 +23,7 @@ namespace MinecraftClient.Protocol
|
|||
string GetUserUUID();
|
||||
string GetSessionID();
|
||||
string[] GetOnlinePlayers();
|
||||
Location GetCurrentLocation();
|
||||
|
||||
/// <summary>
|
||||
/// Called when a server was successfully joined
|
||||
|
|
@ -50,6 +52,13 @@ namespace MinecraftClient.Protocol
|
|||
|
||||
void OnPlayerLeave(Guid uuid);
|
||||
|
||||
/// <summary>
|
||||
/// Called when the server sets the new location for the player
|
||||
/// </summary>
|
||||
/// <param name="location">New location of the player</param>
|
||||
|
||||
void UpdateLocation(Location location);
|
||||
|
||||
/// <summary>
|
||||
/// This method is called when the connection has been lost
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ namespace MinecraftClient
|
|||
public static string BrandInfo = MCCBrandInfo;
|
||||
public static bool DisplaySystemMessages = true;
|
||||
public static bool DisplayXPBarMessages = true;
|
||||
public static bool TerrainAndMovements = false;
|
||||
|
||||
//AntiAFK Settings
|
||||
public static bool AntiAFK_Enabled = false;
|
||||
|
|
@ -178,6 +179,7 @@ namespace MinecraftClient
|
|||
case "scriptcache": CacheScripts = str2bool(argValue); break;
|
||||
case "showsystemmessages": DisplaySystemMessages = str2bool(argValue); break;
|
||||
case "showxpbarmessages": DisplayXPBarMessages = str2bool(argValue); break;
|
||||
case "handleterrainandmovements": TerrainAndMovements = str2bool(argValue); break;
|
||||
|
||||
case "botowners":
|
||||
Bots_Owners.Clear();
|
||||
|
|
@ -407,6 +409,7 @@ namespace MinecraftClient
|
|||
+ "chatbotlogfile= #leave empty for no logfile\r\n"
|
||||
+ "showsystemmessages=true #system messages for server ops\r\n"
|
||||
+ "showxpbarmessages=true #messages displayed above xp bar\r\n"
|
||||
+ "handleterrainandmovements=false #requires more ram and cpu\r\n"
|
||||
+ "accountlist=accounts.txt\r\n"
|
||||
+ "serverlist=servers.txt\r\n"
|
||||
+ "playerheadicon=true\r\n"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue