/// <summary> /// Determines whether the projected grid still fits within block limits set by server after a new block is added /// </summary> private bool IsWithinWorldLimits(MyProjectorBase projector, string name) { if (!MySession.Static.EnableBlockLimits) { return(true); } bool withinLimits = true; var identity = MySession.Static.Players.TryGetIdentity(BuiltBy); if (MySession.Static.MaxBlocksPerPlayer > 0) { withinLimits &= BuiltBy == 0 || IDModule.GetUserRelationToOwner(BuiltBy) != MyRelationsBetweenPlayerAndBlock.Enemies; // Don't allow stolen enemy welders to build withinLimits &= projector.BuiltBy == 0 || IDModule.GetUserRelationToOwner(projector.BuiltBy) != MyRelationsBetweenPlayerAndBlock.Enemies; // Don't allow welders to build from enemy projectors withinLimits &= identity == null || identity.BlocksBuilt < MySession.Static.MaxBlocksPerPlayer + identity.BlockLimitModifier; } withinLimits &= MySession.Static.MaxGridSize == 0 || projector.CubeGrid.BlocksCount < MySession.Static.MaxGridSize; short typeLimit = MySession.Static.GetBlockTypeLimit(name); int typeBuilt; if (identity != null && typeLimit > 0) { withinLimits &= (identity.BlockTypeBuilt.TryGetValue(name, out typeBuilt) ? typeBuilt : 0) < typeLimit; } return(withinLimits); }
public MyProjectorClipboard(MyProjectorBase projector, MyPlacementSettings settings) : base(settings) //Pasting Settings here ? { MyDebug.AssertDebug(projector != null); m_projector = projector; m_calculateVelocity = false; }
public MyProjectorClipboard(MyProjectorBase projector) : base(MyPerGameSettings.PastingSettings) { MyDebug.AssertDebug(projector != null); m_projector = projector; m_calculateVelocity = false; }
public static void BuildPatch(MyProjectorBase __instance, MySlimBlock cubeBlock, long owner, long builder, bool requestInstant = true, long builtBy = 0) { if (CrunchUtilitiesPlugin.file == null) { return; } if (!CrunchUtilitiesPlugin.file.projectorOwnershipPatch) { return; } if (__instance != null && owner == 0) { if (cubeBlock.FatBlock != null) { MyCubeBlock block = cubeBlock.FatBlock; block.CubeGrid.ChangeOwner(block, 0, __instance.OwnerId); } } }
private static bool ExtraCheck(MyProjectorBase __instance, ref Vector3I cubeBlockPosition) { if (__instance == null || cubeBlockPosition != null) { return(true); } Validations.ValidationFailed(); return(false); }
public void SetProjectedGrid(MyObjectBuilder_CubeGrid grid, MyProjectorBase projector) { //if (grid == null) // return; //MyEntities.RemapObjectBuilder(grid); //originalBuilder.SetValue(projector, grid); //sendNewBlueprint.Invoke(projector, new object[] { grid }); ((IMyProjector)projector).SetProjectedGrid(grid); }
private static void PrefixNewBlueprint(MyProjectorBase __instance, ref List <MyObjectBuilder_CubeGrid> projectedGrids) { var proj = __instance; if (proj == null) { Log.Warn("No projector?"); } var grid = projectedGrids[0]; RemoveStockPile(grid); }
private static void DecreaseProjectedCount(MyProjectorBase __instance) { if (!BlockLimiterConfig.Instance.CountProjections) { return; } MyIdentity myIdentity = MySession.Static.Players.TryGetIdentity(__instance.BuiltBy); var grid = __instance.ProjectedGrid; if (grid == null || myIdentity == null) { return; } foreach (var block in grid.CubeBlocks) { Block.DecreaseCount(block.BlockDefinition, myIdentity.IdentityId, 1, __instance.CubeGrid.EntityId); } }
private static void DecreaseCount(MyProjectorBase __instance) { if (__instance == null) { return; } if (MainLogic.Instance.Config?.CounterPcuIncrease == false) { return; } var identity = MySession.Static.Players.TryGetIdentity(__instance.BuiltBy); var copiedGrids = __instance?.Clipboard?.CopiedGrids; if (copiedGrids == null) { return; } int num1 = 0; foreach (MyObjectBuilder_CubeGrid copiedGrid in copiedGrids) { num1 += copiedGrid.CubeBlocks.Count; } if (identity == null || num1 == 0) { return; } var num2 = num1; if (!MySession.Static.CheckLimitsAndNotify(__instance.BuiltBy, __instance.BlockDefinition.BlockPairName, num2, 0, 0, (Dictionary <string, int>)null)) { return; } identity.BlockLimits.DecreaseBlocksBuilt(__instance.BlockDefinition.BlockPairName, num2, __instance.CubeGrid, false); __instance.CubeGrid.BlocksPCU -= num2; }
public static void SetGridPreview(long EntityID, ulong Owner, string GridName) { if (!ValidGrid(Owner, GridName, out MarketListing Offer, out string GridPath)) { return; } if (Offer.NumberofBlocks > 100000) { Log.Warn("MarketPreview Blocked. Grid is greater than 100000 blocks"); return; } //Need async Log.Warn("Loading Grid"); if (!GridSerializer.LoadGrid(GridPath, out IEnumerable <MyObjectBuilder_CubeGrid> GridBuilders)) { RemoveMarketListing(Owner, GridName); return; } //Now attempt to load grid if (MyEntities.TryGetEntityById(EntityID, out MyEntity entity)) { MyProjectorBase proj = entity as MyProjectorBase; if (proj != null) { proj.SendRemoveProjection(); var Grids = GridBuilders.ToList(); Log.Warn("Setting projection!"); SendNewProjection.Invoke(proj, new object[] { Grids }); } } }
public ProjectionRaycastData(MyProjectorBase.BuildCheckResult result, MySlimBlock cubeBlock, MyProjectorBase projector) { raycastResult = result; hitCube = cubeBlock; cubeProjector = projector; }
/// <summary> /// Checks projections before showing and remove any nonAllowed blocks. /// </summary> /// <param name="__instance"></param> /// <returns></returns> private static bool PrefixInitializeClipboard(MyProjectorBase __instance) { if (!BlockLimiterConfig.Instance.EnableLimits) { return(true); } var remoteUserId = MyEventContext.Current.Sender.Value; var grid = __instance.CubeGrid; var copiedGrid = __instance.Clipboard.CopiedGrids[0]; if (copiedGrid == null || grid == null) { return(true); } var player = MySession.Static.Players.TryGetPlayerBySteamId(remoteUserId); var projectedBlocks = copiedGrid.CubeBlocks; if (player == null || projectedBlocks.Count == 0) { return(true); } if (Utilities.IsExcepted(player)) { return(true); } var playerId = player.Identity.IdentityId; if ((Grid.IsSizeViolation(copiedGrid) && BlockLimiterConfig.Instance.BlockType > BlockLimiterConfig.BlockingType.Warn) || BlockLimiterConfig.Instance.MaxBlockSizeProjections < 0 || (projectedBlocks.Count > BlockLimiterConfig.Instance.MaxBlockSizeProjections && BlockLimiterConfig.Instance.MaxBlockSizeProjections > 0) || (Grid.CountViolation(copiedGrid, playerId) && BlockLimiterConfig.Instance.BlockType > BlockLimiterConfig.BlockingType.Warn)) { NetworkManager.RaiseEvent(__instance, RemoveBlueprintMethod, MyEventContext.Current.Sender); Utilities.ValidationFailed(); var msg1 = Utilities.GetMessage(BlockLimiterConfig.Instance.DenyMessage, new List <string> { "Null" }, "SizeViolation", grid.CubeBlocks.Count); if (remoteUserId != 0 && MySession.Static.Players.IsPlayerOnline(player.Identity.IdentityId)) { BlockLimiter.Instance.Torch.CurrentSession.Managers.GetManager <ChatManagerServer>()? .SendMessageAsOther(BlockLimiterConfig.Instance.ServerName, msg1, Color.Red, remoteUserId); } Log.Info($"Projection blocked from {player.DisplayName} due to size limit"); return(false); } var limits = new HashSet <LimitItem>(); limits.UnionWith(BlockLimiterConfig.Instance.AllLimits.Where(x => x.RestrictProjection)); if (limits.Count == 0) { return(true); } var count = 0; var playerFaction = MySession.Static.Factions.GetPlayerFaction(playerId); string limitName = null; var removedList = new List <string>(); foreach (var limit in limits) { if (limit.IsExcepted(player) || limit.IsExcepted(__instance.CubeGrid)) { continue; } var pBlocks = new HashSet <MyObjectBuilder_CubeBlock>(projectedBlocks.Where(x => limit.IsMatch(Utilities.GetDefinition(x)))); if (pBlocks.Count == 0) { continue; } var removalCount = 0; var fCount = 0; limit.FoundEntities.TryGetValue(grid.EntityId, out var gCount); limit.FoundEntities.TryGetValue(playerId, out var pCount); if (playerFaction != null) { limit.FoundEntities.TryGetValue(playerFaction.FactionId, out fCount); } foreach (var block in pBlocks) { if (Math.Abs(pBlocks.Count + pCount - removalCount) <= limit.Limit && Math.Abs(gCount + pBlocks.Count - removalCount) <= limit.Limit && Math.Abs(fCount + pBlocks.Count - removalCount) <= limit.Limit) { break; } removalCount++; count++; projectedBlocks.Remove(block); var blockDef = Utilities.GetDefinition(block).ToString().Substring(16); if (removedList.Contains(blockDef)) { continue; } removedList.Add(blockDef); limitName = limit.Name; } } if (count == 0) { return(true); } Log.Info($"Removed {count} blocks from projector set by {player.DisplayName} "); NetworkManager.RaiseEvent(__instance, RemoveBlueprintMethod); ((IMyProjector)__instance).SetProjectedGrid(copiedGrid); var msg = Utilities.GetMessage(BlockLimiterConfig.Instance.ProjectionDenyMessage, removedList, limitName, count); if (remoteUserId != 0 && MySession.Static.Players.IsPlayerOnline(player.Identity.IdentityId)) { BlockLimiter.Instance.Torch.CurrentSession.Managers.GetManager <ChatManagerServer>()? .SendMessageAsOther(BlockLimiterConfig.Instance.ServerName, msg, Color.Red, remoteUserId); } return(false); }
private static bool PrefixNewBlueprint(MyProjectorBase __instance, ref List <MyObjectBuilder_CubeGrid> projectedGrids) { var remoteUserId = MyEventContext.Current.Sender.Value; var proj = __instance; if (proj == null) { Log.Warn("Null projector detected"); return(true); } var grid = projectedGrids[0]; if (grid == null) { return(true); } var blocks = grid.CubeBlocks; if (MainLogic.Instance.Config.MaxGridSize > 0 && grid.CubeBlocks.Count > MainLogic.Instance.Config.MaxGridSize) { var diff = Math.Abs(grid.CubeBlocks.Count - MainLogic.Instance.Config.MaxGridSize); NetworkManager.RaiseEvent(__instance, RemoveBlueprintMethod); Validations.SendFailSound(remoteUserId); Validations.ValidationFailed(); MyVisualScriptLogicProvider.SendChatMessage($" Projection is {diff} blocks too big", MainLogic.ChatName, MySession.Static.Players.TryGetIdentityId(remoteUserId), MyFontEnum.Red); Log.Info($"Blocked an oversized grid projection by {MySession.Static.Players.TryGetIdentityNameFromSteamId(remoteUserId)}"); return(false); } if (blocks.Count == 0) { NetworkManager.RaiseEvent(__instance, RemoveBlueprintMethod); Validations.SendFailSound(remoteUserId); Validations.ValidationFailed(); return(false); } var invCount = 0; var jCount = 0; var tCount = 0; var pbCount = 0; var fCount = 0; var pRCount = 0; var removalCount = 0; var blockList = new HashSet <string>(); for (var i = blocks.Count - 1; i >= 0; i--) { var block = blocks[i]; var def = Utilities.GetDefinition(block); if (Utilities.IsMatch(def)) { blocks.RemoveAtFast(i); removalCount++; if (def == null || blockList.Contains(def.ToString().Substring(16))) { continue; } blockList.Add(def.ToString().Substring(16)); continue; } if (block is MyObjectBuilder_OreDetector oreDetector && MainLogic.Instance.Config.ResetOreDetectors) { oreDetector.DetectionRadius = 0; } if (block is MyObjectBuilder_RemoteControl rm && MainLogic.Instance.Config.ResetRemoteControl) { rm.AutopilotSpeedLimit = 0; rm.AutomaticBehaviour = null; } if (MainLogic.Instance.Config.ClearInventory) { switch (block) { case MyObjectBuilder_Drill drill: if (drill.Inventory?.Items.Count > 0) { invCount++; drill.Inventory?.Clear(); } break; case MyObjectBuilder_ShipToolBase shipTool: if (shipTool.Inventory?.Items.Count > 0) { invCount++; shipTool.Inventory?.Clear(); } break; case MyObjectBuilder_Reactor reactor: if (reactor.Inventory?.Items.Count > 0) { invCount++; reactor.Inventory?.Clear(); } break; case MyObjectBuilder_SmallMissileLauncherReload mm: { if (mm.GunBase?.RemainingAmmo > 0) { mm.GunBase = null; invCount++; } } break; } var components = block.ComponentContainer?.Components; if (components != null) { foreach (var data in components) { if (data.Component is MyObjectBuilder_Inventory inv && inv.Items.Count > 0) { inv.Clear(); invCount++; } if (data.Component is MyObjectBuilder_EntityCapacitorComponent cap && cap.StoredPower > 0) { cap.StoredPower = 0; } } } try { block.GetType()?.GetField("Inventory")?.SetValue(block, null); block.GetType()?.GetField("InputInventory")?.SetValue(block, null); block.GetType()?.GetField("OutputInventory")?.SetValue(block, null); } catch (Exception e) { Log.Warn(e, "There was an issue clearing projection inventories"); } } if (MainLogic.Instance.Config.ResetJumpDrives && block is MyObjectBuilder_JumpDrive jDrive && Math.Abs(jDrive.StoredPower) > 0) { jDrive.StoredPower = 0; jCount++; } if (MainLogic.Instance.Config.ResetTanks) { if (block is MyObjectBuilder_GasTank tank && tank.FilledRatio > 0) { tank.FilledRatio = 0; tCount++; } if (block is MyObjectBuilder_HydrogenEngine hEngine && hEngine.Capacity > 0) { hEngine.Capacity = 0; tCount++; } } if (MainLogic.Instance.Config.RemoveScripts && block is MyObjectBuilder_MyProgrammableBlock pbBlock) { if (pbBlock.Program != null) { pbBlock.Program = null; pbCount++; } } if (MainLogic.Instance.Config.RemoveProjections && block is MyObjectBuilder_Projector projectedProjector) { if (projectedProjector.ProjectedGrids != null) { projectedProjector.ProjectedGrid = null; pRCount++; } } if (!MainLogic.Instance.Config.ShutOffBlocks || !(block is MyObjectBuilder_FunctionalBlock fBlock) || !fBlock.Enabled || fBlock is MyObjectBuilder_MergeBlock) { continue; } fBlock.Enabled = false; fCount++; } if (jCount > 0) { Log.Info($"{jCount} JumpDrives edited"); } if (invCount > 0) { Log.Info($"{invCount} inventory blocks cleaned"); } if (tCount > 0) { Log.Info($"{tCount} tanks reset in projection"); } if (pbCount > 0) { Log.Info($"{pbCount} programmable blocks cleared from projection"); } if (fCount > 0) { Log.Info($"{fCount} blocks switched off in projection"); } if (pRCount > 0) { Log.Info($"{pRCount} projections removed from projection"); } if (removalCount == 0) { return(true); } Log.Info($"{removalCount} blocks removed from projection"); NetworkManager.RaiseEvent(__instance, RemoveBlueprintMethod); var msg = string.Join("\n", $"Removed {removalCount} Blocks", string.Join("\n", blockList)); MyVisualScriptLogicProvider.SendChatMessage(msg, MainLogic.ChatName, MySession.Static.Players.TryGetIdentityId(remoteUserId), MyFontEnum.Red); try { NetworkManager.RaiseEvent(__instance, NewBlueprintMethod, new List <MyObjectBuilder_CubeGrid> { grid }, new EndpointId(remoteUserId)); } catch (Exception e) { Log.Error(e); } return(true); }
/// <summary> /// Aim to block projections or remove blocks to match grid/player limits. /// </summary> /// <param name="__instance"></param> /// <param name="projectedGrids"></param> /// <returns></returns> private static bool PrefixNewBlueprint(MyProjectorBase __instance, ref List <MyObjectBuilder_CubeGrid> projectedGrids) { if (!BlockLimiterConfig.Instance.EnableLimits) { return(true); } var proj = __instance; if (proj == null) { Log.Warn("No projector?"); return(false); } var grid = projectedGrids[0]; if (grid == null) { Log.Warn("Grid null in projectorPatch"); return(false); } var remoteUserId = MyEventContext.Current.Sender.Value; var player = MySession.Static.Players.TryGetPlayerBySteamId(remoteUserId); var blocks = grid.CubeBlocks; if (player == null || blocks.Count == 0) { return(true); } if (Utilities.IsExcepted(player.Identity.IdentityId, new List <string>())) { return(true); } var target = new EndpointId(remoteUserId); var playerId = player.Identity.IdentityId; if (Grid.IsSizeViolation(grid)) { Task.Run(() => { Thread.Sleep(100); NetworkManager.RaiseEvent(__instance, RemoveProjectionMethod, target); }); Utilities.SendFailSound(remoteUserId); Utilities.ValidationFailed(); MyVisualScriptLogicProvider.SendChatMessage($"{BlockLimiterConfig.Instance.DenyMessage}", BlockLimiterConfig.Instance.ServerName, playerId, MyFontEnum.Red); if (BlockLimiterConfig.Instance.EnableLog) { Log.Info($"Projection blocked from {player.DisplayName}"); } return(false); } var limits = new HashSet <LimitItem>(); limits.UnionWith(BlockLimiterConfig.Instance.AllLimits.Where(x => x.RestrictProjection && !Utilities.IsExcepted(grid.EntityId, x.Exceptions) && !Utilities.IsExcepted(player.Identity.IdentityId, x.Exceptions))); if (limits.Count == 0) { return(true); } var count = 0; var playerFaction = MySession.Static.Factions.GetPlayerFaction(playerId); foreach (var limit in limits) { var pBlocks = blocks.Where(x => Block.IsMatch(Utilities.GetDefinition(x), limit)).ToList(); if (pBlocks.Count < 1) { continue; } var removalCount = 0; var fCount = 0; limit.FoundEntities.TryGetValue(grid.EntityId, out var gCount); limit.FoundEntities.TryGetValue(playerId, out var oCount); if (playerFaction != null) { limit.FoundEntities.TryGetValue(playerFaction.FactionId, out fCount); } foreach (var block in pBlocks) { if (Math.Abs(pBlocks.Count - removalCount) <= limit.Limit || Math.Abs(fCount + pBlocks.Count - removalCount) <= limit.Limit && (Math.Abs((oCount + pBlocks.Count) - removalCount) <= limit.Limit && Math.Abs((gCount + pBlocks.Count) - removalCount) <= limit.Limit)) { break; } removalCount++; count++; blocks.Remove(block); } } if (count < 1) { return(true); } NetworkManager.RaiseEvent(__instance, RemoveProjectionMethod, target); try { NetworkManager.RaiseEvent(__instance, NewBlueprintMethod, new List <MyObjectBuilder_CubeGrid> { grid }); } catch (Exception e) { //NullException thrown here but seems to work for some reason. Don't Touch any further } var msg = BlockLimiterConfig.Instance.ProjectionDenyMessage.Replace("{BC}", $"{count}"); MyVisualScriptLogicProvider.SendChatMessage($"{msg}", BlockLimiterConfig.Instance.ServerName, playerId, MyFontEnum.Red); return(true); }
/// <summary> /// Checks blocks about to be welded with limits and decide if weld is allowed. /// </summary> /// <param name="__instance"></param> /// <param name="cubeBlockPosition"></param> /// <param name="owner"></param> /// <param name="builder"></param> /// <param name="requestInstant"></param> /// <param name="builtBy"></param> /// <returns></returns> private static bool Build(MyProjectorBase __instance, Vector3I cubeBlockPosition, long owner, long builder, bool requestInstant = true, long builtBy = 0) { var projector = __instance; if (projector == null) { return(false); } if (!BlockLimiterConfig.Instance.EnableLimits) { return(true); } if (owner + builder == 0) { return(false); } long projectorId = projector.EntityId; int subgridIndex = (int)builtBy; MyCubeGrid builtGrid = (MyCubeGrid)BlockLimiter.Instance.MultigridProjectorApi.GetBuiltGrid(projectorId, subgridIndex) ?? __instance.CubeGrid; if (builtGrid == null) { return(false); } MyCubeGrid previewGrid = (MyCubeGrid)BlockLimiter.Instance.MultigridProjectorApi.GetPreviewGrid(projectorId, subgridIndex) ?? __instance.ProjectedGrid; if (previewGrid == null) { return(false); } MySlimBlock previewBlock = previewGrid?.GetCubeBlock(cubeBlockPosition); var blockDefinition = previewBlock?.BlockDefinition; if (blockDefinition == null) { return(false); } var remoteUserId = MyEventContext.Current.Sender.Value; if (Block.IsWithinLimits(blockDefinition, owner, builtGrid.EntityId, 1, out var limitName) && Block.IsWithinLimits(blockDefinition, builder, builtGrid.EntityId, 1, out limitName)) { return(true); } BlockLimiter.Instance.Log.Info($"Blocked welding of {blockDefinition.ToString().Substring(16)} owned by {Utilities.GetPlayerNameFromSteamId(remoteUserId)}"); var msg = Utilities.GetMessage(BlockLimiterConfig.Instance.DenyMessage, new List <string> { blockDefinition.ToString().Substring(16) }, limitName); if (remoteUserId == 0) { return(false); } var playerId = Utilities.GetPlayerIdFromSteamId(remoteUserId); if (!MySession.Static.Players.IsPlayerOnline(playerId)) { return(false); } BlockLimiter.Instance.Torch.CurrentSession.Managers.GetManager <ChatManagerServer>()? .SendMessageAsOther(BlockLimiterConfig.Instance.ServerName, msg, Color.Red, remoteUserId); Utilities.SendFailSound(remoteUserId); Utilities.ValidationFailed(remoteUserId); return(false); }
public MyProjectorClipboard(MyProjectorBase projector, MyPlacementSettings settings) : base(settings, true) { this.m_projector = projector; base.m_calculateVelocity = false; }
/// <summary> /// Aim to block projections or remove blocks to match grid/player limits. /// </summary> /// <param name="__instance"></param> /// <param name="projectedGrids"></param> /// <returns></returns> private static bool PrefixNewBlueprint(MyProjectorBase __instance, ref List <MyObjectBuilder_CubeGrid> projectedGrids) { var remoteUserId = MyEventContext.Current.Sender.Value; var proj = __instance; if (proj == null) { Log.Warn("No projector?"); return(false); } bool changesMade = false; if (BlockLimiter.DPBInstalled) { try { object[] parameters = { projectedGrids, remoteUserId, null }; BlockLimiter.DPBCanAdd?.Invoke(null, parameters); changesMade = (bool)parameters[2]; } catch (Exception e) { Log.Warn(e, "DPB was unable to check projection"); } } if (changesMade) { NetworkManager.RaiseEvent(__instance, RemoveBlueprintMethod, new EndpointId(remoteUserId)); } var grid = projectedGrids[0]; if (grid == null) { Log.Warn("Grid null in projectorPatch"); return(false); } if (!BlockLimiterConfig.Instance.EnableLimits) { if (changesMade) { NetworkManager.RaiseEvent(__instance, NewBlueprintMethod, new List <MyObjectBuilder_CubeGrid> { grid }); } return(true); } var player = MySession.Static.Players.TryGetPlayerBySteamId(remoteUserId); var projectedBlocks = grid.CubeBlocks; if (player == null || projectedBlocks.Count == 0) { if (changesMade) { NetworkManager.RaiseEvent(__instance, NewBlueprintMethod, new List <MyObjectBuilder_CubeGrid> { grid }); } return(true); } if (Utilities.IsExcepted(player)) { if (changesMade) { NetworkManager.RaiseEvent(__instance, NewBlueprintMethod, new List <MyObjectBuilder_CubeGrid> { grid }); } return(true); } var playerId = player.Identity.IdentityId; if (Grid.IsSizeViolation(grid) || BlockLimiterConfig.Instance.MaxBlockSizeProjections < 0 || (projectedBlocks.Count > BlockLimiterConfig.Instance.MaxBlockSizeProjections && BlockLimiterConfig.Instance.MaxBlockSizeProjections > 0) || Grid.CountViolation(grid, playerId)) { NetworkManager.RaiseEvent(__instance, RemoveBlueprintMethod, new EndpointId(remoteUserId)); Utilities.ValidationFailed(); var msg1 = Utilities.GetMessage(BlockLimiterConfig.Instance.DenyMessage, new List <string> { "Null" }, "SizeViolation", grid.CubeBlocks.Count); if (remoteUserId != 0 && MySession.Static.Players.IsPlayerOnline(player.Identity.IdentityId)) { BlockLimiter.Instance.Torch.CurrentSession.Managers.GetManager <ChatManagerServer>()? .SendMessageAsOther(BlockLimiterConfig.Instance.ServerName, msg1, Color.Red, remoteUserId); } Log.Info($"Projection blocked from {player.DisplayName} due to size limit"); return(false); } var limits = new HashSet <LimitItem>(); limits.UnionWith(BlockLimiterConfig.Instance.AllLimits.Where(x => x.RestrictProjection)); if (limits.Count == 0) { if (changesMade) { NetworkManager.RaiseEvent(__instance, NewBlueprintMethod, new List <MyObjectBuilder_CubeGrid> { grid }); } return(true); } var count = 0; var playerFaction = MySession.Static.Factions.GetPlayerFaction(playerId); string limitName = null; var removedList = new List <string>(); foreach (var limit in limits) { if (Utilities.IsExcepted(player, limit) || Utilities.IsExcepted(proj.CubeGrid, limit)) { continue; } var pBlocks = new HashSet <MyObjectBuilder_CubeBlock>(projectedBlocks.Where(x => limit.IsMatch(Utilities.GetDefinition(x)))); if (pBlocks.Count == 0) { continue; } var removalCount = 0; var fCount = 0; limit.FoundEntities.TryGetValue(grid.EntityId, out var gCount); limit.FoundEntities.TryGetValue(playerId, out var pCount); if (playerFaction != null) { limit.FoundEntities.TryGetValue(playerFaction.FactionId, out fCount); } foreach (var block in pBlocks) { if (Math.Abs(pBlocks.Count + pCount - removalCount) <= limit.Limit && Math.Abs(gCount + pBlocks.Count - removalCount) <= limit.Limit && Math.Abs(fCount + pBlocks.Count - removalCount) <= limit.Limit) { break; } removalCount++; count++; projectedBlocks.Remove(block); var blockDef = Utilities.GetDefinition(block).ToString().Substring(16); if (removedList.Contains(blockDef)) { continue; } removedList.Add(blockDef); limitName = limit.Name; } } if (count == 0) { return(true); } Log.Info($"Removed {count} blocks from projector set by {player.DisplayName} "); NetworkManager.RaiseEvent(__instance, RemoveBlueprintMethod); try { NetworkManager.RaiseEvent(__instance, NewBlueprintMethod, new List <MyObjectBuilder_CubeGrid> { grid }, new EndpointId(remoteUserId)); } catch (Exception e) { Log.Error(e); } var msg = Utilities.GetMessage(BlockLimiterConfig.Instance.ProjectionDenyMessage, removedList, limitName, count); if (remoteUserId != 0 && MySession.Static.Players.IsPlayerOnline(player.Identity.IdentityId)) { BlockLimiter.Instance.Torch.CurrentSession.Managers.GetManager <ChatManagerServer>()? .SendMessageAsOther(BlockLimiterConfig.Instance.ServerName, msg, Color.Red, remoteUserId); } return(true); }
public override bool Handle(ulong remoteUserId, CallSite site, BitStream stream, object obj) { if (!PluginSettings.Instance.LimitProjectionSize) { return(false); } MyProjectorBase proj = obj as MyProjectorBase; if (proj == null) { NoGrief.Log.Error("Null projector in ProjectionHandler"); return(false); } MyObjectBuilder_CubeGrid grid = null; base.Serialize(site.MethodInfo, stream, ref grid); if (grid.CubeBlocks.Count <= PluginSettings.Instance.ProjectionBlockCount) { return(false); } if (PluginSettings.Instance.AdminProjectionExempt) { if (PlayerManager.Instance.IsUserAdmin(remoteUserId)) { return(false); } ulong ownerSteam = PlayerMap.Instance.GetSteamIdFromPlayerId(proj.OwnerId); if (PlayerManager.Instance.IsUserAdmin(ownerSteam)) { return(false); } } if (!string.IsNullOrEmpty(PluginSettings.Instance.ProjectionLimitMessage)) { Communication.Notification(remoteUserId, MyFontEnum.White, 10000, PluginSettings.Instance.ProjectionLimitMessage); } NoGrief.Log.Info($"Intercepted projection change request from {PlayerMap.Instance.GetFastPlayerNameFromSteamId(remoteUserId)}:{remoteUserId}. Projection size: {grid.CubeBlocks.Count}"); //this junk is to work around the fact that clints set the projected grid locally before sending the network event //so we tell them to remove the projection and replace it with what the server has if (proj.Clipboard.PreviewGrids.Count != 0) { //as much as I hate to do reflection here, it's necessary :( var projGrid = typeof(MyProjectorBase).GetField("m_originalGridBuilder", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(proj) as MyObjectBuilder_CubeGrid; //order of operations is important! //proj.SendRemoveProjection(); //typeof(MyProjectorBase).GetMethod("SendNewBlueprint", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(proj, new object[] { projGrid }); //don't waste bandwidth resending the projection to all clients, just send it back to the requesting client var remMethod = typeof(MyProjectorBase).GetMethod("OnRemoveProjectionRequest", BindingFlags.NonPublic | BindingFlags.Instance); ServerNetworkManager.Instance.RaiseEvent(remMethod, proj, remoteUserId); var newMethod = typeof(MyProjectorBase).GetMethod("OnNewBlueprintSuccess", BindingFlags.NonPublic | BindingFlags.Instance); ServerNetworkManager.Instance.RaiseEvent(newMethod, proj, remoteUserId, projGrid); } else { //if there wasn't already a projection, just tell clients to clear proj.SendRemoveProjection(); } return(true); }
private static bool StepWeld(ShipyardItem shipyardItem) { HashSet <long> stalledWelders = new HashSet <long>(); var missingComponents = new Dictionary <string, int>(); var random = new Random(); float weldAmount = Server.Instance.Config.WelderSpeedMultiplier * PluginSettings.Instance.WeldMultiplier; float boneAmount = weldAmount * .1f; //shorten this to grid for convenience MyCubeGrid grid = shipyardItem.Grid; if (grid?.Physics == null || grid.Closed) { return(false); } var weldBlocks = new HashSet <MySlimBlock>(); foreach (MySlimBlock block in grid.CubeBlocks.Where(block => !block.IsFullIntegrity || (block.HasDeformation || block.MaxDeformation > 0.0001f))) { weldBlocks.Add(block); } //if we have no blocks to weld, return false so we know we're done if (weldBlocks.Count == 0) { if (shipyardItem.GridProjector == null) { foreach (var block in shipyardItem.Grid.GetFatBlocks()) { MyProjectorBase projector = block as MyProjectorBase; if (projector?.Clipboard.PreviewGrids.Count > 0) { /* * bool canBuild = false; * Wrapper.GameAction( () => canBuild = projector.Clipboard.PreviewGrids[0].CubeBlocks.All(x => projector.CanBuild(x, true) != MyProjectorBase.BuildCheckResult.OK)); * if ( !canBuild) * continue; */ shipyardItem.GridProjector = projector; break; } } } } if (weldBlocks.Count < 8 && shipyardItem.GridProjector?.Clipboard.PreviewGrids.Count > 0) { int neededBlocks = 8 - weldBlocks.Count; //shipyardItem.ProcessBlocks.Clear(); for (int b = 0; b < neededBlocks; b++) { var welder = shipyardItem.Tools[b]; var projector = shipyardItem.GridProjector; var projectedGrid = projector.Clipboard.PreviewGrids[0]; MySlimBlock buildBlock = null; Wrapper.GameAction(() => { //buildBlock = projectedGrid.CubeBlocks.First( x => projector.CanBuild( x, true ) == MyProjectorBase.BuildCheckResult.OK ); foreach (var block in projectedGrid.CubeBlocks) { if (projector.CanBuild(block, true) == MyProjectorBase.BuildCheckResult.OK) { buildBlock = block; break; } } if (buildBlock == null) { return; } var welderInventory = (MyInventory)((IMyShipWelder)welder).GetInventory(0); var components = buildBlock.BlockDefinition.Components; if (components == null || components.Length == 0) { return; } var componentId = components[0].Definition.Id; MyGridConveyorSystem.ItemPullRequest((IMyConveyorEndpointBlock)welder, welderInventory, welder.OwnerId, componentId, 1); if (welderInventory.ContainItems(1, buildBlock.BlockDefinition.Components[0].Definition.Id)) { projector.Build(buildBlock, welder.OwnerId, welder.EntityId); } }); /* * Communication.MessageStruct message = new Communication.MessageStruct() * { * toolId=welder.EntityId, * gridId=buildBlock.CubeGrid.EntityId, * blockPos=buildBlock.Position, * packedColor = Color.LightGreen.PackedValue, * pulse=false * }; * Communication.SendLine( message ); */ //if (buildBlock!=null) //weldBlocks.Add( buildBlock ); } } if (shipyardItem.GridProjector?.Clipboard.PreviewGrids.Count == 0) { shipyardItem.GridProjector = null; return(false); } foreach (IMyCubeBlock welder in shipyardItem.Tools) { if (!shipyardItem.ProcessBlocks.ContainsKey(welder.EntityId)) { MySlimBlock nextBlock = null; var tryCount = 0; while (tryCount < 20) { //limit the number of tries so we don't get stuck in a loop forever tryCount++; //pick a random block. we don't really care if two welders hit the same block, so don't check if (weldBlocks.Count > 1) { nextBlock = weldBlocks.ElementAt(random.Next(0, weldBlocks.Count - 1)); } else { nextBlock = weldBlocks.FirstElement(); } if (nextBlock == null) { continue; } if (!nextBlock.IsFullIntegrity || (nextBlock.HasDeformation || nextBlock.MaxDeformation > 0.0001f)) { break; } } //we weren't able to find a suitable block somehow, so skip this welder for now if (nextBlock == null) { continue; } //we found a block to pair with our welder, add it to the dictionary and carry on with destruction shipyardItem.ProcessBlocks.Add(welder.EntityId, nextBlock); } } if (shipyardItem.ProcessBlocks.Count < 1) { //No more blocks to weld return(false); } Wrapper.GameAction(() => { foreach (IMyCubeBlock welderBlock in shipyardItem.Tools) { var welder = (IMyShipWelder)welderBlock; var welderInventory = (MyInventory)welder.GetInventory(0); MySlimBlock block; shipyardItem.ProcessBlocks.TryGetValue(welderBlock.EntityId, out block); if (block?.CubeGrid?.Physics == null) { continue; } if (!(!block.IsFullIntegrity || (block.HasDeformation || block.MaxDeformation > 0.0001f))) { shipyardItem.ProcessBlocks.Remove(welder.EntityId); continue; } block.GetMissingComponents(missingComponents); foreach (KeyValuePair <string, int> component in missingComponents) { var componentId = new MyDefinitionId(typeof(MyObjectBuilder_Component), component.Key); int amount = Math.Max(component.Value - (int)welderInventory.GetItemAmount(componentId), 0); if (amount == 0) { continue; } if (welder.UseConveyorSystem) { MyGridConveyorSystem.ItemPullRequest((IMyConveyorEndpointBlock)welder, welderInventory, welder.OwnerId, componentId, component.Value); } } block.MoveItemsToConstructionStockpile((MyInventory)welder.GetInventory(0)); block.IncreaseMountLevel(weldAmount, 0, null, boneAmount, true); if (!block.CanContinueBuild((MyInventory)welder.GetInventory(0)) && !block.IsFullIntegrity) { stalledWelders.Add(welder.EntityId); } } }); foreach (var tool in shipyardItem.Tools) { MySlimBlock targetBlock; Communication.MessageStruct message = new Communication.MessageStruct() { toolId = tool.EntityId, gridId = 0, blockPos = new SerializableVector3I(), packedColor = 0 }; if (!shipyardItem.ProcessBlocks.TryGetValue(tool.EntityId, out targetBlock)) { Communication.SendLine(message); continue; } message.gridId = targetBlock.CubeGrid.EntityId; message.blockPos = targetBlock.Position; if (stalledWelders.Contains(tool.EntityId)) { message.packedColor = Color.Purple.PackedValue; message.pulse = true; } else { message.packedColor = Color.DarkCyan.PackedValue; message.pulse = false; } Communication.SendLine(message); } return(true); }