/// <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);
        }
Beispiel #8
0
        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;
        }
Beispiel #10
0
        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 });
                }
            }
        }
Beispiel #11
0
 public ProjectionRaycastData(MyProjectorBase.BuildCheckResult result, MySlimBlock cubeBlock, MyProjectorBase projector)
 {
     raycastResult = result;
     hitCube       = cubeBlock;
     cubeProjector = projector;
 }
Beispiel #12
0
        /// <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);
        }
Beispiel #15
0
        /// <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);
        }
Beispiel #16
0
 public MyProjectorClipboard(MyProjectorBase projector, MyPlacementSettings settings) : base(settings, true)
 {
     this.m_projector         = projector;
     base.m_calculateVelocity = false;
 }
Beispiel #17
0
        /// <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);
        }
Beispiel #18
0
        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);
        }
Beispiel #19
0
        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);
        }