public void Online(SocketAsyncEventArgs args, PlayerEnter enter, long roomId) { var piir = GetPlayerInRoom(enter.TokenId); if (piir == null) { // 如果房间里实际没有这个玩家(的存盘), 则表明这是一个新用户, 要从表格中读取初始数据 piir = new PlayerInfoInRoom(); var csv = CsvDataManager.Instance.GetTable("battle_init"); int wood = csv.GetValueInt(1, "PlayerInit_Wood"); int food = csv.GetValueInt(1, "PlayerInit_Food"); int iron = csv.GetValueInt(1, "PlayerInit_Iron"); int actionPointMax = csv.GetValueInt(1, "MaxActionPoint"); piir.AddWood(wood); piir.AddFood(food); piir.AddIron(iron); piir.SetActionPointMax(actionPointMax); piir.AddActionPoint(actionPointMax); piir.TimeSinceLastSave = DateTime.Now.ToFileTime(); piir.TimeSinceLastRestoreActionPoint = 0; PlayersInRoom[enter.TokenId] = piir; } // 把本玩家记录到Room的Redis里, 便于以后查找, 这里保存的就是房间内所有的玩家的id AddPlayerIdToRedis(piir); // 玩家上线 piir.Online(args, enter, roomId); // 玩家进入以后,根据该玩家[离开游戏]的时间,到[现在]的时间差(秒),计算出应该恢复多少的行动点数, 一次性恢复之 piir.RestoreActionPointAfterLoading(); // 这段逻辑很重要: 这是要把所有房间内的玩家的代理权限交给第一个进入房间的玩家, 以后, 如果这些玩家也上线了, 则把代理权交还给真正的玩家 // 这是因为, 服务器并没有对这些玩家的逻辑进行AI处理, 而是由客户端自己来控制自己的. // 未来, 如果服务器要把AI代理权限收回来,这些地方都要做修改. if (piir.AiRights == 0 || piir.AiRights != piir.Enter.TokenId) { // 我之前曾经被别人代理过, 把代理权收回来 var piirAi = GetPlayerInRoom(piir.AiRights); if (piirAi != null && piirAi.IsOnline) { piir.AiRights = piir.Enter.TokenId; ChangeAiRightsReply output = new ChangeAiRightsReply() { RoomId = piirAi.RoomId, OwnerId = piirAi.Enter.TokenId, AiPlayerId = piir.Enter.TokenId, AiAccount = piir.Enter.Account, ControlByMe = false, Ret = true, }; ServerRoomManager.Instance.SendMsg(piirAi.Args, ROOM_REPLY.ChangeAiRightsReply, output.ToByteArray()); ServerRoomManager.Instance.Log($"RoomLogic Online OK - AI Rights of {piir.Enter.TokenId} is no longer controlled by {piir.Enter.Account}"); } else { ServerRoomManager.Instance.Log($"RoomLogic Online Error - When trying to handle the AI controlled rights, the original player is offline! {piir.Enter.Account} - {piir.Enter.Account}"); } } // 遍历所有玩家, 把所有: AI没有被代理, 且不在线的玩家, 权限都给它. 这种情况仅发生在第一个进入的玩家 foreach (var keyValue in PlayersInRoom) { var piirAi = keyValue.Value; if (piirAi.AiRights == 0) { // 我自己不需要发送此消息, 我自己的AiRights此时肯定不是0了 piirAi.AiRights = piir.Enter.TokenId; ChangeAiRightsReply output = new ChangeAiRightsReply() { RoomId = piir.RoomId, OwnerId = piir.Enter.TokenId, AiPlayerId = piirAi.Enter.TokenId, AiAccount = piirAi.Enter.Account, ControlByMe = true, Ret = true, }; ServerRoomManager.Instance.SendMsg(piir.Args, ROOM_REPLY.ChangeAiRightsReply, output.ToByteArray()); ServerRoomManager.Instance.Log($"RoomLogic Online OK - AI Rights of {piirAi.Enter.Account} belongs to {piir.Enter.Account} now!"); } } _curPlayerCount = PlayersInRoom.Count; ServerRoomManager.Instance.Log($"RoomLogic Online OK - Player entered the battlefield! Player:{piir.Enter.Account}"); // 玩家进入战场 }
private void OnHarvestStop(SocketAsyncEventArgs args, byte[] bytes) { HarvestStop input = HarvestStop.Parser.ParseFrom(bytes); if (input.RoomId != RoomId) { return; // 不是自己房间的消息,略过 } if (input.CellIndex == 0) { Debug.LogError("RoomLogic OnHarvestStop Error - Actor position is lost!"); } // 修改地图上的资源数据 var hr = ResManager.GetRes(input.CellIndex); if (hr == null) { hr = new ResInfo(); ResManager.AddRes(input.CellIndex, hr); } hr.SetAmount((ResInfo.RESOURCE_TYPE)input.ResType, input.ResRemain); // 修改玩家身上的资源数据 PlayerInfoInRoom piir = GetPlayerInRoom(input.OwnerId); if (piir == null) { ServerRoomManager.Instance.Log($"RoomLogic OnHarvestStop Error - player not found in server! Id:{input.OwnerId}"); return; } switch ((ResInfo.RESOURCE_TYPE)input.ResType) { case ResInfo.RESOURCE_TYPE.WOOD: piir.AddWood(input.ResHarvest); break; case ResInfo.RESOURCE_TYPE.FOOD: piir.AddFood(input.ResHarvest); break; case ResInfo.RESOURCE_TYPE.IRON: piir.AddIron(input.ResHarvest); break; } HarvestStopReply output = new HarvestStopReply() { RoomId = input.RoomId, OwnerId = input.OwnerId, ActorId = input.ActorId, CellIndex = input.CellIndex, ResType = input.ResType, ResRemain = input.ResRemain, ResHarvest = input.ResHarvest, Ret = true, }; BroadcastMsg(ROOM_REPLY.HarvestStopReply, output.ToByteArray()); // 发送给客户端刷新玩家身上的资源数量 UpdateResReply output2 = new UpdateResReply() { RoomId = input.RoomId, OwnerId = input.OwnerId, Ret = true, Wood = piir.Wood, Food = piir.Food, Iron = piir.Iron, }; ServerRoomManager.Instance.SendMsg(args, ROOM_REPLY.UpdateResReply, output2.ToByteArray()); }