public static bool isActiveBeaconSecurity(IMyCubeGrid grid) { if (grid == null) { return(false); } IMyGridTerminalSystem gridTerminal = MyAPIGateway.TerminalActionsHelper.GetTerminalSystemForGrid(grid); if (gridTerminal == null) { return(false); } List <IMyTerminalBlock> blocks = new List <IMyTerminalBlock>(); gridTerminal.GetBlocks(blocks); foreach (var block in blocks) { BeaconSecurity bs = block.GameLogic as BeaconSecurity; if (bs != null && bs.IsBeaconSecurity && bs.OwnerId != 0 && bs.IsWorking) { return(true); // one beacon removed, one more stay - nothing to do... } } return(false); }
// // == SessionComponent Hooks // public override void UpdateBeforeSimulation() { try { if (MyAPIGateway.Session == null || MyAPIGateway.Utilities == null || MyAPIGateway.Multiplayer == null) // exit if api is not ready { return; } if (!Inited) // init and set handlers { Init(); } if (Settings == null) // request or load setting { GetSettings(); // if server, settings will be set a this call, so it safe } if (!IsServer) // if client exit at this point. Cleaning works only on server side. { return; } if (Frame++ % 10 == 0) { HashSet <IMyEntity> entities = new HashSet <IMyEntity>(); MyAPIGateway.Entities.GetEntities(entities, x => x is IMyCubeGrid); foreach (IMyEntity entity in entities) { IMyCubeGrid grid = entity as IMyCubeGrid; if (grid == null) { continue; } // if this grid have an active BS, then turn off destructible for grid gridDestructible(grid, !isActiveBeaconSecurity(grid)); if (!eventedGrids.Contains(grid)) { // skip if already added actions grid.OnBlockAdded += BuildHandler.grid_OnBlockAdded; eventedGrids.Add(grid); Logger.Log.Debug("OnBlockAdded event added to {0} grids.", grid.EntityId); } } // Remove block from queues foreach (var block in queueRemoveBlocks) { IMyCubeGrid grid = block.CubeGrid as IMyCubeGrid; if (grid == null) { continue; } grid.RemoveBlock(block, true); if (block.FatBlock != null) { block.FatBlock.Close(); } } queueRemoveBlocks.Clear(); } if (Settings.CleaningFrequency == 0) { return; } #region Cleanup if ((DateTime.Now - m_cleaning).TotalSeconds > Settings.CleaningFrequency) // Cleaning by frequency { Logger.Log.Debug("Time for cleaning, from last {0} secs elapsed.", (DateTime.Now - m_cleaning).TotalSeconds); m_cleaning = DateTime.Now; HashSet <IMyEntity> entities = new HashSet <IMyEntity>(); MyAPIGateway.Entities.GetEntities(entities, x => x is IMyCubeGrid); int removed = 0; List <IMySlimBlock> ToRemove = new List <IMySlimBlock>(); HashSet <long> AlreadyCounted = new HashSet <long>(); Dictionary <long, long[]> PerFactionCount = new Dictionary <long, long[]>(); Dictionary <long, long[]> PerPlayerCount = new Dictionary <long, long[]>(); foreach (IMyCubeGrid grid in entities) { var blocks = new List <IMySlimBlock>(); grid.GetBlocks(blocks, x => x.FatBlock != null); foreach (IMySlimBlock block in blocks) { //Logger.Log.Debug("Check block {0} {1}", block.FatBlock.DisplayNameText, block.FatBlock.ToString()); BeaconSecurity bs = block.FatBlock.GameLogic as BeaconSecurity; if (bs == null || !bs.IsBeaconSecurity || bs.OwnerId == 0) { continue; } if (!AlreadyCounted.Contains(block.FatBlock.EntityId)) { AlreadyCounted.Add(block.FatBlock.EntityId); } else { continue; } // Priority for players limit. if (!PerPlayerCount.ContainsKey(bs.OwnerId)) // if there no counts, add it { PerPlayerCount[bs.OwnerId] = new long[] { 0, 0 } } ; PerPlayerCount[bs.OwnerId][0]++; if (bs.OwnerId != 0 && PerPlayerCount[bs.OwnerId][0] > Settings.LimitPerPlayer) { PerPlayerCount[bs.OwnerId][1]++; ToRemove.Add(block); continue; } IMyFaction faction = MyAPIGateway.Session.Factions.TryGetPlayerFaction(bs.OwnerId); if (faction != null) { if (!PerFactionCount.ContainsKey(faction.FactionId)) { PerFactionCount[faction.FactionId] = new long[] { 0, 0 } } ; PerFactionCount[faction.FactionId][0]++; if (PerFactionCount[faction.FactionId][0] > Settings.LimitPerFaction) { PerFactionCount[faction.FactionId][1]++; ToRemove.Add(block); } } } foreach (IMySlimBlock block in ToRemove) { grid.RemoveBlock(block, true); } removed += ToRemove.Count; ToRemove.Clear(); } List <IMyPlayer> players = new List <IMyPlayer>(); MyAPIGateway.Players.GetPlayers(players); // Send warn message about cleaning and restrictions! foreach (long ownerId in PerPlayerCount.Keys) { if (ownerId == 0 || PerPlayerCount[ownerId][1] == 0) { continue; } IMyPlayer player = players.FirstOrDefault(x => x.PlayerID == ownerId); if (player == null) { continue; } SyncPacket pckOut = new SyncPacket(); pckOut.proto = SyncPacket.Version; pckOut.command = (ushort)Command.MessageToChat; pckOut.message = string.Format("Removed {0} entity as a result of limitations on the amount {1} per player.", PerPlayerCount[ownerId][1], Settings.LimitPerPlayer); Core.SendMessage(pckOut, player.SteamUserId); } foreach (long factionId in PerFactionCount.Keys) { if (PerFactionCount[factionId][1] == 0) { continue; } IMyFaction faction = MyAPIGateway.Session.Factions.TryGetFactionById(factionId); if (faction == null) { continue; } foreach (var member in faction.Members) { IMyPlayer player = players.FirstOrDefault(x => x.PlayerID == member.Key); if (player == null) { continue; } SyncPacket pckOut = new SyncPacket(); pckOut.proto = SyncPacket.Version; pckOut.command = (ushort)Command.MessageToChat; pckOut.message = string.Format("Removed {0} entity as a result of limitations on the amount {1} per faction.", PerFactionCount[factionId][1], Settings.LimitPerFaction); Core.SendMessage(pckOut, player.SteamUserId); } } if (removed > 0) { Logger.Log.Info("Cleaning, totaly removed {0} entities.", removed); } } #endregion Cleanup } catch (Exception ex) { Logger.Log.Error("EXCEPTION at BeaconSecurity.UpdateBeforeSimulation(): {0} {1}", ex.Message, ex.StackTrace); } }
public static void OnSyncRequest(byte[] bytes) { try { Logger.Log.Debug("BeaconSecurity.OnSyncRequest() - starts"); SyncPacket pckIn = new SyncPacket(); string data = System.Text.Encoding.Unicode.GetString(bytes); //Logger.Log.Debug(@"*******************************\n{0}\n*******************************\n", data); pckIn = MyAPIGateway.Utilities.SerializeFromXML <SyncPacket>(data); Logger.Log.Info("OnSyncRequest COMMAND:{0}, id:{1}, entity:'{2}', steamid: {3}, isserver: {4}", Enum.GetName(typeof(Command), pckIn.command), pckIn.ownerId, pckIn.entityId, pckIn.steamId, Core.IsServer); if (pckIn.proto != SyncPacket.Version) { Logger.Log.Error("Wrong version of sync protocol client [{0}] <> [{1}] server", SyncPacket.Version, pckIn.proto); MyAPIGateway.Utilities.ShowNotification("Sync Protocol version mismatch! Try to restart game or server!", 5000, MyFontEnum.Red); return; } switch ((Command)pckIn.command) { case Command.MessageToChat: { MyAPIGateway.Utilities.ShowMessage(Core.MODSAY, pckIn.message); break; } case Command.SettingsSync: { if (pckIn.request) // Settings sync request { if (Core.IsServer && Core.Settings != null) { // server send settings to client Logger.Log.Info("Send sync packet with settings to user steamId {0}", pckIn.steamId); SyncPacket pckOut = new SyncPacket(); pckOut.proto = SyncPacket.Version; pckOut.request = false; pckOut.command = (ushort)Command.SettingsSync; pckOut.steamId = pckIn.steamId; pckOut.settings = Core.Settings; Core.SendMessage(pckOut, pckIn.steamId); } } else { if (!Core.IsServer) { // setting sync only for clients Logger.Log.Info("User config synced..."); // if settings changes or syncs... Core.setSettings(pckIn.settings); if (pckIn.steamId == 0) // if steamid is zero, so we updating for all clients and notify this message { MyAPIGateway.Utilities.ShowNotification("Beacon Security settings has been updated!", 2000, MyFontEnum.Green); } } } break; } case Command.SettingsChange: { if (Core.IsServer) // Only server can acccept this message { Logger.Log.Info("Some one with steamid={0} trying to change server settings", pckIn.steamId); if (Core.IsAdmin(pckIn.steamId) || pckIn.steamId == MyAPIGateway.Session.Player.SteamUserId) { Logger.Log.Info("Server config changed by steamId {0}", pckIn.steamId); Core.setSettings(pckIn.settings); // resend for all clients a new settings SyncPacket newpacket = new SyncPacket(); newpacket.proto = SyncPacket.Version; newpacket.request = false; newpacket.command = (ushort)Command.SettingsSync; newpacket.steamId = 0; // for all newpacket.settings = Core.Settings; Core.SendMessage(newpacket); } } break; } case Command.SyncOff: { IMyEntity entity; MyAPIGateway.Entities.TryGetEntityById(pckIn.entityId, out entity); if (entity == null) { break; } Logger.Log.Debug("SyncOff found entity id {0}", pckIn.entityId); BeaconSecurity bs = entity.GameLogic as BeaconSecurity; if (bs == null || !bs.IsBeaconSecurity) { break; } Logger.Log.Debug(" * entity is BeaconSecurity"); if (entity is IMyFunctionalBlock) { (entity as IMyFunctionalBlock).RequestEnable(false); } IMyPlayer player = MyAPIGateway.Session.Player; if (player != null) // check this for dedicated servers { MyRelationsBetweenPlayerAndBlock relation = (entity as IMyFunctionalBlock).GetUserRelationToOwner(player.PlayerID); if (relation == MyRelationsBetweenPlayerAndBlock.Owner || relation == MyRelationsBetweenPlayerAndBlock.FactionShare) { // if player has rights to this beacon, show message MyAPIGateway.Utilities.ShowNotification(string.Format("{0} beacon security called '{1}' is deactivated now!", (relation == MyRelationsBetweenPlayerAndBlock.FactionShare) ? "Faction" : "Your", (entity.GameLogic as BeaconSecurity).DisplayName), 5000, MyFontEnum.Red); } } break; } case Command.SyncOn: { IMyEntity entity; MyAPIGateway.Entities.TryGetEntityById(pckIn.entityId, out entity); if (entity == null) { break; } Logger.Log.Debug("SyncOn found entity id {0}", pckIn.entityId); BeaconSecurity bs = entity.GameLogic as BeaconSecurity; if (bs == null || !bs.IsBeaconSecurity) { break; } Logger.Log.Debug(" * entity is BeaconSecurity"); if (entity is IMyFunctionalBlock) { (entity as IMyFunctionalBlock).RequestEnable(true); } IMyPlayer player = MyAPIGateway.Session.Player; if (player != null) // check this for dedicated servers { MyRelationsBetweenPlayerAndBlock relation = (entity as IMyFunctionalBlock).GetUserRelationToOwner(player.PlayerID); if (relation == MyRelationsBetweenPlayerAndBlock.Owner || relation == MyRelationsBetweenPlayerAndBlock.FactionShare) { // if player has rights to this beacon, show message MyAPIGateway.Utilities.ShowNotification(string.Format("{0} beacon security called '{1}' is activated now!", (relation == MyRelationsBetweenPlayerAndBlock.FactionShare) ? "Faction" : "Your", (entity.GameLogic as BeaconSecurity).DisplayName), 5000, MyFontEnum.Green); } } break; } default: { break; } } } catch (Exception ex) { Logger.Log.Error("Exception at BeaconSecurity.OnSyncRequest(): {0}", ex.Message); return; } }