diff --git a/MinecraftClient/Cache/CacheType.cs b/MinecraftClient/Cache/CacheType.cs deleted file mode 100644 index 9f49cd1c..00000000 --- a/MinecraftClient/Cache/CacheType.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace MinecraftClient.Cache -{ - public enum CacheType { NONE, MEMORY, DISK }; -} diff --git a/MinecraftClient/MinecraftClient.csproj b/MinecraftClient/MinecraftClient.csproj index be23d2ed..35a9ff85 100644 --- a/MinecraftClient/MinecraftClient.csproj +++ b/MinecraftClient/MinecraftClient.csproj @@ -73,8 +73,6 @@ - - @@ -151,6 +149,8 @@ + + diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs index d8af9d34..0dfb168d 100644 --- a/MinecraftClient/Program.cs +++ b/MinecraftClient/Program.cs @@ -6,6 +6,7 @@ using MinecraftClient.Protocol; using System.Reflection; using System.Threading; using MinecraftClient.Protocol.Handlers.Forge; +using MinecraftClient.Protocol.SessionCache; namespace MinecraftClient { @@ -86,19 +87,21 @@ namespace MinecraftClient } //Load cached sessions from disk if necessary - if (Settings.CacheType == Cache.CacheType.DISK) + if (Settings.SessionCaching == CacheType.Disk) { - Console.WriteLine(Cache.SessionCache.InitializeDiskCache() ? "Cached sessions loaded." : "Cached sessions could not be loaded from disk"); + bool cacheLoaded = SessionCache.InitializeDiskCache(); + if (Settings.DebugMessages) + ConsoleIO.WriteLineFormatted(cacheLoaded ? "§8Session cache has been successfully loaded from disk." : "§8Cached sessions could not be loaded from disk"); } //Asking the user to type in missing data such as Username and Password if (Settings.Login == "") { - Console.Write(ConsoleIO.basicIO ? "Please type the username of your choice.\n" : "Username : "); + Console.Write(ConsoleIO.basicIO ? "Please type the username or email of your choice.\n" : "Login : "); Settings.Login = Console.ReadLine(); } - if (Settings.Password == "" && (Settings.CacheType == Cache.CacheType.NONE || !Cache.SessionCache.Contains(Settings.Login))) + if (Settings.Password == "" && (Settings.SessionCaching == CacheType.None || !SessionCache.Contains(Settings.Login.ToLower()))) { RequestPassword(); } @@ -143,18 +146,17 @@ namespace MinecraftClient else { // Validate cached session or login new session. - if (Settings.CacheType != Cache.CacheType.NONE && Cache.SessionCache.Contains(Settings.Login)) + if (Settings.SessionCaching != CacheType.None && SessionCache.Contains(Settings.Login.ToLower())) { - session = Cache.SessionCache.Get(Settings.Login); + session = SessionCache.Get(Settings.Login.ToLower()); result = ProtocolHandler.GetTokenValidation(session); - - if (result != ProtocolHandler.LoginResult.Success && Settings.Password == "") + if (result != ProtocolHandler.LoginResult.Success) { - RequestPassword(); + ConsoleIO.WriteLineFormatted("§8Cached session is invalid or expired."); + if (Settings.Password == "") + RequestPassword(); } - - Console.WriteLine("Cached session is " + (result == ProtocolHandler.LoginResult.Success ? "valid." : "invalid.")); - + else ConsoleIO.WriteLineFormatted("§8Cached session is still valid for " + session.PlayerName + '.'); } if (result != ProtocolHandler.LoginResult.Success) @@ -162,9 +164,9 @@ namespace MinecraftClient Console.WriteLine("Connecting to Minecraft.net..."); result = ProtocolHandler.GetLogin(Settings.Login, Settings.Password, out session); - if (result == ProtocolHandler.LoginResult.Success && Settings.CacheType != Cache.CacheType.NONE) + if (result == ProtocolHandler.LoginResult.Success && Settings.SessionCaching != CacheType.None) { - Cache.SessionCache.Store(Settings.Login, session); + SessionCache.Store(Settings.Login.ToLower(), session); } } @@ -180,7 +182,8 @@ namespace MinecraftClient if (Settings.playerHeadAsIcon) ConsoleIcon.setPlayerIconAsync(Settings.Username); - Console.WriteLine("Success. (session ID: " + session.ID + ')'); + if (Settings.DebugMessages) + Console.WriteLine("Success. (session ID: " + session.ID + ')'); //ProtocolHandler.RealmsListWorlds(Settings.Username, PlayerID, sessionID); //TODO REMOVE @@ -221,11 +224,6 @@ namespace MinecraftClient } } - if (forgeInfo != null && !forgeInfo.Mods.Any()) - { - forgeInfo = null; - } - if (protocolversion != 0) { try diff --git a/MinecraftClient/Protocol/Handlers/ChatParser.cs b/MinecraftClient/Protocol/Handlers/ChatParser.cs index 5d2e785b..5c5b6c84 100644 --- a/MinecraftClient/Protocol/Handlers/ChatParser.cs +++ b/MinecraftClient/Protocol/Handlers/ChatParser.cs @@ -123,7 +123,8 @@ namespace MinecraftClient.Protocol.Handlers } } - ConsoleIO.WriteLineFormatted("§8Translations file loaded."); + if (Settings.DebugMessages) + ConsoleIO.WriteLineFormatted("§8Translations file loaded."); } else //No external dictionnary found. { diff --git a/MinecraftClient/Protocol/Handlers/Protocol16.cs b/MinecraftClient/Protocol/Handlers/Protocol16.cs index 1a080aa9..8480b259 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol16.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol16.cs @@ -449,7 +449,7 @@ namespace MinecraftClient.Protocol.Handlers if (serverID == "-") ConsoleIO.WriteLineFormatted("§8Server is in offline mode."); - else + else if (Settings.DebugMessages) ConsoleIO.WriteLineFormatted("§8Handshake successful. (Server ID: " + serverID + ')'); return StartEncryption(uuid, username, sessionID, token, serverID, PublicServerkey); @@ -462,7 +462,8 @@ namespace MinecraftClient.Protocol.Handlers System.Security.Cryptography.RSACryptoServiceProvider RSAService = CryptoHandler.DecodeRSAPublicKey(serverKey); byte[] secretKey = CryptoHandler.GenerateAESPrivateKey(); - ConsoleIO.WriteLineFormatted("§8Crypto keys & hash generated."); + if (Settings.DebugMessages) + ConsoleIO.WriteLineFormatted("§8Crypto keys & hash generated."); if (serverIDhash != "-") { diff --git a/MinecraftClient/Protocol/Handlers/Protocol18.cs b/MinecraftClient/Protocol/Handlers/Protocol18.cs index 0d6f04dd..e35317c4 100644 --- a/MinecraftClient/Protocol/Handlers/Protocol18.cs +++ b/MinecraftClient/Protocol/Handlers/Protocol18.cs @@ -451,13 +451,15 @@ namespace MinecraftClient.Protocol.Handlers byte fmlProtocolVersion = readNextByte(packetData); // There's another value afterwards for the dimension, but we don't need it. - ConsoleIO.WriteLineFormatted("§8Forge protocol version : " + fmlProtocolVersion); + if (Settings.DebugMessages) + ConsoleIO.WriteLineFormatted("§8Forge protocol version : " + fmlProtocolVersion); // Tell the server we're running the same version. SendForgeHandshakePacket(FMLHandshakeDiscriminator.ClientHello, new byte[] { fmlProtocolVersion }); // Then tell the server that we're running the same mods. - ConsoleIO.WriteLineFormatted("§8Sending falsified mod list to server..."); + if (Settings.DebugMessages) + ConsoleIO.WriteLineFormatted("§8Sending falsified mod list to server..."); byte[][] mods = new byte[forgeInfo.Mods.Count][]; for (int i = 0; i < forgeInfo.Mods.Count; i++) { @@ -476,7 +478,8 @@ namespace MinecraftClient.Protocol.Handlers Thread.Sleep(2000); - ConsoleIO.WriteLineFormatted("§8Accepting server mod list..."); + if (Settings.DebugMessages) + ConsoleIO.WriteLineFormatted("§8Accepting server mod list..."); // Tell the server that yes, we are OK with the mods it has // even though we don't actually care what mods it has. @@ -497,8 +500,8 @@ namespace MinecraftClient.Protocol.Handlers // with blocks and items. int registrySize = readNextVarInt(packetData); - ConsoleIO.WriteLineFormatted("§8Received registry " + - "with " + registrySize + " entries"); + if (Settings.DebugMessages) + ConsoleIO.WriteLineFormatted("§8Received registry with " + registrySize + " entries"); fmlHandshakeState = FMLHandshakeClientState.PENDINGCOMPLETE; } @@ -509,14 +512,10 @@ namespace MinecraftClient.Protocol.Handlers bool hasNextRegistry = readNextBool(packetData); string registryName = readNextString(packetData); int registrySize = readNextVarInt(packetData); - - ConsoleIO.WriteLineFormatted("§8Received registry " + registryName + - " with " + registrySize + " entries"); - + if (Settings.DebugMessages) + ConsoleIO.WriteLineFormatted("§8Received registry " + registryName + " with " + registrySize + " entries"); if (!hasNextRegistry) - { fmlHandshakeState = FMLHandshakeClientState.PENDINGCOMPLETE; - } } return false; @@ -525,9 +524,8 @@ namespace MinecraftClient.Protocol.Handlers // Just say yes. if (discriminator != FMLHandshakeDiscriminator.HandshakeAck) return false; - - ConsoleIO.WriteLineFormatted("§8Accepting server registries..."); - + if (Settings.DebugMessages) + ConsoleIO.WriteLineFormatted("§8Accepting server registries..."); SendForgeHandshakePacket(FMLHandshakeDiscriminator.HandshakeAck, new byte[] { (byte)FMLHandshakeClientState.PENDINGCOMPLETE }); fmlHandshakeState = FMLHandshakeClientState.COMPLETE; @@ -540,8 +538,8 @@ namespace MinecraftClient.Protocol.Handlers SendForgeHandshakePacket(FMLHandshakeDiscriminator.HandshakeAck, new byte[] { (byte)FMLHandshakeClientState.COMPLETE }); - ConsoleIO.WriteLine("Forge server connection complete!"); - + if (Settings.DebugMessages) + ConsoleIO.WriteLine("Forge server connection complete!"); fmlHandshakeState = FMLHandshakeClientState.DONE; return true; } @@ -582,7 +580,7 @@ namespace MinecraftClient.Protocol.Handlers private void ProcessChunkColumnData(int chunkX, int chunkZ, ushort chunkMask, bool hasSkyLight, bool chunksContinuous, List cache) { - if (protocolversion >= MC19Version && chunksContinuous && chunkMask == 0) + if (protocolversion < MC19Version && chunksContinuous && chunkMask == 0) { //Unload the entire chunk column handler.GetWorld()[chunkX, chunkZ] = null; @@ -1124,7 +1122,7 @@ namespace MinecraftClient.Protocol.Handlers { readNextPacket(ref packetID, packetData); - if (packetID == 0x40) // Disconect + if (packetID == 0x40) // Disconnect { handler.OnConnectionLost(ChatBot.DisconnectReason.LoginRejected, ChatParser.ParseText(readNextString(packetData))); return false; @@ -1148,7 +1146,8 @@ namespace MinecraftClient.Protocol.Handlers System.Security.Cryptography.RSACryptoServiceProvider RSAService = CryptoHandler.DecodeRSAPublicKey(serverKey); byte[] secretKey = CryptoHandler.GenerateAESPrivateKey(); - ConsoleIO.WriteLineFormatted("§8Crypto keys & hash generated."); + if (Settings.DebugMessages) + ConsoleIO.WriteLineFormatted("§8Crypto keys & hash generated."); if (serverIDhash != "-") { @@ -1408,8 +1407,6 @@ namespace MinecraftClient.Protocol.Handlers if (protocolversion < 47 && version.Split(' ', '/').Contains("1.8")) protocolversion = ProtocolHandler.MCVer2ProtocolVersion("1.8.0"); - ConsoleIO.WriteLineFormatted("§8Server version : " + version + " (protocol v" + protocolversion + ")."); - // Check for forge on the server. if (jsonData.Properties.ContainsKey("modinfo") && jsonData.Properties["modinfo"].Type == Json.JSONData.DataType.Object) { @@ -1418,13 +1415,24 @@ namespace MinecraftClient.Protocol.Handlers { forgeInfo = new ForgeInfo(modData); - ConsoleIO.WriteLineFormatted("§8Server is running forge. Mod list:"); - foreach (ForgeInfo.ForgeMod mod in forgeInfo.Mods) + if (forgeInfo.Mods.Any()) { - ConsoleIO.WriteLineFormatted("§8 " + mod.ToString()); + if (Settings.DebugMessages) + { + ConsoleIO.WriteLineFormatted("§8Server is running Forge. Mod list:"); + foreach (ForgeInfo.ForgeMod mod in forgeInfo.Mods) + { + ConsoleIO.WriteLineFormatted("§8 " + mod.ToString()); + } + } + else ConsoleIO.WriteLineFormatted("§8Server is running Forge."); } + else forgeInfo = null; } } + + ConsoleIO.WriteLineFormatted("§8Server version : " + version + " (protocol v" + protocolversion + (forgeInfo != null ? ", with Forge)." : ").")); + return true; } } diff --git a/MinecraftClient/Protocol/IMinecraftComHandler.cs b/MinecraftClient/Protocol/IMinecraftComHandler.cs index 7ca8cea6..dae4b516 100644 --- a/MinecraftClient/Protocol/IMinecraftComHandler.cs +++ b/MinecraftClient/Protocol/IMinecraftComHandler.cs @@ -90,8 +90,8 @@ namespace MinecraftClient.Protocol void UnregisterPluginChannel(string channel, ChatBot bot); /// - /// Sends a plugin channel packet to the server. See http://wiki.vg/Plugin_channel for more information - /// about plugin channels. + /// Sends a plugin channel packet to the server. + /// See http://wiki.vg/Plugin_channel for more information about plugin channels. /// /// The channel to send the packet on. /// The payload for the packet. diff --git a/MinecraftClient/Protocol/ProtocolHandler.cs b/MinecraftClient/Protocol/ProtocolHandler.cs index 84ddeee7..894f1c00 100644 --- a/MinecraftClient/Protocol/ProtocolHandler.cs +++ b/MinecraftClient/Protocol/ProtocolHandler.cs @@ -123,8 +123,9 @@ namespace MinecraftClient.Protocol case "1.8.6": case "1.8.7": case "1.8.8": - return 47; case "1.8.9": + return 47; + case "1.9.0": return 107; default: return 0; diff --git a/MinecraftClient/Protocol/SessionCache/CacheType.cs b/MinecraftClient/Protocol/SessionCache/CacheType.cs new file mode 100644 index 00000000..886d61f9 --- /dev/null +++ b/MinecraftClient/Protocol/SessionCache/CacheType.cs @@ -0,0 +1,4 @@ +namespace MinecraftClient.Protocol.SessionCache +{ + public enum CacheType { None, Memory, Disk }; +} diff --git a/MinecraftClient/Cache/SessionCache.cs b/MinecraftClient/Protocol/SessionCache/SessionCache.cs similarity index 85% rename from MinecraftClient/Cache/SessionCache.cs rename to MinecraftClient/Protocol/SessionCache/SessionCache.cs index a943958b..7a03fa9d 100644 --- a/MinecraftClient/Cache/SessionCache.cs +++ b/MinecraftClient/Protocol/SessionCache/SessionCache.cs @@ -6,15 +6,16 @@ using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using System.Timers; -namespace MinecraftClient.Cache +namespace MinecraftClient.Protocol.SessionCache { - /// - /// Handle sessions caching and storage. + /// + /// Handle sessions caching and storage. /// public static class SessionCache { - const string filename = "cache.bin"; + private const string SessionCacheFile = "SessionCache.db"; + private static Dictionary sessions = new Dictionary(); private static FileSystemWatcher cachemonitor = new FileSystemWatcher(); private static Timer updatetimer = new Timer(100); @@ -22,10 +23,10 @@ namespace MinecraftClient.Cache private static BinaryFormatter formatter = new BinaryFormatter(); - /// - /// Retrieve whether SessionCache contains a session for the given login. - /// - /// User login used with Minecraft.net + /// + /// Retrieve whether SessionCache contains a session for the given login. + /// + /// User login used with Minecraft.net /// TRUE if session is available public static bool Contains(string login) @@ -33,10 +34,10 @@ namespace MinecraftClient.Cache return sessions.ContainsKey(login); } - /// - /// Store a session and save it to disk if required. - /// - /// User login used with Minecraft.net + /// + /// Store a session and save it to disk if required. + /// + /// User login used with Minecraft.net /// User session token used with Minecraft.net public static void Store(string login, SessionToken session) @@ -50,18 +51,20 @@ namespace MinecraftClient.Cache sessions.Add(login, session); } - if (Settings.CacheType == CacheType.DISK && updatetimer.Enabled == true) { + if (Settings.SessionCaching == CacheType.Disk && updatetimer.Enabled == true) + { pendingadds.Add(new KeyValuePair(login, session)); - }else if (Settings.CacheType == CacheType.DISK) + } + else if (Settings.SessionCaching == CacheType.Disk) { SaveToDisk(); } } - /// - /// Retrieve a session token for the given login. - /// - /// User login used with Minecraft.net + /// + /// Retrieve a session token for the given login. + /// + /// User login used with Minecraft.net /// SessionToken for given login public static SessionToken Get(string login) @@ -69,16 +72,16 @@ namespace MinecraftClient.Cache return sessions[login]; } - /// - /// Initialize cache monitoring to keep cache updated with external changes. - /// + /// + /// Initialize cache monitoring to keep cache updated with external changes. + /// /// TRUE if session tokens are seeded from file public static bool InitializeDiskCache() { cachemonitor.Path = AppDomain.CurrentDomain.BaseDirectory; cachemonitor.IncludeSubdirectories = false; - cachemonitor.Filter = filename; + cachemonitor.Filter = SessionCacheFile; cachemonitor.NotifyFilter = NotifyFilters.LastWrite; cachemonitor.Changed += new FileSystemEventHandler(OnChanged); cachemonitor.EnableRaisingEvents = true; @@ -88,10 +91,10 @@ namespace MinecraftClient.Cache return LoadFromDisk(); } - /// - /// Reloads cache on external cache file change. - /// - /// Sender + /// + /// Reloads cache on external cache file change. + /// + /// Sender /// Event data private static void OnChanged(object sender, FileSystemEventArgs e) @@ -100,10 +103,10 @@ namespace MinecraftClient.Cache updatetimer.Start(); } - /// - /// Called after timer elapsed. Reads disk cache and adds new/modified sessions back. - /// - /// Sender + /// + /// Called after timer elapsed. Reads disk cache and adds new/modified sessions back. + /// + /// Sender /// Event data private static void HandlePending(object sender, ElapsedEventArgs e) @@ -117,18 +120,18 @@ namespace MinecraftClient.Cache } } - /// - /// Reads cache file and loads SessionTokens into SessionCache. - /// + /// + /// Reads cache file and loads SessionTokens into SessionCache. + /// /// True if data is successfully loaded private static bool LoadFromDisk() { - if (File.Exists(filename)) + if (File.Exists(SessionCacheFile)) { try { - using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read)) + using (FileStream fs = new FileStream(SessionCacheFile, FileMode.Open, FileAccess.Read, FileShare.Read)) { sessions = (Dictionary)formatter.Deserialize(fs); return true; @@ -146,15 +149,15 @@ namespace MinecraftClient.Cache return false; } - /// - /// Saves SessionToken's from SessionCache into cache file. + /// + /// Saves SessionToken's from SessionCache into cache file. /// private static void SaveToDisk() { - bool fileexists = File.Exists(filename); + bool fileexists = File.Exists(SessionCacheFile); - using (FileStream fs = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None)) + using (FileStream fs = new FileStream(SessionCacheFile, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None)) { cachemonitor.EnableRaisingEvents = false; diff --git a/MinecraftClient/Settings.cs b/MinecraftClient/Settings.cs index 0d86cdf2..679b86bf 100644 --- a/MinecraftClient/Settings.cs +++ b/MinecraftClient/Settings.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using System.IO; using System.Text.RegularExpressions; +using MinecraftClient.Protocol.SessionCache; namespace MinecraftClient { @@ -29,9 +30,6 @@ namespace MinecraftClient public static string SingleCommand = ""; public static string ConsoleTitle = ""; - //Cache Settings - public static Cache.CacheType CacheType = Cache.CacheType.NONE; - //Proxy Settings public static bool ProxyEnabledLogin = false; public static bool ProxyEnabledIngame = false; @@ -42,8 +40,8 @@ namespace MinecraftClient public static string ProxyPassword = ""; //Other Settings - public static string TranslationsFile_FromMCDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\.minecraft\assets\objects\03\03f31164d234f10a3230611656332f1756e570a9"; //MC 1.8 en_GB.lang - public static string TranslationsFile_Website_Index = "https://s3.amazonaws.com/Minecraft.Download/indexes/1.8.json"; + public static string TranslationsFile_FromMCDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\.minecraft\assets\objects\3d\3d7f778ea0a3baaf826ae75a094d77c46410902f"; //MC 1.9 en_GB.lang + public static string TranslationsFile_Website_Index = "https://s3.amazonaws.com/Minecraft.Download/indexes/1.9.json"; public static string TranslationsFile_Website_Download = "http://resources.download.minecraft.net"; public static TimeSpan splitMessageDelay = TimeSpan.FromSeconds(2); public static List Bots_Owners = new List(); @@ -60,6 +58,8 @@ namespace MinecraftClient public static bool DisplayXPBarMessages = true; public static bool TerrainAndMovements = false; public static string PrivateMsgsCmdName = "tell"; + public static CacheType SessionCaching = CacheType.None; + public static bool DebugMessages = false; //AntiAFK Settings public static bool AntiAFK_Enabled = false; @@ -187,6 +187,7 @@ namespace MinecraftClient case "terrainandmovements": TerrainAndMovements = str2bool(argValue); break; case "privatemsgscmdname": PrivateMsgsCmdName = argValue.ToLower().Trim(); break; case "botmessagedelay": botMessageDelay = TimeSpan.FromSeconds(str2int(argValue)); break; + case "debugmessages": DebugMessages = str2bool(argValue); break; case "botowners": Bots_Owners.Clear(); @@ -203,10 +204,10 @@ namespace MinecraftClient } break; - case "accountcache": - if (argValue == "none") { CacheType = Cache.CacheType.NONE; } - else if (argValue == "memory") { CacheType = Cache.CacheType.MEMORY; } - else if (argValue == "disk") { CacheType = Cache.CacheType.DISK; } + case "sessioncache": + if (argValue == "none") { SessionCaching = CacheType.None; } + else if (argValue == "memory") { SessionCaching = CacheType.Memory; } + else if (argValue == "disk") { SessionCaching = CacheType.Disk; } break; case "accountlist": @@ -425,11 +426,12 @@ namespace MinecraftClient + "showsystemmessages=true #system messages for server ops\r\n" + "showxpbarmessages=true #messages displayed above xp bar\r\n" + "terrainandmovements=false #uses more ram, cpu, bandwidth\r\n" - + "accountcache=none #use 'none', 'memory' or 'disk'\r\n" + + "sessioncache=memory #use 'none', 'memory' or 'disk'\r\n" + "accountlist=accounts.txt\r\n" + "serverlist=servers.txt\r\n" + "playerheadicon=true\r\n" + "exitonfailure=false\r\n" + + "debugmessages=false\r\n" + "scriptcache=true\r\n" + "timestamps=false\r\n" + "\r\n"