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;
                }
            };
        }