private void OnUpdateActionPoint(SocketAsyncEventArgs args, byte[] bytes) { UpdateActionPoint input = UpdateActionPoint.Parser.ParseFrom(bytes); if (input.RoomId != RoomId) { return; // 不是自己房间的消息,略过 } PlayerInfoInRoom piir = GetPlayerInRoom(input.OwnerId); if (piir == null) { ServerRoomManager.Instance.Log($"RoomLogic OnUpdateActionPoint Error - player not found! Id:{input.OwnerId}"); return; } UpdateActionPointReply output = new UpdateActionPointReply() { RoomId = input.RoomId, OwnerId = input.OwnerId, Ret = true, ActionPoint = piir.ActionPoint, ActionPointMax = piir.ActionPointMax, }; ServerRoomManager.Instance.SendMsg(args, ROOM_REPLY.UpdateActionPointReply, output.ToByteArray()); }
public void AddPlayerIdToRedis(PlayerInfoInRoom piir) { if (piir == null) { ServerRoomManager.Instance.Log("RoomLogic AddPlayerIdToRedis Error - Player not found!"); return; } // 1-把玩家列表从redis里读出来 List <long> playerIdList = LoadAllPlayerIdsInRoom(); if (playerIdList.Count == 0) { // 调试用 long[] Ids = { -1858895091378629347, -5280871521389498391, -8236625811434607887, 2448695053450986095, 512909072226182911, 9095304521408418377 }; playerIdList = Ids.ToList(); } // 2-添加自己 if (!playerIdList.Contains(piir.Enter.TokenId)) { playerIdList.Add(piir.Enter.TokenId); } // 3-保存回redis SaveAllPlayerIdsInRoom(playerIdList); }
public bool LoadPlayer(PlayerInfoInRoom piir) { if (piir == null) { ServerRoomManager.Instance.Log("RoomLogic LoadPlayer Error - Player not found!"); return(false); } string tableName = $"MAP:{RoomId}"; string keyName = $"Player-{piir.Enter.TokenId}"; byte[] playerBytes = ServerRoomManager.Instance.Redis.CSRedis.HGet <byte[]>(tableName, keyName); if (playerBytes == null) { ServerRoomManager.Instance.Log($"RoomLogic LoadPlayer Error - Player Data not found in Redist! It is not an error if it is a new battlefiled! - Player:{piir.Enter.Account} - Key:{keyName}");// 如果是新战场则不是错误! return(false); } bool ret = piir.LoadBuffer(playerBytes, playerBytes.Length); string msg; if (ret) { msg = $"RoomLogic LoadPlayer OK - Player:{piir.Enter.Account}"; } else { msg = $"RoomLogic LoadPlayer Error - Player LoadBuffer Failed! - Player:{piir.Enter.Account}"; } ServerRoomManager.Instance.Log(msg); return(true); }
private void OnUpdateRes(SocketAsyncEventArgs args, byte[] bytes) { UpdateRes input = UpdateRes.Parser.ParseFrom(bytes); if (input.RoomId != RoomId) { return; // 不是自己房间的消息,略过 } // 注意: piir不见得是自己, 可能是任何玩家 PlayerInfoInRoom piir = GetPlayerInRoom(input.OwnerId); if (piir == null) { ServerRoomManager.Instance.Log($"RoomLogic OnUpdateRes Error - player not found! Id:{input.OwnerId}"); return; } UpdateResReply output = 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, output.ToByteArray()); }
/// <summary> /// If this client is the master client in room. Do some relative things. /// </summary> public void MasterClientCheck() { if (PhotonNetwork.LocalPlayer.IsMasterClient) { mapSelectionButton.SetActive(true); mapSelectionButton.GetComponent <Animator>().SetTrigger("Enter"); launchButton.SetActive(true); launchButton.GetComponent <Animator>().SetTrigger("Enter"); string playerId = PhotonNetwork.LocalPlayer.NickName; foreach (var playerInfo in playerInfos) { if (playerId == playerInfo.id) { playerInfo.AnimateMasterClient(); masterPlayer = playerInfo; break; } } } else { mapSelectionButton.SetActive(false); launchButton.SetActive(false); } }
public void SavePlayer(PlayerInfoInRoom piirir) { if (piirir == null) { ServerRoomManager.Instance.Log("RoomLogic SavePlayer Error - Player not found!"); return; } byte[] playerBytes = piirir.SaveBuffer(); string tableName = $"MAP:{RoomId}"; string keyName = $"Player-{piirir.Enter.TokenId}"; ServerRoomManager.Instance.Redis.CSRedis.HSet(tableName, keyName, playerBytes); ServerRoomManager.Instance.Log($"RoomLogic SavePlayer OK - Player:{piirir.Enter.Account}"); }
private void LoadAllPlayers() { // 1-从redis里把本房间里所有的玩家的id都读出来 List <long> playerIdList = LoadAllPlayerIdsInRoom(); // 2-创建实例, 然后把每个玩家在redis的存盘都读出来 for (int i = 0; i < playerIdList.Count; ++i) { PlayerInfoInRoom piir = new PlayerInfoInRoom { Enter = { TokenId = playerIdList[i] } }; if (LoadPlayer(piir)) { // 可能存在没有存盘的情况, 比如玩家刚刚进入游戏, 而服务器还没有存盘, PlayersInRoom[playerIdList[i]] = piir; piir.Offline(); // 这时候没人在线 } } }
/// <summary> /// 保存基础信息, 仅供查看, 如果不想看的话, 根本不用保存 /// </summary> /// <param name="piir"></param> public void SavePlayerDebugInfo(PlayerInfoInRoom piir) { string tableName = $"MAP:{RoomId}"; string keyName = $"Infos"; string info = $"Total City Count:{UrbanManager.AllCities.Count} | Total Actor Count:{ActorManager.AllActors.Count} | Total Res Count:{ResManager.AllRes.Count}"; ServerRoomManager.Instance.Redis.CSRedis.HSet(tableName, keyName, info); // 本玩家身上的物体的数量 if (piir == null) { ServerRoomManager.Instance.Log("RoomLogic SavePlayerDebugInfo Error - player not found!"); return; } long ownerId = piir.Enter.TokenId; keyName = $"Infos-{ownerId}"; info = $"City Count:{UrbanManager.CountOfThePlayer(ownerId)}/{UrbanManager.AllCities.Count} | Actor Count:{ActorManager.CountOfThePlayer(ownerId)}/{ActorManager.AllActors.Count} | Res Count:{ResManager.AllRes.Count}"; ServerRoomManager.Instance.Redis.CSRedis.HSet(tableName, keyName, info); }
/// <summary> /// Call by rpcs. Update specific player's room Info. /// </summary> /// <param name="targetTeam"></param> /// <param name="playerId"></param> public void SwitchTeam(Team targetTeam, string playerId) { PlayerInfoInRoom targetPlayer = null; foreach (var playerInfo in playerInfos) { if (playerInfo != null) { if (playerInfo.id == playerId) { targetPlayer = playerInfo; break; } } } if (targetPlayer == null) { return; } targetPlayer.team = targetTeam; targetPlayer.UpdateInfo(); }
// 获取指定资源数量 public Fix64 GetMyResource(string resourceType) { PlayerInfoInRoom pi = Players[GameCore.Instance.MePlayer]; return(pi.Resources.ContainsKey(resourceType) ? pi.Resources[resourceType] : 0); }
private static void ENTER_ROOM(byte[] bytes) { bool ret = false; string errMsg = ""; EnterRoom input = EnterRoom.Parser.ParseFrom(bytes); RoomLogic roomLogic = ServerRoomManager.Instance.GetRoomLogic(input.RoomId); if (roomLogic == null) { // 房间没有开启,需要开启并进入 roomLogic = new RoomLogic(); if (roomLogic != null) { string tableName = $"MAP:{input.RoomId}"; if (ServerRoomManager.Instance.Redis.CSRedis.Exists(tableName)) { long createrId = ServerRoomManager.Instance.Redis.CSRedis.HGet <long>(tableName, "Creator"); NetRoomInfo roomInfo = new NetRoomInfo() { RoomId = ServerRoomManager.Instance.Redis.CSRedis.HGet <long>(tableName, "RoomId"), MaxPlayerCount = ServerRoomManager.Instance.Redis.CSRedis.HGet <int>(tableName, "MaxPlayerCount"), RoomName = ServerRoomManager.Instance.Redis.CSRedis.HGet <string>(tableName, "RoomName"), Creator = createrId, }; // 初始化 roomLogic.Init(roomInfo); ServerRoomManager.Instance.AddRoomLogic(roomInfo.RoomId, roomLogic); } else {// 房间地图数据没有找到,等于没有创建房间 roomLogic = null; } } } PlayerInfo pi = null; PlayerInfoInRoom piir = null; if (roomLogic == null) { errMsg = $"Battlefield is not found! RoomId:{input.RoomId}"; // 战场没有找到! } else { pi = ServerRoomManager.Instance.GetPlayer(_args); if (pi == null) { errMsg = "PlayerInfo is not found!"; // 玩家没有找到! } else { pi.RoomId = input.RoomId; piir = roomLogic.GetPlayerInRoom(pi.Enter.TokenId); if (piir == null) { errMsg = "PlayerInfoInRoom is not found!"; // 玩家没有找到! roomLogic.Online(_args, pi.Enter, pi.RoomId); piir = roomLogic.GetPlayerInRoom(pi.Enter.TokenId); } } } if (piir != null) { // 把当前玩家设置为在线(所有玩家信息在房间创建的时候(RoomLogic.Init)就存在了, 只是不在线) roomLogic.Online(_args, pi.Enter, input.RoomId); // 通知大厅 ServerRoomManager.Instance.UpdateRoomInfoToLobby(roomLogic); // 返回成功 EnterRoomReply output = new EnterRoomReply() { Ret = true, RoomId = roomLogic.RoomId, RoomName = roomLogic.RoomName, }; ServerRoomManager.Instance.SendMsg(_args, ROOM_REPLY.EnterRoomReply, output.ToByteArray()); ServerRoomManager.Instance.Log($"MSG: ENTER_ROOM OK - Player enters the battlefield! Account:{pi.Enter.Account} - Room:{roomLogic.RoomName}"); // 玩家进入战场! } else { // 返回失败 EnterRoomReply output = new EnterRoomReply() { Ret = false, ErrMsg = errMsg, }; ServerRoomManager.Instance.SendMsg(_args, ROOM_REPLY.EnterRoomReply, output.ToByteArray()); ServerRoomManager.Instance.Log("MSG: ENTER_ROOM Error - " + errMsg); } }
public void Offline(long playerId) { var piir = GetPlayerInRoom(playerId); if (piir == null) { ServerRoomManager.Instance.Log($"RoomLogic Offline - Player not found!"); return; } // 玩家下线 piir.Offline(); // 把本玩家的代理权交给别的在线玩家, 除非我已经是最后一个了, 就不做任何处理了 // 找到一个仍然在线的玩家 PlayerInfoInRoom piirOnline = null; foreach (var keyValue in PlayersInRoom) { var piirOther = keyValue.Value; if (piirOther.IsOnline) { piirOnline = piirOther; } } if (piirOnline != null) { // 不仅是自己, 而且是把所有自己管理的AiRights, 都交给对方 foreach (var keyValue in PlayersInRoom) { var piirAi = keyValue.Value; if (piirAi.AiRights == piir.Enter.TokenId) { piirAi.AiRights = piirOnline.Enter.TokenId; ChangeAiRightsReply output = new ChangeAiRightsReply() { RoomId = piirOnline.RoomId, OwnerId = piirOnline.Enter.TokenId, AiPlayerId = piirAi.Enter.TokenId, AiAccount = piirAi.Enter.Account, ControlByMe = true, Ret = true, }; ServerRoomManager.Instance.SendMsg(piirOnline.Args, ROOM_REPLY.ChangeAiRightsReply, output.ToByteArray()); ServerRoomManager.Instance.Log($"RoomLogic Offline OK - AI Rights of {piirAi.Enter.Account} belongs to {piirOnline.Enter.Account}"); } } } else { // 如果我是最后一个玩家, 则把所有人的 AI Rights 改为0 foreach (var keyValue in PlayersInRoom) { var piirAi = keyValue.Value; if (piirAi.AiRights != piir.Enter.TokenId) { ServerRoomManager.Instance.Log($"RoomLogic Offline Error - I am the last one in the room. But the AI Rights of {piirAi.Enter.Account} belongs to someone else {piirAi.AiRights} - MyName:{piir.Enter.Account}"); } piirAi.AiRights = 0; ServerRoomManager.Instance.Log($"RoomLogic Offline OK - AI Rights of {piirAi.Enter.Account} belongs to nobody! There is no player in the room."); } } _curPlayerCount = PlayersInRoom.Count; ServerRoomManager.Instance.Log($"RoomLogic Offline OK - Player left the battlefield! Player:{piir.Enter.Account}"); // 玩家离开战场 }
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()); }
private void OnTryCommand(SocketAsyncEventArgs args, byte[] bytes) { TryCommand input = TryCommand.Parser.ParseFrom(bytes); if (input.RoomId != RoomId) { return; // 不是自己房间的消息,略过 } PlayerInfoInRoom piir = GetPlayerInRoom(input.OwnerId); if (piir == null) { string msg = "在服务器没有找到该玩家!"; TryCommandReply output = new TryCommandReply() { RoomId = input.RoomId, OwnerId = input.OwnerId, Ret = false, ErrMsg = msg, }; ServerRoomManager.Instance.SendMsg(args, ROOM_REPLY.TryCommandReply, output.ToByteArray()); ServerRoomManager.Instance.Log("RoomLogic OnTryCommand Error - " + msg + $" - Id:{input.OwnerId}"); return; } var csv = CsvDataManager.Instance.GetTable("command_id"); int actionPointCost = csv.GetValueInt(input.CommandId, "ActionPointCost"); if (actionPointCost > 0) { bool ret = true; string msg = ""; if (actionPointCost != input.ActionPointCost) { // 服务器校验一下 msg = $"行动点数服务器与客户端不一致! {input.ActionPointCost} : {actionPointCost}"; ret = false; } if (piir.ActionPoint < input.ActionPointCost) { msg = "行动点不足, 请稍后再试!"; ret = false; } if (!ret) { TryCommandReply output = new TryCommandReply() { RoomId = input.RoomId, OwnerId = input.OwnerId, Ret = false, ErrMsg = msg, }; ServerRoomManager.Instance.SendMsg(args, ROOM_REPLY.TryCommandReply, output.ToByteArray()); ServerRoomManager.Instance.Log("RoomLogic OnTryCommand Error - " + msg); return; } // 扣除行动点数 piir.AddActionPoint(-input.ActionPointCost); } { // 行动点发生变化,要通知客户端 UpdateActionPointReply output = new UpdateActionPointReply() { RoomId = input.RoomId, OwnerId = input.OwnerId, ActionPoint = piir.ActionPoint, ActionPointMax = piir.ActionPointMax, Ret = true, }; ServerRoomManager.Instance.SendMsg(args, ROOM_REPLY.UpdateActionPointReply, output.ToByteArray()); TryCommandReply output2 = new TryCommandReply() { RoomId = input.RoomId, OwnerId = input.OwnerId, Ret = true, }; ServerRoomManager.Instance.SendMsg(args, ROOM_REPLY.TryCommandReply, output2.ToByteArray()); ServerRoomManager.Instance.Log($"RoomLogic OnTryCommand OK - Permission granted! - CommandId:{input.CommandId} - ActionPointCost:{input.ActionPointCost}"); } }