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 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); }