private void UpdateStatusInfo() { if (InvokeRequired) { Invoke(new DelegEmpty(UpdateStatusInfo)); } else { try { if (!main.Tas.IsLoggedIn) { return; } Client.Battle b = main.Tas.GetBattle(); if (b == null) { return; } int players = b.Users.Count - b.CountSpectators(); toolStripStatusLabel1.Text = "on since: " + Program.startupTime.ToString("g"); toolStripStatusLabel2.Text = "players: " + players + "/" + b.MaxPlayers; toolStripStatusLabel3.Text = "mod: " + b.Mod.Name; toolStripStatusLabel4.Text = "map: " + b.Map.Name; toolStripStatusLabel5.Text = "last game: " + (main.Spring.GameStarted != DateTime.MinValue ? main.Spring.GameStarted.ToString("g") : "never"); if (!main.Spring.IsRunning) { if (players > 0) { if (notifyIcon1.Icon != Resources.joined) { notifyIcon1.Icon = Resources.joined; } } else if (notifyIcon1.Icon != Resources.ok) { notifyIcon1.Icon = Resources.ok; } } notifyIcon1.Text = players + "/" + b.MaxPlayers + "\r\n" + b.Map.Name + "\r\n" + (main.Spring.GameStarted != DateTime.MinValue ? main.Spring.GameStarted.ToString("g") : "never"); } catch {} } }
public void Connect(string host, int port) { serverHost = host; serverIp = Dns.GetHostAddresses(host)[0]; serverPort = port; battle = null; battleID = 0; existingUsers = new Dictionary<string, User>(); existingChannels = new Dictionary<string, ExistingChannel>(); joinedChannels = new Dictionary<string, Channel>(); isChanScanning = false; isLoggedIn = false; isConnected = false; username = ""; try { con = new ServerConnection(); con.Connect(host, port); con.ConnectionClosed += OnConnectionClosed; con.CommandRecieved += OnCommandRecieved; } catch { con = null; if (ConnectionLost != null) ConnectionLost(this, new TasEventArgs("Cannot connect to remote machine")); } }
public void Start(string modname, string mapname) { Stop(); manager = new AutoManager(this, tas, spring); lockedByKickSpec = false; autoLock = 0; kickSpectators = config.KickSpectators; minCpuSpeed = config.MinCpuSpeed; kickMinRank = config.KickMinRank; if (config.LadderId > 0) ladder = new Ladder(config.LadderId); else ladder = null; config.BattleDetails.Validate(); if (String.IsNullOrEmpty(modname)) modname = config.DefaultMod; if (String.IsNullOrEmpty(mapname)) mapname = config.DefaultMap; if (!spring.UnitSync.HasMap(mapname)) { IEnumerator<MapInfo> enu = spring.UnitSync.MapList.Values.GetEnumerator(); enu.MoveNext(); mapname = enu.Current.Name; } if (!spring.UnitSync.HasMod(modname)) { IEnumerator<ModInfo> enu = spring.UnitSync.ModList.Values.GetEnumerator(); enu.MoveNext(); modname = enu.Current.Name; } int mint, maxt; Battle b = new Battle((ladder == null ? config.Password : "******"), config.HostingPort, config.MaxPlayers, config.MinRank, spring.UnitSync.GetMapInfo(mapname), (ladder != null ? "(ladder " + ladder.Id + ") " : "") + config.GameTitle.Replace("%1", MainConfig.SpringieVersion), spring.UnitSync.GetModInfo(modname), (ladder != null ? ladder.CheckBattleDetails(config.BattleDetails, out mint, out maxt) : config.BattleDetails)); // if hole punching enabled then we use it if (config.UseHolePunching) b.Nat = Battle.NatMode.HolePunching; else if (Program.main.config.GargamelMode && Program.main.Stats != null) b.Nat = Battle.NatMode.FixedPorts; else b.Nat = Battle.NatMode.None; // else either no nat or fixed ports (for gargamel fake - to get client IPs) for (int i = 0; i < config.DefaultRectangles.Count; ++i) b.Rectangles.Add(i, config.DefaultRectangles[i]); tas.OpenBattle(b); }
public static void Generate(string filename, Battle b, int autoHostPort, out List<Battle.GrPlayer> players) { Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; var s = new StringBuilder(); s.AppendLine("[GAME]"); s.AppendLine("{"); s.AppendFormat(" Mapname={0};\n", b.Map.Name); s.AppendFormat(" StartMetal={0};\n", b.Details.StartingMetal); s.AppendFormat(" StartEnergy={0};\n", b.Details.StartingEnergy); s.AppendFormat(" MaxUnits={0};\n", b.Details.MaxUnits); s.AppendFormat(" StartPosType={0};\n", (int) b.Details.StartPos); s.AppendFormat(" GameMode={0};\n", (int) b.Details.EndCondition); s.AppendFormat(" GameType={0};\n", b.Mod.ArchiveName); s.AppendFormat(" LimitDGun={0};\n", b.Details.LimitDgun); s.AppendFormat(" DiminishingMMs={0};\n", b.Details.DiminishingMM); s.AppendFormat(" GhostedBuildings={0};\n", b.Details.GhostedBuildings); s.AppendFormat(" AutohostPort={0};\n", autoHostPort); s.AppendLine(); s.AppendFormat(" HostIP={0};\n", "127.0.0.1"); s.AppendFormat(" HostPort={0};\n", b.HostPort); //s.AppendFormat(" MinSpeed={0};\n", 1); //s.AppendFormat(" MaxSpeed={0};\n", 1); s.AppendLine(); s.AppendFormat(" MyPlayerNum={0};\n", 0); //List<Battle.GrPlayer> players; List<Battle.GrTeam> teams; List<Battle.GrAlly> alliances; b.GroupData(out players, out teams, out alliances); s.AppendLine(); s.AppendFormat(" NumPlayers={0};\n", players.Count); s.AppendFormat(" NumTeams={0};\n", teams.Count); s.AppendFormat(" NumAllyTeams={0};\n", alliances.Count); s.AppendLine(); // PLAYERS for (int i = 0; i < players.Count; ++i) { var u = players[i].user; s.AppendFormat(" [PLAYER{0}]\n", i); s.AppendLine(" {"); s.AppendFormat(" name={0};\n", u.name); s.AppendFormat(" Spectator={0};\n", u.IsSpectator ? 1 : 0); if (!u.IsSpectator) s.AppendFormat(" team={0};\n", u.TeamNumber); s.AppendLine(" }"); } // TEAMS s.AppendLine(); for (int i = 0; i < teams.Count; ++i) { s.AppendFormat(" [TEAM{0}]\n", i); s.AppendLine(" {"); s.AppendFormat(" TeamLeader={0};\n", teams[i].leader); var u = teams[i].bot ?? players[teams[i].leader].user; s.AppendFormat(" AllyTeam={0};\n", u.AllyNumber); s.AppendFormat(" RGBColor={0:F5} {1:F5} {2:F5};\n", (u.TeamColor & 255)/255.0, ((u.TeamColor >> 8) & 255)/255.0, ((u.TeamColor >> 16) & 255)/255.0); s.AppendFormat(" Side={0};\n", b.Mod.Sides[u.Side]); s.AppendFormat(" Handicap={0};\n", 0); if (teams[i].bot != null) s.AppendFormat(" AIDLL={0};\n", teams[i].bot.aiLib); s.AppendLine(" }"); } // ALLYS s.AppendLine(); for (int i = 0; i < alliances.Count; ++i) { s.AppendFormat("[ALLYTEAM{0}]\n", i); s.AppendLine("{"); s.AppendFormat(" NumAllies={0};\n", 0); double left, top, right, bottom; alliances[i].rect.ToFractions(out left, out top, out right, out bottom); s.AppendFormat(" StartRectLeft={0};\n", left); s.AppendFormat(" StartRectTop={0};\n", top); s.AppendFormat(" StartRectRight={0};\n", right); s.AppendFormat(" StartRectBottom={0};\n", bottom); s.AppendLine("}"); } s.AppendLine(); s.AppendFormat(" NumRestrictions={0};\n", b.DisabledUnits.Count); s.AppendLine(" [RESTRICT]"); s.AppendLine(" {"); for (int i = 0; i < b.DisabledUnits.Count; ++i) { s.AppendFormat(" Unit{0}={1};\n", i, b.DisabledUnits[i]); s.AppendFormat(" Limit{0}=0;\n", i); } s.AppendLine(" }"); s.AppendLine(" [modoptions]"); s.AppendLine(" {"); foreach (var o in b.Mod.Options) { string v = o.Default; if (b.ModOptions.ContainsKey(o.Key)) v = b.ModOptions[o.Key]; s.AppendFormat(" {0}={1};\n", o.Key, v); } s.AppendLine(" }"); s.AppendLine("}"); var f = File.CreateText(filename); f.Write(s.ToString()); f.Flush(); f.Close(); }
// SPRING.EXE functions public void StartGame(Battle battle) { if (!IsRunning) { ConfigMaker.Generate(path + "springie.txt", battle, out players); process = new Process(); process.StartInfo.CreateNoWindow = true; if (Program.main.config.SpringStartsMinimized) { process.StartInfo.Arguments = "/minimise "; } else process.StartInfo.Arguments = ""; process.StartInfo.Arguments += "springie.txt"; process.StartInfo.RedirectStandardOutput = true; process.StartInfo.WorkingDirectory = path; process.StartInfo.FileName = path + ExecutableName; process.StartInfo.UseShellExecute = false; process.Exited += new EventHandler(springProcess_Exited); Thread.Sleep(1000); // give time to user's spring to start and ignore upcoming registry hax PrepareRegistry(); process.Start(); gameStarted = DateTime.Now; process.WaitForInputIdle(); outputReader = new Thread(SpringOutputReader); outputReader.Name = "SpringOutputReader"; outputReader.Start(this); talker = new Talker(process); RestoreRegistry(); if (IsRunning && SpringStarted != null) SpringStarted(this, EventArgs.Empty); SpringWindowHidden = Program.main.config.SpringStartsHidden; System.Threading.Thread.Sleep(1000); ProcessPriority = Program.main.config.HostingProcessPriority; } }
void spring_SpringStarted(object sender, EventArgs e) { battle = tas.GetBattle(); players = new Dictionary<string, Player>(); startTime = DateTime.Now; }
public void SendBattleResult(Battle battle, Dictionary<string, EndGamePlayerInfo> players) { try { var response = server.SendBattleResult(account, battle.Map.Name, players.Values); autoHost.SayBattle(response.MessageToDisplay); var users = tas.GetBattle().Users; foreach (var p in players.Values) if (p.Name != tas.UserName && users.Find(x => x.name == p.Name) == null) tas.Say(TasClient.SayPlace.User, p.Name, response.MessageToDisplay, false); foreach (var kvp in response.RankNotifications) tas.Say(TasClient.SayPlace.User, kvp.Name, kvp.Text, false); ComListPlanets(TasSayEventArgs.Default, new string[] {}); } catch (Exception ex) { autoHost.SayBattle(string.Format("Error sending planet battle result :(( {0}", ex), true); } }
public void OpenBattle(Battle nbattle) { LeaveBattle(); // leave current battle battleID = -1; battle = (Battle) nbattle.Clone(); var objList = new List<object>(); objList.Add(0); // type = normal objList.Add((int) battle.Nat); objList.Add(battle.Password); objList.Add(battle.HostPort); objList.Add(battle.MaxPlayers); ; //battle.Details.AddToParamList(objList); objList.Add(battle.Mod.Checksum); objList.Add(battle.Rank); objList.Add(battle.Map.Checksum); objList.Add(battle.Map.Name); objList.Add('\t' + battle.Title); objList.Add('\t' + battle.Mod.Name); mapToChangeTo = battle.Map; lockToChangeTo = false; con.SendCommand(0, "OPENBATTLE", objList.ToArray()); lastSpectatorCount = -1; // send predefined starting rectangles foreach (var v in battle.Rectangles) con.SendCommand(0, "ADDSTARTRECT", v.Key, v.Value.Left, v.Value.Top, v.Value.Right, v.Value.Bottom); }
/// <summary> /// Primary method - processes commands from server /// </summary> /// <param name="command">command name</param> /// <param name="args">command arguments</param> private void DispatchServerCommand(string command, string[] args) { try { switch (command) { case "TASServer": // happens after connecting to server serverVersion = args[0]; int.TryParse(args[1], out serverUdpHolePunchingPort); isConnected = true; if (Connected != null) Connected(this, new TasEventArgs()); break; case "ACCEPTED": // Login accepted username = args[0]; isLoggedIn = true; if (LoginAccepted != null) LoginAccepted(this, new TasEventArgs()); break; case "DENIED": // login denied isLoggedIn = false; if (LoginDenied != null) LoginDenied(this, new TasEventArgs(Utils.Glue(args))); break; case "JOIN": // channel joined if (!joinedChannels.ContainsKey(args[0])) joinedChannels.Add(args[0], Channel.Create(args[0])); if (ChannelJoined != null) ChannelJoined(this, new TasEventArgs(args)); break; case "JOINFAILED": // channel join failed if (ChannelJoinFailed != null) ChannelJoinFailed(this, new TasEventArgs(Utils.Glue(args))); break; case "CHANNEL": // iterating channels { ExistingChannel c = new ExistingChannel(); c.name = args[0]; int.TryParse(args[1], out c.userCount); if (args.Length >= 3) c.topic = Utils.Glue(args, 2); existingChannels.Add(c.name, c); } break; case "ENDOFCHANNELS": // end of channel list iteration isChanScanning = false; if (ChannelListDone != null) ChannelListDone(this, new TasEventArgs()); break; case "ADDUSER": // new user joined ta server { User u = User.Create(args[0]); u.country = args[1]; int.TryParse(args[2], out u.cpu); //IPAddress.TryParse(args[3], out u.ip); existingUsers.Add(u.name, u); if (UserAdded != null) UserAdded(this, new TasEventArgs(args)); } break; case "REMOVEUSER": // user left ta server existingUsers.Remove(args[0]); if (UserRemoved != null) UserRemoved(this, new TasEventArgs(args)); break; case "MOTD": // server motd if (Said != null && args.Length > 0) Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Server, TasSayEventArgs.Places.Motd, "", "", Utils.Glue(args, 0), false)); break; case "SERVERMSG": // server message if (Said != null) Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Server, TasSayEventArgs.Places.Normal, "", "", Utils.Glue(args, 0), false)); break; case "SERVERMSGBOX": // server messagebox if (Said != null) Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Server, TasSayEventArgs.Places.MessageBox, "", "", Utils.Glue(args, 0), false)); break; case "CHANNELMESSAGE": // server broadcast to channel if (Said != null) Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Server, TasSayEventArgs.Places.Channel, args[0], "", Utils.Glue(args, 1), false)); break; case "SAID": // someone said something in channel if (Said != null) Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Player, TasSayEventArgs.Places.Channel, args[0], args[1], Utils.Glue(args, 2), false)); break; case "SAIDEX": // someone said something with emote in channel if (Said != null) Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Player, TasSayEventArgs.Places.Channel, args[0], args[1], Utils.Glue(args, 2), true)); break; case "SAYPRIVATE": // sent back from sever when user sends private message if (Said != null) Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Player, TasSayEventArgs.Places.Normal, args[0], username, Utils.Glue(args, 1), false)); // channel = char partner name break; case "SAIDPRIVATE": // someone said something to me if (Said != null) Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Player, TasSayEventArgs.Places.Normal, args[0], args[0], Utils.Glue(args, 1), false)); break; case "SAIDBATTLE": // someone said something in battle if (Said != null) Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Player, TasSayEventArgs.Places.Battle, "", args[0], Utils.Glue(args, 1), false)); break; case "SAIDBATTLEEX": // someone said in battle with emote if (Said != null) Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Player, TasSayEventArgs.Places.Battle, "", args[0], Utils.Glue(args, 1), true)); break; case "BROADCAST": // server sends urgent broadcast if (Said != null) Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Server, TasSayEventArgs.Places.Broadcast, "", "", Utils.Glue(args, 0), false)); break; case "REDIRECT": // server sends backup IP // removed due to bugs break; case "CLIENTSTATUS": // client's status changed { int status = 0; int.TryParse(args[1], out status); User u = existingUsers[args[0]]; u.FromInt(status); existingUsers[args[0]] = u; if (UserStatusChanged != null) UserStatusChanged(this, new TasEventArgs(args)); } break; case "CLIENTS": // client list sent after channel join string[] usrs = Utils.Glue(args, 1).Split(' '); foreach (string s in usrs) { joinedChannels[args[0]].channelUsers.Add(s); } if (ChannelUserAdded != null) ChannelUserAdded(this, new TasEventArgs(args[0])); break; case "JOINED": // user joined one of my channels joinedChannels[args[0]].channelUsers.Add(args[1]); if (ChannelUserAdded != null) ChannelUserAdded(this, new TasEventArgs(args[0])); break; case "LEFT": // user left one of my channels joinedChannels[args[0]].channelUsers.Remove(args[1]); if (ChannelUserRemoved != null) ChannelUserRemoved(this, new TasEventArgs(args[0], args[1], Utils.Glue(args, 2))); break; case "CHANNELTOPIC": // channel topic update (after joining a channel) { Channel c = joinedChannels[args[0]]; c.topicSetBy = args[1]; c.topicSetDate = ConvertMilisecondTime(args[2]); c.topic = Utils.Glue(args, 3); if (ChannelTopicChanged != null) ChannelTopicChanged(this, new TasEventArgs(args[0])); } break; case "OPENBATTLEFAILED": // opening new battle has failed if (BattleOpenFailed != null) BattleOpenFailed(this, new TasEventArgs(Utils.Glue(args))); break; case "OPENBATTLE": // openbattle ok { battleID = int.Parse(args[0]); UserBattleStatus self = new UserBattleStatus(username); self.IsSpectator = true; battle.Users.Add(self); // add self if (BattleOpened != null) BattleOpened(this, new TasEventArgs(args[0])); } break; case "REQUESTBATTLESTATUS": // server asks us to update our status con.SendCommand(0, "MYBATTLESTATUS", 1 << 22, 0); // tell server that we are synchronized spectators break; case "JOINEDBATTLE": // user joined the battle if (battle != null && int.Parse(args[0]) == battleID) { battle.Users.Add(new UserBattleStatus(args[1])); if (BattleUserJoined != null) BattleUserJoined(this, new TasEventArgs(args[1])); } break; case "LEFTBATTLE": // user left the battle if (battle != null && int.Parse(args[0]) == battleID) { battle.RemoveUser(args[1]); UpdateSpectators(); if (BattleUserLeft != null) BattleUserLeft(this, new TasEventArgs(args[1])); if (args[1] == username) { battle = null; battleID = 0; if (BattleClosed != null) BattleClosed(this, new TasEventArgs()); } } break; case "CLIENTBATTLESTATUS": // player battle status has changed if (battle != null) { int uindex = battle.GetUserIndex(args[0]); if (uindex != -1) { UserBattleStatus bs = battle.Users[uindex]; bs.SetFrom(int.Parse(args[1]), int.Parse(args[2])); battle.Users[uindex] = bs; UpdateSpectators(); if (BattleUserStatusChanged != null) BattleUserStatusChanged(this, new TasEventArgs(args[0])); } } break; case "UPDATEBATTLEINFO": // update external battle info (lock and map) if (battle != null && int.Parse(args[0]) == battleID) { string mapname = Utils.Glue(args, 4); if (battle.Map.Name != mapname) { if (mapToChangeTo != null && mapToChangeTo.Name == mapname) { // if we changed to known requested map, use it battle.Map = mapToChangeTo; } else battle.Map = Program.main.Spring.UnitSync.MapList[mapname]; //otherwise find this map using unitsync if (BattleMapChanged != null) BattleMapChanged(this, new TasEventArgs(mapname)); } if (battle.IsLocked != int.Parse(args[2]) > 0) { battle.IsLocked = int.Parse(args[2]) > 0; if (BattleLockChanged != null) BattleLockChanged(this, new TasEventArgs(args[2])); } } break; case "UPDATEBATTLEDETAILS": // updates internal battle details if (battle != null) { BattleDetails bd = new BattleDetails(); bd.StartingMetal = int.Parse(args[0]); bd.StartingEnergy = int.Parse(args[1]); bd.MaxUnits = int.Parse(args[2]); bd.StartPos = (BattleStartPos)int.Parse(args[3]); bd.EndCondition = (BattleEndCondition)int.Parse(args[4]); bd.LimitDgun = int.Parse(args[5]); bd.DiminishingMM = int.Parse(args[6]); bd.GhostedBuildings = int.Parse(args[7]); battle.Details = bd; if (BattleDetailsChanged != null) BattleDetailsChanged(this, new TasEventArgs(args)); } break; case "BATTLEOPENED": { if (BattleFound != null) BattleFound(this, new TasEventArgs(args)); break; } case "CLIENTIPPORT": if (battle != null) { int idx = battle.GetUserIndex(args[0]); if (idx != -1) { UserBattleStatus bs = battle.Users[idx]; bs.ip = IPAddress.Parse(args[1]); battle.Users[idx] = bs; if (BattleUserIpRecieved != null) BattleUserIpRecieved(this, new TasEventArgs(args)); } } break; } } catch (Exception e) { if (!ErrorHandling.HandleException(e, "Exception while dispatching " + command)) throw e; }; }
public void Start(string modname, string mapname) { Stop(); kickSpectators = config.KickSpectators; minCpuSpeed = config.MinCpuSpeed; config.BattleDetails.Validate(); if (String.IsNullOrEmpty(modname)) modname = config.DefaultMod; if (String.IsNullOrEmpty(mapname)) mapname = config.DefaultMap; if (!spring.UnitSync.HasMap(mapname)) { IEnumerator<MapInfo> enu = spring.UnitSync.MapList.Values.GetEnumerator(); enu.MoveNext(); mapname = enu.Current.Name; } if (!spring.UnitSync.HasMod(modname)) { IEnumerator<ModInfo> enu = spring.UnitSync.ModList.Values.GetEnumerator(); enu.MoveNext(); modname = enu.Current.Name; } Battle b = new Battle(config.Password, config.HostingPort, config.MaxPlayers, config.MinRank, spring.UnitSync.GetMapInfo(mapname), config.GameTitle.Replace("%1", MainConfig.SpringieVersion), spring.UnitSync.GetModInfo(modname), config.BattleDetails); // if hole punching enabled then we use it if (config.UseHolePunching) b.Nat = Battle.NatMode.HolePunching; else if (Program.main.config.GargamelMode && Program.main.Stats != null) b.Nat = Battle.NatMode.FixedPorts; else b.Nat = Battle.NatMode.None; // else either no nat or fixed ports (for gargamel fake - to get client IPs) for (int i = 0; i < config.DefaultRectangles.Count; ++i) { b.Rectangles.Add(i, config.DefaultRectangles[i]); } tas.OpenBattle(b); }
public void OpenBattle(Battle nbattle) { LeaveBattle(); // leave current battle battleID = -1; this.battle = (Battle)nbattle.Clone(); List<Object> objList = new List<object>(); objList.Add(0); // type = normal objList.Add(Program.main.config.GargamelMode ? 2 : 0); // nat - fixed ports for gargamel otherwise 0 objList.Add(battle.Password); objList.Add(battle.HostPort); objList.Add(battle.MaxPlayers); ; battle.Details.AddToParamList(objList); objList.Add(battle.Mod.Checksum); objList.Add(battle.Rank); objList.Add(battle.Map.Checksum); objList.Add(battle.Map.Name); objList.Add('\t' + battle.Title); objList.Add('\t' + battle.Mod.Name); mapToChangeTo = battle.Map; lockToChangeTo = false; con.SendCommand(0, "OPENBATTLE", objList.ToArray()); lastSpectatorCount = -1; // send predefined starting rectangles foreach (KeyValuePair<int, BattleRect> v in battle.Rectangles) { con.SendCommand(0, "ADDSTARTRECT", v.Key, v.Value.Left, v.Value.Top, v.Value.Right, v.Value.Bottom); } }
public void Start(string modname, string mapname) { Stop(); config.BattleDetails.Validate(); if (String.IsNullOrEmpty(modname)) modname = config.DefaultMod; if (String.IsNullOrEmpty(mapname)) mapname = config.DefaultMap; if (!spring.UnitSync.HasMap(mapname)) { IEnumerator<MapInfo> enu = spring.UnitSync.MapList.Values.GetEnumerator(); enu.MoveNext(); mapname = enu.Current.Name; } if (!spring.UnitSync.HasMod(modname)) { IEnumerator<ModInfo> enu = spring.UnitSync.ModList.Values.GetEnumerator(); enu.MoveNext(); modname = enu.Current.Name; } Battle b = new Battle(config.Password, config.HostingPort, config.MaxPlayers, config.MinRank, spring.UnitSync.GetMapInfo(mapname), config.GameTitle.Replace("%1", MainConfig.SpringieVersion), spring.UnitSync.GetModInfo(modname), config.BattleDetails); for (int i = 0; i < config.DefaultRectangles.Count; ++i) { b.Rectangles.Add(i, config.DefaultRectangles[i]); } tas.OpenBattle(b); //unsyncKicker = new UnSyncKicker(tas); }
/// <summary> /// Primary method - processes commands from server /// </summary> /// <param name="command">command name</param> /// <param name="args">command arguments</param> private void DispatchServerCommand(string command, string[] args) { try { switch (command) { case "TASServer": // happens after connecting to server serverVersion = args[0]; int.TryParse(args[1], out serverUdpHolePunchingPort); isConnected = true; if (Connected != null) { Connected(this, new TasEventArgs()); } break; case "ACCEPTED": // Login accepted username = args[0]; isLoggedIn = true; if (LoginAccepted != null) { LoginAccepted(this, new TasEventArgs()); } break; case "DENIED": // login denied isLoggedIn = false; if (LoginDenied != null) { LoginDenied(this, new TasEventArgs(Utils.Glue(args))); } break; case "JOIN": // channel joined if (!joinedChannels.ContainsKey(args[0])) { joinedChannels.Add(args[0], Channel.Create(args[0])); } if (ChannelJoined != null) { ChannelJoined(this, new TasEventArgs(args)); } break; case "JOINFAILED": // channel join failed if (ChannelJoinFailed != null) { ChannelJoinFailed(this, new TasEventArgs(Utils.Glue(args))); } break; case "CHANNEL": // iterating channels { ExistingChannel c = new ExistingChannel(); c.name = args[0]; int.TryParse(args[1], out c.userCount); if (args.Length >= 3) { c.topic = Utils.Glue(args, 2); } existingChannels.Add(c.name, c); } break; case "ENDOFCHANNELS": // end of channel list iteration isChanScanning = false; if (ChannelListDone != null) { ChannelListDone(this, new TasEventArgs()); } break; case "ADDUSER": // new user joined ta server { User u = User.Create(args[0]); u.country = args[1]; int.TryParse(args[2], out u.cpu); IPAddress.TryParse(args[3], out u.ip); existingUsers.Add(u.name, u); if (UserAdded != null) { UserAdded(this, new TasEventArgs(args)); } } break; case "REMOVEUSER": // user left ta server existingUsers.Remove(args[0]); if (UserRemoved != null) { UserRemoved(this, new TasEventArgs(args)); } break; case "MOTD": // server motd if (Said != null && args.Length > 0) { Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Server, TasSayEventArgs.Places.Motd, "", "", Utils.Glue(args, 0), false)); } break; case "SERVERMSG": // server message if (Said != null) { Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Server, TasSayEventArgs.Places.Normal, "", "", Utils.Glue(args, 0), false)); } break; case "SERVERMSGBOX": // server messagebox if (Said != null) { Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Server, TasSayEventArgs.Places.MessageBox, "", "", Utils.Glue(args, 0), false)); } break; case "CHANNELMESSAGE": // server broadcast to channel if (Said != null) { Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Server, TasSayEventArgs.Places.Channel, args[0], "", Utils.Glue(args, 1), false)); } break; case "SAID": // someone said something in channel if (Said != null) { Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Player, TasSayEventArgs.Places.Channel, args[0], args[1], Utils.Glue(args, 2), false)); } break; case "SAIDEX": // someone said something with emote in channel if (Said != null) { Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Player, TasSayEventArgs.Places.Channel, args[0], args[1], Utils.Glue(args, 2), true)); } break; case "SAYPRIVATE": // sent back from sever when user sends private message if (Said != null) { Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Player, TasSayEventArgs.Places.Normal, args[0], username, Utils.Glue(args, 1), false)); // channel = char partner name } break; case "SAIDPRIVATE": // someone said something to me if (Said != null) { Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Player, TasSayEventArgs.Places.Normal, args[0], args[0], Utils.Glue(args, 1), false)); } break; case "SAIDBATTLE": // someone said something in battle if (Said != null) { Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Player, TasSayEventArgs.Places.Battle, "", args[0], Utils.Glue(args, 1), false)); } break; case "SAIDBATTLEEX": // someone said in battle with emote if (Said != null) { Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Player, TasSayEventArgs.Places.Battle, "", args[0], Utils.Glue(args, 1), true)); } break; case "BROADCAST": // server sends urgent broadcast if (Said != null) { Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Server, TasSayEventArgs.Places.Broadcast, "", "", Utils.Glue(args, 0), false)); } break; case "REDIRECT": // server sends backup IP // removed due to bugs break; case "CLIENTSTATUS": // client's status changed { int status = 0; int.TryParse(args[1], out status); User u = existingUsers[args[0]]; u.FromInt(status); existingUsers[args[0]] = u; if (UserStatusChanged != null) { UserStatusChanged(this, new TasEventArgs(args)); } } break; case "CLIENTS": // client list sent after channel join string[] usrs = Utils.Glue(args, 1).Split(' '); foreach (string s in usrs) { joinedChannels[args[0]].channelUsers.Add(s); } if (ChannelUserAdded != null) { ChannelUserAdded(this, new TasEventArgs(args[0])); } break; case "JOINED": // user joined one of my channels joinedChannels[args[0]].channelUsers.Add(args[1]); if (ChannelUserAdded != null) { ChannelUserAdded(this, new TasEventArgs(args[0])); } break; case "LEFT": // user left one of my channels joinedChannels[args[0]].channelUsers.Remove(args[1]); if (ChannelUserRemoved != null) { ChannelUserRemoved(this, new TasEventArgs(args[0], args[1], Utils.Glue(args, 2))); } break; case "CHANNELTOPIC": // channel topic update (after joining a channel) { Channel c = joinedChannels[args[0]]; c.topicSetBy = args[1]; c.topicSetDate = ConvertMilisecondTime(args[2]); c.topic = Utils.Glue(args, 3); if (ChannelTopicChanged != null) { ChannelTopicChanged(this, new TasEventArgs(args[0])); } } break; case "OPENBATTLEFAILED": // opening new battle has failed if (BattleOpenFailed != null) { BattleOpenFailed(this, new TasEventArgs(Utils.Glue(args))); } break; case "OPENBATTLE": // openbattle ok battleID = int.Parse(args[0]); battle.Users.Add(new UserBattleStatus(username)); // add self if (BattleOpened != null) { BattleOpened(this, new TasEventArgs(args[0])); } break; case "REQUESTBATTLESTATUS": // server asks us to update our status con.SendCommand(0, "MYBATTLESTATUS", 1 << 22, 0); // tell server that we are synchronized spectators break; case "JOINEDBATTLE": // user joined the battle if (battle != null && int.Parse(args[0]) == battleID) { battle.Users.Add(new UserBattleStatus(args[1])); if (BattleUserJoined != null) { BattleUserJoined(this, new TasEventArgs(args[1])); } } break; case "LEFTBATTLE": // user left the battle if (battle != null && int.Parse(args[0]) == battleID) { battle.RemoveUser(args[1]); UpdateSpectators(); if (BattleUserLeft != null) { BattleUserLeft(this, new TasEventArgs(args[1])); } if (args[1] == username) { battle = null; battleID = 0; if (BattleClosed != null) { BattleClosed(this, new TasEventArgs()); } } } break; case "CLIENTBATTLESTATUS": // player battle status has changed if (battle != null) { int uindex = battle.GetUserIndex(args[0]); UserBattleStatus bs = battle.Users[uindex]; bs.SetFrom(int.Parse(args[1]), int.Parse(args[2])); battle.Users[uindex] = bs; UpdateSpectators(); if (BattleUserStatusChanged != null) { BattleUserStatusChanged(this, new TasEventArgs(args[0])); } } break; case "UPDATEBATTLEINFO": // update external battle info (lock and map) if (battle != null && int.Parse(args[0]) == battleID) { if (battle.Map != Utils.Glue(args, 3)) { battle.Map = Utils.Glue(args, 3); if (BattleMapChanged != null) { BattleMapChanged(this, new TasEventArgs(Utils.Glue(args, 3))); } } if (battle.IsLocked != int.Parse(args[2]) > 0) { battle.IsLocked = int.Parse(args[2]) > 0; if (BattleLockChanged != null) { BattleLockChanged(this, new TasEventArgs(args[2])); } } } break; case "UPDATEBATTLEDETAILS": // updates internal battle details if (battle != null) { BattleDetails bd = new BattleDetails(); bd.StartingMetal = int.Parse(args[0]); bd.StartingEnergy = int.Parse(args[1]); bd.MaxUnits = int.Parse(args[2]); bd.StartPos = (BattleStartPos)int.Parse(args[3]); bd.EndCondition = (BattleEndCondition)int.Parse(args[4]); bd.LimitDgun = int.Parse(args[5]); bd.DiminishingMM = int.Parse(args[6]); bd.GhostedBuildings = int.Parse(args[7]); battle.Details = bd; if (BattleDetailsChanged != null) { BattleDetailsChanged(this, new TasEventArgs(args)); } } break; case "BATTLEOPENED": { if (BattleFound != null) { BattleFound(this, new TasEventArgs(args)); } break; } } } catch (Exception e) { if (!ErrorHandling.HandleException(e, "Exception while dispatching " + command)) { throw e; } }; }
public void Disconnect() { if (con != null && isConnected) con.Close(); //con.CommandRecieved existingUsers = new Dictionary<string, User>(); existingChannels = new Dictionary<string, ExistingChannel>(); joinedChannels = new Dictionary<string, Channel>(); battle = null; battleID = 0; username = ""; isLoggedIn = false; isConnected = false; isChanScanning = false; }
public void StartGame(Battle battle) { if (!IsRunning) { List<Battle.GrPlayer> players; talker = new Talker(); readyPlayers.Clear(); talker.SpringEvent += talker_SpringEvent; string configName = Path.Combine(Program.WorkPath, "springie" + Program.main.AutoHost.config.HostingPort + ".txt").Replace('\\', '/'); ConfigMaker.Generate(configName, battle, talker.LoopbackPort, out players); talker.SetPlayers(players); process = new Process(); process.StartInfo.CreateNoWindow = true; process.StartInfo.Arguments += configName; process.StartInfo.FileName = Program.main.config.ExecutableName; process.StartInfo.WorkingDirectory = Path.GetDirectoryName(Program.main.config.ExecutableName); process.StartInfo.UseShellExecute = false; process.Exited += springProcess_Exited; process.EnableRaisingEvents = true; PlanetWarsMessages = new Dictionary<string, int>(); process.Start(); gameStarted = DateTime.Now; Thread.Sleep(1000); if (!Program.IsLinux && IsRunning) process.PriorityClass = Program.main.config.HostingProcessPriority; if (IsRunning && SpringStarted != null) SpringStarted(this, EventArgs.Empty); } }
public void LeaveBattle() { if (battle != null) { con.SendCommand(0, "LEAVEBATTLE"); battle = null; battleID = 0; if (BattleClosed != null) BattleClosed(this, new TasEventArgs()); } }
// SPRING.EXE functions public void StartGame(Battle battle) { if (!IsRunning) { List<Battle.GrPlayer> players; talker = new Talker(); talker.SpringEvent += new EventHandler<Talker.SpringEventArgs>(talker_SpringEvent); string configName = "springie" + Program.main.AutoHost.config.HostingPort + ".txt"; ConfigMaker.Generate(path + configName, battle, talker.LoopbackPort, out players); talker.SetPlayers(players); process = new Process(); process.StartInfo.CreateNoWindow = true; process.StartInfo.Arguments += configName; process.StartInfo.WorkingDirectory = path; process.StartInfo.FileName = path + ExecutableName; process.StartInfo.UseShellExecute = false; process.Exited += new EventHandler(springProcess_Exited); process.Start(); process.ProcessorAffinity = (IntPtr)Program.main.config.SpringCoreAffinity; gameStarted = DateTime.Now; process.WaitForInputIdle(); if (IsRunning && SpringStarted != null) SpringStarted(this, EventArgs.Empty); System.Threading.Thread.Sleep(1000); ProcessPriority = Program.main.config.HostingProcessPriority; } }
/// <summary> /// Primary method - processes commands from server /// </summary> /// <param name="command">command name</param> /// <param name="args">command arguments</param> private void DispatchServerCommand(string command, string[] args) { Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; try { switch (command) { case "TASServer": // happens after connecting to server serverVersion = args[0]; int.TryParse(args[2], out serverUdpHolePunchingPort); isConnected = true; if (Connected != null) Connected(this, new TasEventArgs()); break; case "ACCEPTED": // Login accepted username = args[0]; isLoggedIn = true; if (LoginAccepted != null) LoginAccepted(this, new TasEventArgs()); break; case "DENIED": // login denied isLoggedIn = false; if (LoginDenied != null) LoginDenied(this, new TasEventArgs(Utils.Glue(args))); break; case "JOIN": // channel joined if (!joinedChannels.ContainsKey(args[0])) joinedChannels.Add(args[0], Channel.Create(args[0])); if (ChannelJoined != null) ChannelJoined(this, new TasEventArgs(args)); break; case "JOINFAILED": // channel join failed if (ChannelJoinFailed != null) ChannelJoinFailed(this, new TasEventArgs(Utils.Glue(args))); break; case "CHANNEL": // iterating channels { var c = new ExistingChannel(); c.name = args[0]; int.TryParse(args[1], out c.userCount); if (args.Length >= 3) c.topic = Utils.Glue(args, 2); existingChannels.Add(c.name, c); } break; case "ENDOFCHANNELS": // end of channel list iteration isChanScanning = false; if (ChannelListDone != null) ChannelListDone(this, new TasEventArgs()); break; case "ADDUSER": // new user joined ta server { var u = User.Create(args[0]); u.country = args[1]; int.TryParse(args[2], out u.cpu); //IPAddress.TryParse(args[3], out u.ip); existingUsers.Add(u.name, u); if (UserAdded != null) UserAdded(this, new TasEventArgs(args)); } break; case "REMOVEUSER": // user left ta server existingUsers.Remove(args[0]); if (UserRemoved != null) UserRemoved(this, new TasEventArgs(args)); break; case "MOTD": // server motd if (Said != null && args.Length > 0) Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Server, TasSayEventArgs.Places.Motd, "", "", Utils.Glue(args, 0), false)); break; case "SERVERMSG": // server message if (Said != null) Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Server, TasSayEventArgs.Places.Normal, "", "", Utils.Glue(args, 0), false)); break; case "SERVERMSGBOX": // server messagebox if (Said != null) Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Server, TasSayEventArgs.Places.MessageBox, "", "", Utils.Glue(args, 0), false)); break; case "CHANNELMESSAGE": // server broadcast to channel if (Said != null) Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Server, TasSayEventArgs.Places.Channel, args[0], "", Utils.Glue(args, 1), false)); break; case "SAID": // someone said something in channel if (Said != null) Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Player, TasSayEventArgs.Places.Channel, args[0], args[1], Utils.Glue(args, 2), false)); break; case "SAIDEX": // someone said something with emote in channel if (Said != null) Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Player, TasSayEventArgs.Places.Channel, args[0], args[1], Utils.Glue(args, 2), true)); break; case "SAYPRIVATE": // sent back from sever when user sends private message if (Said != null) Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Player, TasSayEventArgs.Places.Normal, args[0], username, Utils.Glue(args, 1), false)); // channel = char partner name break; case "SAIDPRIVATE": // someone said something to me if (Said != null) Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Player, TasSayEventArgs.Places.Normal, args[0], args[0], Utils.Glue(args, 1), false)); break; case "SAIDBATTLE": // someone said something in battle if (Said != null) Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Player, TasSayEventArgs.Places.Battle, "", args[0], Utils.Glue(args, 1), false)); break; case "SAIDBATTLEEX": // someone said in battle with emote if (Said != null) Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Player, TasSayEventArgs.Places.Battle, "", args[0], Utils.Glue(args, 1), true)); break; case "BROADCAST": // server sends urgent broadcast if (Said != null) Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Server, TasSayEventArgs.Places.Broadcast, "", "", Utils.Glue(args, 0), false)); break; case "REDIRECT": // server sends backup IP // removed due to bugs break; case "CLIENTSTATUS": // client's status changed { int status = 0; int.TryParse(args[1], out status); var u = existingUsers[args[0]]; u.FromInt(status); if (u.name == UserName && (u.isInGame && existingUsers[args[0]].isInGame == false)) { existingUsers[args[0]] = u; if (MyStatusChangedToInGame != null) MyStatusChangedToInGame(this, new TasEventArgs()); } existingUsers[args[0]] = u; if (UserStatusChanged != null) UserStatusChanged(this, new TasEventArgs(args)); } break; case "CLIENTS": // client list sent after channel join var usrs = Utils.Glue(args, 1).Split(' '); foreach (var s in usrs) joinedChannels[args[0]].channelUsers.Add(s); if (ChannelUserAdded != null) ChannelUserAdded(this, new TasEventArgs(args[0])); break; case "JOINED": // user joined one of my channels joinedChannels[args[0]].channelUsers.Add(args[1]); if (ChannelUserAdded != null) ChannelUserAdded(this, new TasEventArgs(args[0])); break; case "LEFT": // user left one of my channels joinedChannels[args[0]].channelUsers.Remove(args[1]); if (ChannelUserRemoved != null) ChannelUserRemoved(this, new TasEventArgs(args[0], args[1], Utils.Glue(args, 2))); break; case "CHANNELTOPIC": // channel topic update (after joining a channel) { var c = joinedChannels[args[0]]; c.topicSetBy = args[1]; c.topicSetDate = ConvertMilisecondTime(args[2]); c.topic = Utils.Glue(args, 3); if (ChannelTopicChanged != null) ChannelTopicChanged(this, new TasEventArgs(args[0])); } break; case "OPENBATTLEFAILED": // opening new battle has failed if (BattleOpenFailed != null) BattleOpenFailed(this, new TasEventArgs(Utils.Glue(args))); break; case "OPENBATTLE": // openbattle ok { battleID = int.Parse(args[0]); var self = new UserBattleStatus(username); self.IsSpectator = true; battle.Users.Add(self); // add self UpdateBattleDetails(battle.Details); if (BattleOpened != null) BattleOpened(this, new TasEventArgs(args[0])); } break; case "REQUESTBATTLESTATUS": // server asks us to update our status con.SendCommand(0, "MYBATTLESTATUS", 1 << 22, 0); // tell server that we are synchronized spectators break; case "JOINEDBATTLE": // user joined the battle if (battle != null && int.Parse(args[0]) == battleID) { battle.Users.Add(new UserBattleStatus(args[1])); if (BattleUserJoined != null) BattleUserJoined(this, new TasEventArgs(args[1])); } break; case "ADDBOT": // bot added to battle if (battle != null && int.Parse(args[0]) == battleID) { var bs = new BotBattleStatus(args[1], args[2], Utils.Glue(args, 5)); bs.SetFrom(int.Parse(args[3]), int.Parse(args[4])); battle.Bots.Add(bs); } break; case "REMOVEBOT": // bot removed from battle if (battle != null && int.Parse(args[0]) == battleID) battle.Bots.RemoveAll(delegate(BotBattleStatus bot) { return bot.name == args[1]; }); break; case "UPDATEBOT": // bot data changed if (battle != null && int.Parse(args[0]) == battleID) { var st = battle.Bots.Find(delegate(BotBattleStatus bot) { return bot.name == args[1]; }); if (st != null) st.SetFrom(int.Parse(args[2]), int.Parse(args[3])); } break; case "LEFTBATTLE": // user left the battle if (battle != null && int.Parse(args[0]) == battleID) { battle.RemoveUser(args[1]); UpdateSpectators(); if (BattleUserLeft != null) BattleUserLeft(this, new TasEventArgs(args[1])); if (args[1] == username) { battle = null; battleID = 0; if (BattleClosed != null) BattleClosed(this, new TasEventArgs()); } } break; case "CLIENTBATTLESTATUS": // player battle status has changed if (battle != null) { int uindex = battle.GetUserIndex(args[0]); if (uindex != -1) { var bs = battle.Users[uindex]; bs.SetFrom(int.Parse(args[1]), int.Parse(args[2])); battle.Users[uindex] = bs; UpdateSpectators(); if (BattleUserStatusChanged != null) BattleUserStatusChanged(this, new TasEventArgs(args[0])); } } break; case "UPDATEBATTLEINFO": // update external battle info (lock and map) if (battle != null && int.Parse(args[0]) == battleID) { string mapname = Utils.Glue(args, 4); if (battle.Map.Name != mapname) { if (mapToChangeTo != null && mapToChangeTo.Name == mapname) { // if we changed to known requested map, use it battle.Map = mapToChangeTo; } else battle.Map = Program.main.Spring.UnitSync.MapList[mapname]; //otherwise find this map using unitsync if (BattleMapChanged != null) BattleMapChanged(this, new TasEventArgs(mapname)); } if (battle.IsLocked != int.Parse(args[2]) > 0) { battle.IsLocked = int.Parse(args[2]) > 0; if (BattleLockChanged != null) BattleLockChanged(this, new TasEventArgs(args[2])); } } break; case "BATTLEOPENED": { if (BattleFound != null) BattleFound(this, new TasEventArgs(args)); break; } case "CLIENTIPPORT": if (battle != null) { int idx = battle.GetUserIndex(args[0]); if (idx != -1) { var bs = battle.Users[idx]; bs.ip = IPAddress.Parse(args[1]); bs.port = int.Parse(args[2]); battle.Users[idx] = bs; if (BattleUserIpRecieved != null) BattleUserIpRecieved(this, new TasEventArgs(args)); } } break; case "SETSCRIPTTAGS": // updates internal battle details if (battle != null) { var bd = new BattleDetails(); bd.Parse(Utils.Glue(args), battle.ModOptions); battle.Details = bd; if (BattleDetailsChanged != null) BattleDetailsChanged(this, new TasEventArgs(args)); } break; case "UDPSOURCEPORT": udpPunchingTimer.Stop(); if (startingAfterUdpPunch) { startingAfterUdpPunch = false; if (battle != null) { // send UDP packets to client (2x to be sure) foreach (var ubs in battle.Users) if (ubs.ip != IPAddress.None && ubs.port != 0) SendUdpPacket(lastUdpSourcePort, ubs.ip, ubs.port); foreach (var ubs in battle.Users) if (ubs.ip != IPAddress.None && ubs.port != 0) SendUdpPacket(lastUdpSourcePort, ubs.ip, ubs.port); battle.HostPort = lastUdpSourcePort; // update source port for hosting and start it ChangeMyStatus(false, true); } } break; } } catch (Exception e) { if (!ErrorHandling.HandleException(e, "Exception while dispatching " + command + " " + Utils.Glue(args))) throw e; } ; }
/// <summary> /// Primary method - processes commands from server /// </summary> /// <param name="command">command name</param> /// <param name="args">command arguments</param> private void DispatchServerCommand(string command, string[] args) { Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; try { switch (command) { case "TASServer": // happens after connecting to server serverVersion = args[0]; int.TryParse(args[2], out serverUdpHolePunchingPort); isConnected = true; if (Connected != null) { Connected(this, new TasEventArgs()); } break; case "ACCEPTED": // Login accepted username = args[0]; isLoggedIn = true; if (LoginAccepted != null) { LoginAccepted(this, new TasEventArgs()); } break; case "DENIED": // login denied isLoggedIn = false; if (LoginDenied != null) { LoginDenied(this, new TasEventArgs(Utils.Glue(args))); } break; case "JOIN": // channel joined if (!joinedChannels.ContainsKey(args[0])) { joinedChannels.Add(args[0], Channel.Create(args[0])); } if (ChannelJoined != null) { ChannelJoined(this, new TasEventArgs(args)); } break; case "JOINFAILED": // channel join failed if (ChannelJoinFailed != null) { ChannelJoinFailed(this, new TasEventArgs(Utils.Glue(args))); } break; case "CHANNEL": // iterating channels { var c = new ExistingChannel(); c.name = args[0]; int.TryParse(args[1], out c.userCount); if (args.Length >= 3) { c.topic = Utils.Glue(args, 2); } existingChannels.Add(c.name, c); } break; case "ENDOFCHANNELS": // end of channel list iteration isChanScanning = false; if (ChannelListDone != null) { ChannelListDone(this, new TasEventArgs()); } break; case "ADDUSER": // new user joined ta server { var u = User.Create(args[0]); u.country = args[1]; int.TryParse(args[2], out u.cpu); //IPAddress.TryParse(args[3], out u.ip); existingUsers.Add(u.name, u); if (UserAdded != null) { UserAdded(this, new TasEventArgs(args)); } } break; case "REMOVEUSER": // user left ta server existingUsers.Remove(args[0]); if (UserRemoved != null) { UserRemoved(this, new TasEventArgs(args)); } break; case "MOTD": // server motd if (Said != null && args.Length > 0) { Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Server, TasSayEventArgs.Places.Motd, "", "", Utils.Glue(args, 0), false)); } break; case "SERVERMSG": // server message if (Said != null) { Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Server, TasSayEventArgs.Places.Normal, "", "", Utils.Glue(args, 0), false)); } break; case "SERVERMSGBOX": // server messagebox if (Said != null) { Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Server, TasSayEventArgs.Places.MessageBox, "", "", Utils.Glue(args, 0), false)); } break; case "CHANNELMESSAGE": // server broadcast to channel if (Said != null) { Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Server, TasSayEventArgs.Places.Channel, args[0], "", Utils.Glue(args, 1), false)); } break; case "SAID": // someone said something in channel if (Said != null) { Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Player, TasSayEventArgs.Places.Channel, args[0], args[1], Utils.Glue(args, 2), false)); } break; case "SAIDEX": // someone said something with emote in channel if (Said != null) { Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Player, TasSayEventArgs.Places.Channel, args[0], args[1], Utils.Glue(args, 2), true)); } break; case "SAYPRIVATE": // sent back from sever when user sends private message if (Said != null) { Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Player, TasSayEventArgs.Places.Normal, args[0], username, Utils.Glue(args, 1), false)); // channel = char partner name } break; case "SAIDPRIVATE": // someone said something to me if (Said != null) { Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Player, TasSayEventArgs.Places.Normal, args[0], args[0], Utils.Glue(args, 1), false)); } break; case "SAIDBATTLE": // someone said something in battle if (Said != null) { Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Player, TasSayEventArgs.Places.Battle, "", args[0], Utils.Glue(args, 1), false)); } break; case "SAIDBATTLEEX": // someone said in battle with emote if (Said != null) { Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Player, TasSayEventArgs.Places.Battle, "", args[0], Utils.Glue(args, 1), true)); } break; case "BROADCAST": // server sends urgent broadcast if (Said != null) { Said(this, new TasSayEventArgs(TasSayEventArgs.Origins.Server, TasSayEventArgs.Places.Broadcast, "", "", Utils.Glue(args, 0), false)); } break; case "REDIRECT": // server sends backup IP // removed due to bugs break; case "CLIENTSTATUS": // client's status changed { var status = 0; int.TryParse(args[1], out status); var u = existingUsers[args[0]]; u.FromInt(status); if (u.name == UserName && (u.isInGame && existingUsers[args[0]].isInGame == false)) { existingUsers[args[0]] = u; if (MyStatusChangedToInGame != null) { MyStatusChangedToInGame(this, new TasEventArgs()); } } existingUsers[args[0]] = u; if (UserStatusChanged != null) { UserStatusChanged(this, new TasEventArgs(args)); } } break; case "CLIENTS": // client list sent after channel join var usrs = Utils.Glue(args, 1).Split(' '); foreach (var s in usrs) { joinedChannels[args[0]].channelUsers.Add(s); if (ChannelUserAdded != null) { ChannelUserAdded(this, new TasEventArgs(args[0], s)); } } break; case "JOINED": // user joined one of my channels joinedChannels[args[0]].channelUsers.Add(args[1]); if (ChannelUserAdded != null) { ChannelUserAdded(this, new TasEventArgs(args[0], args[1])); } break; case "LEFT": // user left one of my channels joinedChannels[args[0]].channelUsers.Remove(args[1]); if (ChannelUserRemoved != null) { ChannelUserRemoved(this, new TasEventArgs(args[0], args[1], Utils.Glue(args, 2))); } break; case "CHANNELTOPIC": // channel topic update (after joining a channel) { var c = joinedChannels[args[0]]; c.topicSetBy = args[1]; c.topicSetDate = ConvertMilisecondTime(args[2]); c.topic = Utils.Glue(args, 3); if (ChannelTopicChanged != null) { ChannelTopicChanged(this, new TasEventArgs(args[0])); } } break; case "OPENBATTLEFAILED": // opening new battle has failed if (BattleOpenFailed != null) { BattleOpenFailed(this, new TasEventArgs(Utils.Glue(args))); } break; case "OPENBATTLE": // openbattle ok { battleID = int.Parse(args[0]); var self = new UserBattleStatus(username); self.IsSpectator = true; battle.Users.Add(self); // add self UpdateBattleDetails(battle.Details); SetScriptTag(battle.Mod.GetDefaultModOptionsTags()); // sends default mod options todo remove when tasclient fixes if (BattleOpened != null) { BattleOpened(this, new TasEventArgs(args[0])); } } break; case "REQUESTBATTLESTATUS": // server asks us to update our status con.SendCommand(0, "MYBATTLESTATUS", 1 << 22, 0); // tell server that we are synchronized spectators break; case "JOINEDBATTLE": // user joined the battle if (battle != null && int.Parse(args[0]) == battleID) { battle.Users.Add(new UserBattleStatus(args[1])); if (BattleUserJoined != null) { BattleUserJoined(this, new TasEventArgs(args[1])); } } break; case "ADDBOT": // bot added to battle if (battle != null && int.Parse(args[0]) == battleID) { var bs = new BotBattleStatus(args[1], args[2], Utils.Glue(args, 5)); bs.SetFrom(int.Parse(args[3]), int.Parse(args[4])); battle.Bots.Add(bs); } break; case "REMOVEBOT": // bot removed from battle if (battle != null && int.Parse(args[0]) == battleID) { battle.Bots.RemoveAll(delegate(BotBattleStatus bot) { return(bot.name == args[1]); }); } break; case "UPDATEBOT": // bot data changed if (battle != null && int.Parse(args[0]) == battleID) { var st = battle.Bots.Find(delegate(BotBattleStatus bot) { return(bot.name == args[1]); }); if (st != null) { st.SetFrom(int.Parse(args[2]), int.Parse(args[3])); } } break; case "LEFTBATTLE": // user left the battle if (battle != null && int.Parse(args[0]) == battleID) { battle.RemoveUser(args[1]); UpdateSpectators(); if (BattleUserLeft != null) { BattleUserLeft(this, new TasEventArgs(args[1])); } if (args[1] == username) { battle = null; battleID = 0; if (BattleClosed != null) { BattleClosed(this, new TasEventArgs()); } } } break; case "CLIENTBATTLESTATUS": // player battle status has changed if (battle != null) { var uindex = battle.GetUserIndex(args[0]); if (uindex != -1) { var bs = battle.Users[uindex]; bs.SetFrom(int.Parse(args[1]), int.Parse(args[2])); battle.Users[uindex] = bs; UpdateSpectators(); if (BattleUserStatusChanged != null) { BattleUserStatusChanged(this, new TasEventArgs(args[0])); } } } break; case "UPDATEBATTLEINFO": // update external battle info (lock and map) if (battle != null && int.Parse(args[0]) == battleID) { var mapname = Utils.Glue(args, 4); if (battle.Map.Name != mapname) { if (mapToChangeTo != null && mapToChangeTo.Name == mapname) { // if we changed to known requested map, use it battle.Map = mapToChangeTo; } else { battle.Map = Program.main.Spring.UnitSyncWrapper.MapList[mapname]; //otherwise find this map using unitsync } if (BattleMapChanged != null) { BattleMapChanged(this, new TasEventArgs(mapname)); } } if (battle.IsLocked != int.Parse(args[2]) > 0) { battle.IsLocked = int.Parse(args[2]) > 0; if (BattleLockChanged != null) { BattleLockChanged(this, new TasEventArgs(args[2])); } } } break; case "BATTLEOPENED": { if (BattleFound != null) { BattleFound(this, new TasEventArgs(args)); } break; } case "CLIENTIPPORT": if (battle != null) { var idx = battle.GetUserIndex(args[0]); if (idx != -1) { var bs = battle.Users[idx]; bs.ip = IPAddress.Parse(args[1]); bs.port = int.Parse(args[2]); battle.Users[idx] = bs; if (BattleUserIpRecieved != null) { BattleUserIpRecieved(this, new TasEventArgs(args)); } } } break; case "SETSCRIPTTAGS": // updates internal battle details if (battle != null) { var bd = new BattleDetails(); bd.Parse(Utils.Glue(args), battle.ModOptions); battle.Details = bd; if (BattleDetailsChanged != null) { BattleDetailsChanged(this, new TasEventArgs(args)); } } break; case "UDPSOURCEPORT": udpPunchingTimer.Stop(); if (startingAfterUdpPunch) { startingAfterUdpPunch = false; if (battle != null) { // send UDP packets to client (2x to be sure) foreach (var ubs in battle.Users) { if (ubs.ip != IPAddress.None && ubs.port != 0) { SendUdpPacket(lastUdpSourcePort, ubs.ip, ubs.port); } } foreach (var ubs in battle.Users) { if (ubs.ip != IPAddress.None && ubs.port != 0) { SendUdpPacket(lastUdpSourcePort, ubs.ip, ubs.port); } } battle.HostPort = lastUdpSourcePort; // update source port for hosting and start it ChangeMyStatus(false, true); } } break; } } catch (Exception e) { if (!ErrorHandling.HandleException(e, "Exception while dispatching " + command + " " + Utils.Glue(args))) { throw e; } } ; }