/// <summary> /// Send message in chat. Can use locale strings and write text from server to clients even if client don't have this /// mod /// </summary> /// <param name="m">Text to print</param> /// <param name="color">text color</param> public static void Post(string m, Color color) { switch (Main.netMode) { case NetmodeID.SinglePlayer: Main.NewText(m); break; case NetmodeID.Server: NetMessage.BroadcastChatMessage(NetworkText.FromKey(m), color); break; } }
/// <summary> /// Write text in to chat/console. /// Mostly used for debugging and sending client only related info /// </summary> /// <param name="m">Text to print</param> public static void Text(string m) { switch (Main.netMode) { case NetmodeID.MultiplayerClient: case NetmodeID.SinglePlayer: Main.NewText(m); break; case NetmodeID.Server: Console.WriteLine(m); break; } }
public override void HandlePacket(BinaryReader reader, int whoAmI) { NetPacketType type = (NetPacketType)reader.ReadByte(); if (type != NetPacketType.Custom) { //Currently only server can said us what we should do if (whoAmI != 256) { return; } } if (type == NetPacketType.EventWasStarted) { var name = reader.ReadString(); foreach (WorldEvent it in EventsPool) { if (it.GetType().Name == name) { ModContent.GetInstance <EventWorld>().StartWorldEvent(it); break; } } if (ModContent.GetInstance <EventWorld>().CurrentEvent == null) { Main.NewText( $"WARNING! You ether or disable FunMode or you are using outdated version of mod, what haven't an {name} event! Switching to NoSync mode..."); } ModContent.GetInstance <EventWorld>().CurrentEvent.TimeLeft = reader.ReadInt32(); InvasionType invType = (InvasionType)reader.ReadByte(); if (invType == InvasionType.Invasion) { Main.invasionProgressWave = reader.ReadInt32(); Main.invasionSizeStart = reader.ReadInt32(); Main.invasionSize = reader.ReadInt32(); Main.invasionType = reader.ReadInt32(); Main.invasionX = reader.ReadDouble(); Main.invasionProgress = reader.ReadInt32(); } } else if (type == NetPacketType.EventWaveUpdated) { var name = reader.ReadString(); if (ModContent.GetInstance <EventWorld>().CurrentEvent == null || ModContent.GetInstance <EventWorld>().CurrentEvent.GetType().Name != name) { //if (ModContent.GetInstance<EventWorld>().CurrentEvent == null) // Main.NewText($"WARNING! Currently you wont have any executing event, but server send wave update for {name} event!"); if (ModContent.GetInstance <EventWorld>().CurrentEvent.GetType().Name != name) { Main.NewText( $"ERROR! Currently executing event not the same what server sends! Executed event is: {ModContent.GetInstance<EventWorld>().CurrentEvent.GetType().Name}. Server has {name} event!"); ModContent.GetInstance <EventWorld>().CurrentEvent .EventEnd(ModContent.GetInstance <EventWorld>(), this); ModContent.GetInstance <EventWorld>().CurrentEvent = null; } foreach (WorldEvent it in EventsPool) { if (it.GetType().Name == name) { ModContent.GetInstance <EventWorld>().StartWorldEvent(it); break; } } if (ModContent.GetInstance <EventWorld>().CurrentEvent == null) { //Main.NewText($"WARNING! You ether or disable FunMode or you are using outdated version of mod, what haven't an {name} event!"); } } ModContent.GetInstance <EventWorld>().CurrentEvent.TimeLeft = reader.ReadInt32(); InvasionType invType = (InvasionType)reader.ReadByte(); if (invType == InvasionType.Invasion) { Main.invasionProgressWave = reader.ReadInt32(); Main.invasionSizeStart = reader.ReadInt32(); Main.invasionSize = reader.ReadInt32(); Main.invasionType = reader.ReadInt32(); Main.invasionX = reader.ReadDouble(); Main.invasionProgress = reader.ReadInt32(); ModContent.GetInstance <EventWorld>().CurrentEvent.OnWaveChange(); } } else if (type == NetPacketType.EventEnded) { var name = reader.ReadString(); if (ModContent.GetInstance <EventWorld>().CurrentEvent == null || ModContent.GetInstance <EventWorld>().CurrentEvent.GetType().Name != name) { if (ModContent.GetInstance <EventWorld>().CurrentEvent == null) { Main.NewText( $"WARNING! Currently you wont have any executing event, but server send event end for {name} event!"); } if (ModContent.GetInstance <EventWorld>().CurrentEvent.GetType().Name != name) { Main.NewText( $"ERROR! Currently executing event not the same what server sends! Executed event is: {ModContent.GetInstance<EventWorld>().CurrentEvent.GetType().Name}. Server has {name} event!"); ModContent.GetInstance <EventWorld>().CurrentEvent .EventEnd(ModContent.GetInstance <EventWorld>(), this); ModContent.GetInstance <EventWorld>().CurrentEvent = null; } } else { ModContent.GetInstance <EventWorld>().CurrentEvent .EventEnd(ModContent.GetInstance <EventWorld>(), this); ModContent.GetInstance <EventWorld>().CurrentEvent = null; } } else if (type == NetPacketType.Custom) { #region Constants const string lunarSky = "LunarSkies"; const string netSendFix = "NetSend"; #endregion var eve = reader.ReadString(); if (eve == lunarSky) { LunarSkies t = (LunarSkies)reader.ReadByte(); EventPlayer.LunarSky = t; } else if (eve == netSendFix) { var b = reader.ReadBoolean(); if (b) { ModPacket p = GetPacket(); p.Write((byte)NetPacketType.Custom); p.Write(netSendFix); p.Write(false); ModContent.GetInstance <EventWorld>().WriteNetSendData(p); p.Send(whoAmI); } else { ModContent.GetInstance <EventWorld>().NetReceive(reader); } } } }
public override void Load() { base.Load(); RecentChatters = new List <string>(); #if DEBUG //Used for debugging RecentChatters.AddRange(new[] { "Nightbot", "KarmikKoalla", "Moobot", "SomeoneFromChat" }); #endif Instance = this; BossCommands = new Dictionary <string, Action>(); EventsPool = new List <WorldEvent>(); LastStatus.Value = $"[c/{TwitchColor}: Client not connected]"; OldConfig = new TwitchOldConfig(Storage = new ModStorage(@"Twitch")); Store = new ResourceStore <byte[]>(new StorageBackedResourceStore(Storage)); if (ModLoader.version.Major == 10) { Store.AddStore(new OnlineStore()); } else { Store.AddStore(new WebStore("image/png")); } Textures = new Texture2DStore(Store); EmoticonHandler.store = new EmoticonsStore(Store); if (Storage.Exists("EmoteIDs.json")) { using (Stream p = Storage.GetStream("EmoteIDs.json")) using (StreamReader s = new StreamReader(p)) { try { EmoticonHandler.convertingEmotes = JsonConvert.DeserializeObject <Dictionary <string, int> >(s.ReadToEnd()); } catch (Exception e) { Logger.Warn($"Failed to load emotes id:\n{e}"); } } } // Just to create file OldConfig.Save(); Irc = new IrcClient(); // This client used in my twitch bot so class know all info about twitch irc server so we don't need to provide what info here //Start migrating to new configs //ShowDebug = OldConfig.Get<bool>(TwitchCfg.ShowAllIrc); //IgnoreCommands = OldConfig.Get<bool>(TwitchCfg.IgnoreCommands); //CommandPrefix = OldConfig.Get<string>(TwitchCfg.IgnoreCommandPrefix); Username = OldConfig.Get <string>(TwitchCfg.Username); Fun = OldConfig.Get <bool>(TwitchCfg.EnableFun); Channel = OldConfig.Get <string>(TwitchCfg.Channel); if (ShowDebug) { Razorwing.Framework.Logging.Logger.Storage = Storage; //Thx tML 0.11 for adding "Mod.Logger" <3 Breaking all as all ways } if (Fun) { //Since it not work on server (Not affect clients) until i write packets for this Twitch boss is disabled for server if (Main.netMode == NetmodeID.Server || Main.netMode == NetmodeID.SinglePlayer) { TwitchBoss.InitialiseDefault(); } //Register inner world event invasions foreach (Mod mod in ModLoader.Mods) { foreach (TypeInfo it in mod.GetType().Assembly.DefinedTypes) { if (!it.IsAbstract && ( it.BaseType != typeof(object) && it.BaseType == typeof(WorldEvent) || it.BaseType?.BaseType != typeof(object) && it.BaseType?.BaseType == typeof(WorldEvent)) ) //In case if WorldEvent is second parent { try { EventsPool.Add((WorldEvent)Activator.CreateInstance(it)); } catch (Exception e) { Logger.Error( "Exception caught in Events register loop. Report mod author with related stacktrace: \n" + $"{e.Message}\n" + $"{e.StackTrace}\n"); } } } } } if (ShowDebug) { Irc.ServerMessage += (s, m) => { try { Text(m); } catch (Exception) { Logger.Warn("Failed to post message"); } } } ; Irc.OnConnect += (s, e) => { LastStatus.Value = $"[c/{TwitchColor}:Connected]"; Irc.SendRaw("CAP REQ :twitch.tv/tags"); Thread.Sleep(500); Irc.SendRaw("CAP REQ :twitch.tv/commands"); Thread.Sleep(500); Irc.JoinChannel(Channel); inRestoringState = false; }; Irc.ConnectionClosed += (s, e) => { if (!inRestoringState) { LastStatus.Value = $"[c/{TwitchColor}:Connection lost!]"; inRestoringState = true; Thread.Sleep(5000); Irc.Connect(); } else { LastStatus.Value = $"[c/{TwitchColor}:Connection terminated! Client now offline]"; } }; Irc.ChannelMessage += (s, e) => { if (Main.netMode != NetmodeID.Server && !Main.gameMenu) { //If we ignore commands, we also want ignore bots messages if (IgnoreCommands) { if (e.Message.StartsWith(CommandPrefix)) { return; } //In case you self bot, we ignore your own messages if (e.From == Username) { return; } //if message was send by known bot, we ignore it if (KnownBots.Contains(e.From)) { return; } } var result = e.Message; var parsed = new List <SEmote>(); foreach (var it in e.Badge.emotes) { if (it == string.Empty) { break; } string[] pair = it.Split(':'); string[] ind = pair[1].Split(','); parsed.AddRange(ind.Select(p => { string[] ip = p.Split('-'); return(new SEmote(ip[0], ip[1], pair[0])); })); } if (parsed.Count != 0) { var list = new Dictionary <int, string>(); foreach (SEmote it in parsed) { if (list.ContainsKey(it.Emote)) { continue; } var st = e.Message.Substring(it.Start, it.End - it.Start + 1); //Not perfect because if Kappa mentioned in msg KappaPride get broken, //but it way faster what per glyph concat result = result.Replace(st, $"[e:{it.Emote}]"); list.Add(it.Emote, st); } foreach (KeyValuePair <int, string> em in list) { if (!EmoticonHandler.convertingEmotes.ContainsKey(em.Value)) { EmoticonHandler.convertingEmotes.Add(em.Value, em.Key); } } } else { result = e.Message; } var prefix = ""; if (e.Badge.sub) { prefix += $"[i:{ItemID.Star}] "; } if (e.Badge.mod) { prefix += $"[i:{ItemID.Arkhalis}]"; } //String format Main.NewText($@"{prefix} [c/{TwitchColor}:{e.Badge.DisplayName}]: {result}"); if (!RecentChatters.Contains(e.Badge.DisplayName)) { RecentChatters.Add(e.Badge.DisplayName); } } if ((Main.netMode == NetmodeID.Server || Main.netMode == NetmodeID.SinglePlayer) && Fun) { if (e.Message.StartsWith(CommandPrefix)) { return; } //In case you self bot, we ignore your own messages #if !DEBUG if (e.From == Username) { return; } #endif //if message was sent by known bot, we ignore it if (KnownBots.Contains(e.From)) { return; } //var word = e.Message.ToLower().Split(' ').First(); //if (CurrentPool?.ContainsKey(word) ?? false) //{ // CurrentPool[word]?.Invoke(e); //} if (e.From == TwitchBoss.Boss && TwitchBoss.Cooldown < DateTimeOffset.Now) { TwitchBoss.ProcessCommand(e); } } }; if (OldConfig.Get <bool>(TwitchCfg.AutoConnect) && OldConfig.Get <string>(TwitchCfg.OAToken) != "https://twitchapps.com/tmi/" && OldConfig.Get <string>(TwitchCfg.Username) != "missingno") { Irc.Username = OldConfig.Get <string>(TwitchCfg.Username); Irc.AuthToken = OldConfig.Get <string>(TwitchCfg.OAToken); Irc.Connect(); } WorldGen.SpawnTownNPC += SpawnTownNpcHook; }