Esempio n. 1
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);

                    if (u.name == UserName && (u.isInGame == true && 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
                    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]);
                            bs.port           = int.Parse(args[2]);
                            battle.Users[idx] = bs;
                            if (BattleUserIpRecieved != null)
                            {
                                BattleUserIpRecieved(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 (UserBattleStatus ubs in battle.Users)
                            {
                                if (ubs.ip != IPAddress.None && ubs.port != 0)
                                {
                                    SendUdpPacket(lastUdpSourcePort, ubs.ip, ubs.port);
                                }
                            }
                            foreach (UserBattleStatus 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;
                }
            };
        }
Esempio n. 2
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;
			}
			;
		}
Esempio n. 3
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;
      };
    }