예제 #1
0
        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 {}
            }
        }
예제 #2
0
		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"));
			}
		}
예제 #3
0
    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);
    }
예제 #4
0
		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();
		}
예제 #5
0
    // 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;
      }
    }
예제 #6
0
 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);
            }
        }
예제 #8
0
		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);
		}
예제 #9
0
    /// <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;
      };
    }
예제 #10
0
    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);
    }
예제 #11
0
    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);
      }

    }
예제 #12
0
    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);
    }
예제 #13
0
        /// <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;
                }
            };
        }
예제 #14
0
		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;
		}
예제 #15
0
        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);
            }
        }
예제 #16
0
		public void LeaveBattle()
		{
			if (battle != null) {
				con.SendCommand(0, "LEAVEBATTLE");
				battle = null;
				battleID = 0;
				if (BattleClosed != null) BattleClosed(this, new TasEventArgs());
			}
		}
예제 #17
0
    // 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;
      }
    }
예제 #18
0
		/// <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;
			}
			;
		}
예제 #19
0
        /// <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;
                }
            }
            ;
        }