// Catch new room comer, containing watcher and reconnector public ushort CatchNewRoomComer() { if (listener == null) { return 0; } Socket socket; try { socket = listener.AcceptSocket(); } catch (SocketException) { return 0; } NetworkStream ns = new NetworkStream(socket); string data = Base.VW.WHelper.ReadByteLine(ns); if (data == null) { return 0; } else if (data.StartsWith("C2QI,")) // Watcher case { string[] blocks = data.Split(','); ushort ut = ushort.Parse(blocks[1]); if (ut == 0) ut = watchCount++; string uname = blocks[2]; while (netchers.ContainsKey(ut)) ++ut; Netcher nc = new Netcher(uname, ut) { Tunnel = socket }; netchers.Add(ut, nc); Base.VW.WHelper.SentByteLine(ns, "C2QJ," + ut); Base.VW.WHelper.SentByteLine(ns, "C2SA,0"); return ut; } else if (data.StartsWith("C4CR,")) // Reconnect case { // C4CR,u,i,A,cd string[] blocks = data.Split(','); ushort newUt = ushort.Parse(blocks[1]); ushort oldUt = ushort.Parse(blocks[2]); string uname = blocks[3]; string roomPwd = blocks[4]; ushort gameUt = neayers.Values.First(p => p.AUid == oldUt).Uid; Neayer ny = new Neayer(uname, 0) // set avatar = 0, not care { AUid = newUt, Uid = gameUt, HopeTeam = 0, Tunnel = socket, Alive = false }; neayers[ny.Uid] = ny; StartListenTask(() => KeepOnListenRecv(ny)); Base.VW.WHelper.SentByteLine(ns, "C4CS," + ny.Uid); ny.Alive = true; WakeTunnelInWaiting(ny.AUid, ny.Uid); return ny.Uid; } else { Base.VW.WHelper.SentByteLine(ns, "C2CN,0"); return 0; } }
// n1 is a temporary version of neayers (uid not rearranged), netchers is usable private void ConnectDo(Socket socket, List<ushort> valids, IDictionary<ushort, Neayer> n1) { NetworkStream ns = new NetworkStream(socket); string data = Base.VW.WHelper.ReadByteLine(ns); //string addr = (socket.RemoteEndPoint as IPEndPoint).Address.ToString(); if (data == null) { return; } else if (data.StartsWith("C2CO,")) { string[] blocks = data.Split(','); ushort ut = ushort.Parse(blocks[1]); string uname = blocks[2]; ushort uava = ushort.Parse(blocks[3]); int uHope = int.Parse(blocks[4]); //if (uHope == Base.Rules.RuleCode.HOPE_AKA) // uHope = 1; //else if (uHope == Base.Rules.RuleCode.HOPE_AO) // uHope = 2; //else if (uHope == Base.Rules.RuleCode.HOPE_IP) //{ // if (addrDict.ContainsKey(addr)) // uHope = addrDict[addr]; // else // addrDict.Add(addr, uHope = addrRank++); //} //else // uHope = 0; if (n1 == null) Base.VW.WHelper.SentByteLine(ns, "C2CN,0"); if (valids != null) { if (valids.Contains(ut) && GetAliveNeayersCount() < playerCapacity) { Neayer ny = new Neayer(uname, uava) { Uid = ut, // actual Uid isn't set yet AUid = ut, HopeTeam = uHope, Tunnel = socket }; n1.Add(ut, ny); vi.Cout(0, "[{0}]{1} joined.", ny.AUid, uname); Base.VW.WHelper.SentByteLine(ns, "C2CN," + ny.AUid); } else Base.VW.WHelper.SentByteLine(ns, "C2CN,0"); } else // In Direct mode, exit isn't allowed, AUid isn't useful. { ushort allocUid = (ushort)(curCount++); Neayer ny = new Neayer(uname, uava) { Uid = allocUid, AUid = allocUid, HopeTeam = uHope, Tunnel = socket }; string c2rm = ""; string c2nw = "C2NW," + ny.Uid + "," + ny.Name + "," + ny.Avatar; foreach (Neayer nyr in n1.Values) { c2rm += "," + nyr.Uid + "," + nyr.Name + "," + nyr.Avatar; Base.VW.WHelper.SentByteLine(new NetworkStream(nyr.Tunnel), c2nw); } n1.Add(ny.Uid, ny); vi.Cout(0, "[{0}]{1} joined.", ny.Uid, uname); Base.VW.WHelper.SentByteLine(ns, "C2CN," + ny.Uid); if (c2rm.Length > 0) Base.VW.WHelper.SentByteLine(ns, "C2RM" + c2rm); } } else if (data.StartsWith("C2QI,")) { string[] blocks = data.Split(','); ushort ut = (valids != null) ? ushort.Parse(blocks[1]) : watchCount++; string uname = blocks[2]; while (netchers.ContainsKey(ut)) ++ut; Netcher nc = new Netcher(uname, ut) { Tunnel = socket }; netchers.Add(ut, nc); Base.VW.WHelper.SentByteLine(ns, "C2QJ," + ut); } }
private void StartRoom(string[] args) { VI = new VW.Djvi(6, Log); string netMode = GetValue(args, 1, "联机模式(SF:单机/NT:联网)").Trim().ToUpper(); if (netMode != "SF") netMode = "NT"; string sel = GetValue(args, 2, "选人模式(31:三选一/RM:随机/" + "BP:禁选/RD:轮选/ZY:昭鹰/CP:协同/SS:北软/CJ:召唤/TC:明暗)").Trim().ToUpper(); int selCode = RuleCode.CastMode(sel); int levelCode = RuleCode.LEVEL_ALL; string[] trainer = null; if (netMode == "SF") { //IsGameCompete = false; VW.Djwi djwi = new VW.Djwi(playerCapacity, this.Log); WI = djwi; Board.Garden = new Dictionary<ushort, Player>(); List<VW.Neayer> neayers = new List<VW.Neayer>(); string[] xingsen = new string[] { "撞仙", "笑犬", "翼君", "失影", "厌凉", "彰危" }; while (neayers.Count < playerCapacity) { string py = xingsen[neayers.Count]; ushort pv = (ushort)(neayers.Count * neayers.Count); VW.Neayer neayer = new VW.Neayer(py, pv); neayers.Add(neayer); } VI.Init(); // setup finish, re-newed player's uid List<int> uidList = new List<int>(Enumerable.Range(1, playerCapacity)); uidList.Shuffle(); for (ushort i = 0; i < neayers.Count; ++i) { Player player = new Player(neayers[i].Name, neayers[i].Avatar, (ushort)uidList[i]) { Team = (uidList[i] % 2 == 1) ? 1 : 2, IsAlive = true }; Board.Garden.Add(player.Uid, player); } Log.Start(); IDictionary<ushort, PSD.ClientZero.XIClient> xiclients = new Dictionary<ushort, PSD.ClientZero.XIClient>(); foreach (Player player in Board.Garden.Values) { XIClient xc = new XIClient(player.Uid, djwi, VI); xiclients.Add(player.Uid, xc); xc.RunAsync(); } Thread.Sleep(100); WI.BCast("H0SD," + string.Join(",", Board.Garden.Values.Select( p => p.Uid + "," + p.AUid + "," + p.Name))); foreach (Player player in Board.Garden.Values) VI.Cout(0, "player " + player.Uid + "# belongs to Team " + player.Team + "."); isFinished = false; levelCode = RuleCode.LEVEL_ALL; //trainer = new string[] { "HL003", "HL011", "HL012" }; } else if (netMode == "NT") { string teamModeStr = GetValue(args, 3, "请选择是否支持选队(YJ:选队/NJ:不允许选队)"); bool teamMode = (teamModeStr == "YJ") ? true : false; string level = GetValue(args, 4, "房间等级,(1:新手场/2:标准场/3:高手场/4:至尊场/5:界限突破场,后附+为特训"); bool isTrain = level.Contains("+"); trainer = isTrain ? Base.Utils.Algo.Substring(level, level.IndexOf('+') + 1, -1).Split(',') : null; if (isTrain) level = level.Substring(0, level.IndexOf('+')); if (!int.TryParse(level, out levelCode) || levelCode < 0 || levelCode > RuleCode.LEVEL_IPV) levelCode = RuleCode.LEVEL_RCM; else if (levelCode == 0) levelCode = RuleCode.DEF_CODE; else levelCode = (levelCode << 1) | (isTrain ? RuleCode.LEVEL_TRAIN_MASK : 0); //string gameModeStr = GetValue(args, 5, "请选择游戏模式(JY:休闲模式/CT:竞技模式)"); //IsGameCompete = (gameModeStr == "CT") ? true : false; // true -> CT string portStr = GetValue(args, 5, "请输入房间编号(0为默认值)"); int port; if (!int.TryParse(portStr, out port)) port = 0; port += Base.NetworkCode.DIR_PORT; if (port >= 65535 || port < 1024) port = Base.NetworkCode.DIR_PORT; IPAddress[] ipHost = Dns.GetHostAddresses(Dns.GetHostName()); if (ipHost.Length > 0) { Console.WriteLine("本机IP合法地址为:"); foreach (IPAddress ip in ipHost) { string ipt = ip.ToString(); if (ipt.StartsWith("10.") || ipt.StartsWith("127.0.") || ipt.StartsWith("192.168.")) Console.WriteLine(" [内网地址]" + ipt); else Console.WriteLine(" " + ipt); } } else Console.WriteLine("本机目前网卡异常,仅支持本地模式。"); VW.Aywi aywi = new VW.Aywi(port, 6, Log, HandleYMessage); WI = aywi; VI.Cout(0, "Wait for others players joining"); VI.Init(); Log.Start(); aywi.TcpListenerStart(); Board.Garden = aywi.Connect(VI, teamMode, null); int count = Board.Garden.Count; while (count > 0) { Base.VW.Msgs msg = WI.RecvInfRecv(); if (msg.Msg.StartsWith("C2ST,")) --count; } isFinished = false; WI.BCast("H0SD," + string.Join(",", Board.Garden.Values.Select( p => p.Uid + "," + p.AUid + "," + p.Name))); } Board.RoundIN = "H0PR"; if (WI is VW.Aywi) HoldRoomTunnel(); VI.SetInGame(true); if (selCode == RuleCode.MODE_00) levelCode = 0; SelectHero(selCode, levelCode, trainer); Run(levelCode, selCode == Base.Rules.RuleCode.MODE_00); }