private void OnChangePlayerModeMessage(IPlayer fromPlayer, ChangePlayerModePacket plrmode) { IServerPlayer plr = fromPlayer as IServerPlayer; bool freeMoveAllowed = plr.HasPrivilege(Privilege.freemove); bool gameModeAllowed = plr.HasPrivilege(Privilege.gamemode); bool pickRangeAllowed = plr.HasPrivilege(Privilege.pickingrange); if (plrmode.axisLock != null) { fromPlayer.WorldData.FreeMovePlaneLock = (EnumFreeMovAxisLock)plrmode.axisLock; } if (plrmode.pickingRange != null && pickRangeAllowed) { fromPlayer.WorldData.PickingRange = (float)plrmode.pickingRange; } if (plrmode.fly != null) { fromPlayer.WorldData.FreeMove = (bool)plrmode.fly && freeMoveAllowed; } if (plrmode.noclip != null) { fromPlayer.WorldData.NoClip = (bool)plrmode.noclip && freeMoveAllowed; } }
public void GiveKit(IServerPlayer player, string kitName) { var kit = GetLoadedKits().kits.Find( x => x.name == kitName ); if (kit != null) { if (!player.HasPrivilege(Privilege.ignoreCooldowns)) { var cooldown = GetCooldownManager().GetCooldown(player.PlayerUID, kitName); if (cooldown > 0) { player.SendErr($"You must wait {cooldown} sec. to use this kit"); return; } } if (!player.HasPrivilege($"{Privilege.kit}.{kit.name}")) { player.SendErr($"You don't have access to kit {kit.name}"); return; } player.SendOk($"Giving kit {kit.name}"); // TODO: if inventory full, should use player.Entity.World.SpawnItemEntity(); kit.items.ForEach( item => player.GiveItemStack(item.type, item.code, item.amount) ); GetCooldownManager().SetCooldown(player.PlayerUID, kitName, kit.delay); } else { player.SendErr($"{kitName} not found"); } }
public List <string> GetAccessedKits(IServerPlayer player) { return(GetLoadedKits() .kits .Where(kit => player.HasPrivilege($"{Privilege.kit}.{kit.name}")) .Select(kit => kit.name) .ToList()); }
private void impactOnEntity(Entity entity) { if (!Alive) { return; } EntityPos pos = SidedPos; IServerPlayer fromPlayer = null; if (FiredBy is EntityPlayer) { fromPlayer = (FiredBy as EntityPlayer).Player as IServerPlayer; } bool targetIsPlayer = entity is EntityPlayer; bool targetIsCreature = entity is EntityAgent; bool canDamage = true; ICoreServerAPI sapi = World.Api as ICoreServerAPI; if (fromPlayer != null) { if (targetIsPlayer && (!sapi.Server.Config.AllowPvP || !fromPlayer.HasPrivilege("attackplayers"))) { canDamage = false; } if (targetIsCreature && !fromPlayer.HasPrivilege("attackcreatures")) { canDamage = false; } } msCollide = World.ElapsedMilliseconds; World.PlaySoundAt(new AssetLocation("sounds/arrow-impact"), this, null, false, 24); if (canDamage) { float dmg = Damage; dmg *= FiredBy.Stats.GetBlended("rangedWeaponsDamage"); bool didDamage = entity.ReceiveDamage(new DamageSource() { Source = EnumDamageSource.Entity, SourceEntity = FiredBy == null ? this : FiredBy, Type = EnumDamageType.PiercingAttack }, dmg); float kbresist = entity.Properties.KnockbackResistance; entity.SidedPos.Motion.Add(kbresist * pos.Motion.X * Weight, kbresist * pos.Motion.Y * Weight, kbresist * pos.Motion.Z * Weight); int leftDurability = ProjectileStack == null ? 1 : ProjectileStack.Attributes.GetInt("durability", 1); if (World.Rand.NextDouble() < DropOnImpactChance && leftDurability > 0) { pos.Motion.Set(0, 0, 0); } else { Die(); } if (FiredBy is EntityPlayer && didDamage) { World.PlaySoundFor(new AssetLocation("sounds/player/projectilehit"), (FiredBy as EntityPlayer).Player, false, 24); } } else { pos.Motion.Set(0, 0, 0); } }
private void CmdEditServer(IServerPlayer player, int groupId, CmdArgs args) { this.fromPlayer = player; this.groupId = groupId; if (!CanUseWorldEdit(player, true)) { return; } this.workspace = GetOrCreateWorkSpace(player); BlockPos centerPos = player.Entity.Pos.AsBlockPos; IPlayerInventoryManager plrInv = player.InventoryManager; ItemStack stack = plrInv.ActiveHotbarSlot.Itemstack; if (args.Length == 0) { Bad("No arguments supplied. Check the wiki for help, or did you mean to type .we?"); return; } string cmd = args.PopWord(); if ((cmd == "tr" || cmd == "tsx" || cmd == "tsy" || cmd == "tsz") && args.Length > 0) { double val = 0; if (double.TryParse(args[0], NumberStyles.Any, GlobalConstants.DefaultCultureInfo, out val)) { if (val > 50 && workspace.serverOverloadProtection) { Bad("Operation rejected. Server overload protection is on. Might kill the server or client to use such a large brush (max is 50)."); SendPlayerWorkSpace(fromPlayer.PlayerUID); return; } } } switch (cmd) { case "impr": int angle = 90; if (args.Length > 0) { if (!int.TryParse(args[0], NumberStyles.Any, GlobalConstants.DefaultCultureInfo, out angle)) { Bad("Invalid Angle (not a number)"); break; } } if (angle < 0) { angle += 360; } if (angle != 0 && angle != 90 && angle != 180 && angle != 270) { Bad("Invalid Angle, allowed values are -270, -180, -90, 0, 90, 180 and 270"); break; } workspace.ImportAngle = angle; Good("Ok, set rotation to " + angle + " degrees"); break; case "impflip": workspace.ImportFlipped = !workspace.ImportFlipped; Good("Ok, import data flip " + (workspace.ImportFlipped ? "on" : "off")); break; case "mcopy": if (workspace.StartMarker == null || workspace.EndMarker == null) { Bad("Please mark start and end position"); break; } workspace.clipboardBlockData = CopyArea(workspace.StartMarker, workspace.EndMarker); Good(Lang.Get("{0} blocks and {1} entities copied", workspace.clipboardBlockData.BlockIds.Count, workspace.clipboardBlockData.EntitiesUnpacked.Count)); break; case "mposcopy": if (workspace.StartMarker == null || workspace.EndMarker == null) { Bad("Please mark start and end position"); break; } BlockPos s = workspace.StartMarker; BlockPos e = workspace.EndMarker; serverChannel.SendPacket(new CopyToClipboardPacket() { Text = string.Format("/we mark {0} {1} {2} {3} {4} {5}", s.X, s.Y, s.Z, e.X, e.Y, e.Z) }, player); break; case "mpaste": if (workspace.clipboardBlockData == null) { Bad("No copied block data to paste"); break; } PasteBlockData(workspace.clipboardBlockData, workspace.StartMarker, EnumOrigin.StartPos); Good(workspace.clipboardBlockData.BlockIds.Count + " blocks pasted"); break; case "cpinfo": if (workspace.clipboardBlockData == null) { Bad("No schematic in the clipboard"); break; } workspace.clipboardBlockData.Init(workspace.revertableBlockAccess); workspace.clipboardBlockData.LoadMetaInformationAndValidate(workspace.revertableBlockAccess, workspace.world, "(from clipboard)"); string sides = ""; for (int i = 0; i < workspace.clipboardBlockData.PathwayStarts.Length; i++) { if (sides.Length > 0) { sides += ","; } sides += workspace.clipboardBlockData.PathwaySides[i].Code + " (" + workspace.clipboardBlockData.PathwayOffsets[i].Length + " blocks)"; } if (sides.Length > 0) { sides = "Found " + workspace.clipboardBlockData.PathwayStarts.Length + " pathways: " + sides; } Good("{0} blocks in clipboard. {1}", workspace.clipboardBlockData.BlockIds.Count, sides); break; case "block": if (stack == null || stack.Class == EnumItemClass.Item) { Bad("Please put the desired block in your active hotbar slot"); return; } sapi.World.BlockAccessor.SetBlock(stack.Id, centerPos.DownCopy()); Good("Block placed"); break; case "relight": workspace.DoRelight = (bool)args.PopBool(true); workspace.revertableBlockAccess.Relight = workspace.DoRelight; Good("Block relighting now " + ((workspace.DoRelight) ? "on" : "off")); break; case "sovp": if (args.Length > 0) { if (!fromPlayer.HasPrivilege(Privilege.controlserver)) { Bad("controlserver privilege required to change server overload protection flag"); break; } workspace.serverOverloadProtection = (bool)args.PopBool(true); } Good("Server overload protection " + (workspace.serverOverloadProtection ? "on" : "off")); break; case "undo": HandleHistoryChange(args, false); break; case "redo": HandleHistoryChange(args, true); break; case "on": Good("World edit tools now enabled"); workspace.ToolsEnabled = true; workspace.ResendBlockHighlights(this); break; case "off": Good("World edit tools now disabled"); workspace.ToolsEnabled = false; workspace.ResendBlockHighlights(this); break; case "rebuildrainmap": if (!player.HasPrivilege(Privilege.controlserver)) { Bad("You lack the controlserver privilege to rebuild the rain map."); return; } Good("Ok, rebuilding rain map on all loaded chunks, this may take some time and lag the server"); int rebuilt = RebuildRainMap(); Good("Done, rebuilding {0} map chunks", rebuilt); break; case "t": string toolname = null; string suppliedToolname = args.PopAll(); if (suppliedToolname.Length > 0) { int toolId; if (int.TryParse(suppliedToolname, NumberStyles.Any, GlobalConstants.DefaultCultureInfo, out toolId)) { if (toolId < 0) { Good("World edit tools now disabled"); workspace.ToolsEnabled = false; workspace.ResendBlockHighlights(this); return; } toolname = ToolRegistry.ToolTypes.GetKeyAtIndex(toolId); } else { foreach (string name in ToolRegistry.ToolTypes.Keys) { if (name.ToLowerInvariant().StartsWith(suppliedToolname.ToLowerInvariant())) { toolname = name; break; } } } } if (toolname == null) { Bad("No such tool '" + suppliedToolname + "' registered"); break; } workspace.SetTool(toolname); Good(toolname + " tool selected"); workspace.ToolsEnabled = true; workspace.ResendBlockHighlights(this); SendPlayerWorkSpace(fromPlayer.PlayerUID); break; case "tom": EnumToolOffsetMode mode = EnumToolOffsetMode.Center; try { int index = 0; if (args.Length > 0) { index = args[0].ToInt(0); } mode = (EnumToolOffsetMode)index; } catch (Exception) { } workspace.ToolOffsetMode = mode; Good("Set tool offset mode " + mode); workspace.ResendBlockHighlights(this); break; case "range": float pickingrange = GlobalConstants.DefaultPickingRange; if (args.Length > 0) { pickingrange = args[0].ToFloat(GlobalConstants.DefaultPickingRange); } fromPlayer.WorldData.PickingRange = pickingrange; fromPlayer.BroadcastPlayerData(); Good("Picking range " + pickingrange + " set"); break; case "mex": case "mexc": if (workspace.StartMarker == null || workspace.EndMarker == null) { Bad("Please mark start and end position"); break; } if (args.Length < 1) { Bad("Please provide a filename"); break; } ExportArea(args[0], workspace.StartMarker, workspace.EndMarker, cmd == "mexc" ? fromPlayer : null); if (args.Length > 1 && args[1] == "c") { BlockPos st = workspace.StartMarker; BlockPos en = workspace.EndMarker; serverChannel.SendPacket(new CopyToClipboardPacket() { Text = string.Format("/we mark {0} {1} {2} {3} {4} {5}\n/we mex {6}", st.X, st.Y, st.Z, en.X, en.Y, en.Z, args[0]) }, player); } break; case "mre": if (workspace.StartMarker == null || workspace.EndMarker == null) { Bad("Please mark start and end position"); break; } Good("Relighting marked area, this may lag the server for a while..."); sapi.WorldManager.FullRelight(workspace.StartMarker, workspace.EndMarker); Good("Ok, relighting complete"); break; case "mgencode": if (workspace.StartMarker == null || workspace.EndMarker == null) { Bad("Please mark start and end position"); break; } if (player.CurrentBlockSelection == null) { Bad("Please look at a block as well"); break; } GenMarkedMultiblockCode(player); break; case "imp": if (workspace.StartMarker == null) { Bad("Please mark a start position"); break; } if (args.Length < 1) { Bad("Please provide a filename"); break; } EnumOrigin origin = EnumOrigin.StartPos; if (args.Length > 1) { try { origin = (EnumOrigin)Enum.Parse(typeof(EnumOrigin), args[1]); } catch (Exception) { } } ImportArea(args[0], workspace.StartMarker, origin); break; case "impres": if (args.Length == 0) { Good("Import item/block resolving currently " + (!sapi.ObjectCache.ContainsKey("donotResolveImports") || (bool)sapi.ObjectCache["donotResolveImports"] == false ? "on" : "off")); } else { bool doreplace = (bool)args.PopBool(ReplaceMetaBlocks); sapi.ObjectCache["donotResolveImports"] = !doreplace; Good("Import item/block resolving now globally " + (doreplace ? "on" : "off")); } break; case "blu": BlockLineup(centerPos, args); Good("Block lineup created"); break; // Mark start case "ms": SetStartPos(centerPos); break; // Mark end case "me": SetEndPos(centerPos); break; case "mark": workspace.StartMarker = args.PopVec3i(null)?.AsBlockPos; workspace.EndMarker = args.PopVec3i(null)?.AsBlockPos; Good("Start and end position marked"); EnsureInsideMap(workspace.EndMarker); workspace.HighlightSelectedArea(); break; case "gn": ModifyMarker(BlockFacing.NORTH, args); break; case "ge": ModifyMarker(BlockFacing.EAST, args); break; case "gs": ModifyMarker(BlockFacing.SOUTH, args); break; case "gw": ModifyMarker(BlockFacing.WEST, args); break; case "gu": ModifyMarker(BlockFacing.UP, args); break; case "gd": ModifyMarker(BlockFacing.DOWN, args); break; case "mr": HandleRotateCommand(args.PopInt(), args.PopWord()); break; case "mmirn": HandleMirrorCommand(BlockFacing.NORTH, args); break; case "mmire": HandleMirrorCommand(BlockFacing.EAST, args); break; case "mmirs": HandleMirrorCommand(BlockFacing.SOUTH, args); break; case "mmirw": HandleMirrorCommand(BlockFacing.WEST, args); break; case "mmiru": HandleMirrorCommand(BlockFacing.UP, args); break; case "mmird": HandleMirrorCommand(BlockFacing.DOWN, args); break; case "mrepn": HandleRepeatCommand(BlockFacing.NORTH, args); break; case "mrepe": HandleRepeatCommand(BlockFacing.EAST, args); break; case "mreps": HandleRepeatCommand(BlockFacing.SOUTH, args); break; case "mrepw": HandleRepeatCommand(BlockFacing.WEST, args); break; case "mrepu": HandleRepeatCommand(BlockFacing.UP, args); break; case "mrepd": HandleRepeatCommand(BlockFacing.DOWN, args); break; case "mmu": HandleMoveCommand(BlockFacing.UP, args); break; case "mmd": HandleMoveCommand(BlockFacing.DOWN, args); break; case "mmn": HandleMoveCommand(BlockFacing.NORTH, args); break; case "mme": HandleMoveCommand(BlockFacing.EAST, args); break; case "mms": HandleMoveCommand(BlockFacing.SOUTH, args); break; case "mmw": HandleMoveCommand(BlockFacing.WEST, args); break; case "mmby": HandleMoveCommand(null, args); break; case "smu": HandleShiftCommand(BlockFacing.UP, args); break; case "smd": HandleShiftCommand(BlockFacing.DOWN, args); break; case "smn": HandleShiftCommand(BlockFacing.NORTH, args); break; case "sme": HandleShiftCommand(BlockFacing.EAST, args); break; case "sms": HandleShiftCommand(BlockFacing.SOUTH, args); break; case "smw": HandleShiftCommand(BlockFacing.WEST, args); break; case "smby": HandleShiftCommand(null, args); break; // Marked clear case "mc": case "clear": workspace.StartMarker = null; workspace.EndMarker = null; Good("Marked positions cleared"); workspace.ResendBlockHighlights(this); break; // Marked info case "minfo": int sizeX = Math.Abs(workspace.StartMarker.X - workspace.EndMarker.X); int sizeY = Math.Abs(workspace.StartMarker.Y - workspace.EndMarker.Y); int sizeZ = Math.Abs(workspace.StartMarker.Z - workspace.EndMarker.Z); Good(string.Format("Marked area is a cuboid of size {0}x{1}x{2} or a total of {3:n0} blocks", sizeX, sizeY, sizeZ, ((long)sizeX * sizeY * sizeZ))); break; // Fill marked case "mfill": if (workspace.StartMarker == null || workspace.EndMarker == null) { Bad("Start marker or end marker not set"); return; } if (stack == null || stack.Class == EnumItemClass.Item) { Bad("Please put the desired block in your active hotbar slot"); return; } int filled = FillArea(stack, workspace.StartMarker, workspace.EndMarker); Good(filled + " marked blocks placed"); break; case "mclear": { Bad("No such function, did you mean mdelete?"); return; } // Clear marked case "mdelete": { if (workspace.StartMarker == null || workspace.EndMarker == null) { Bad("Start marker or end marker not set"); return; } int cleared = FillArea(null, workspace.StartMarker, workspace.EndMarker); Good(cleared + " marked blocks removed"); } break; // Clear area case "delete": { if (args.Length < 1) { Bad("Missing size param"); return; } int size = 0; if (!int.TryParse(args[0], NumberStyles.Any, GlobalConstants.DefaultCultureInfo, out size)) { Bad("Invalide size param"); return; } int height = 20; if (args.Length > 1) { int.TryParse(args[1], NumberStyles.Any, GlobalConstants.DefaultCultureInfo, out height); } int cleared = FillArea(null, centerPos.AddCopy(-size, 0, -size), centerPos.AddCopy(size, height, size)); Good(cleared + " Blocks removed"); } break; default: args.PushSingle(cmd); if (workspace.ToolInstance == null || !workspace.ToolInstance.OnWorldEditCommand(this, args)) { Bad("No such function " + cmd + ". Maybe wrong tool selected?"); } break; } }
/// <summary> /// Whether or not the player has the privilage to run the command. /// </summary> /// <param name="player"></param> /// <returns></returns> public bool HasPrivilege(IServerPlayer player) { return(player.HasPrivilege(RequiredPrivilege)); }
bool TryAttackEntity(double impactSpeed) { if (World is IClientWorldAccessor || World.ElapsedMilliseconds <= msCollide + 250) { return(false); } if (impactSpeed <= 0.01) { return(false); } EntityPos pos = LocalPos; Cuboidd projectileBox = CollisionBox.ToDouble().Translate(ServerPos.X, ServerPos.Y, ServerPos.Z); // We give it a bit of extra leeway of 50% because physics ticks can run twice or 3 times in one game tick if (ServerPos.Motion.X < 0) { projectileBox.X1 += 1.5 * ServerPos.Motion.X; } else { projectileBox.X2 += 1.5 * ServerPos.Motion.X; } if (ServerPos.Motion.Y < 0) { projectileBox.Y1 += 1.5 * ServerPos.Motion.Y; } else { projectileBox.Y2 += 1.5 * ServerPos.Motion.Y; } if (ServerPos.Motion.Z < 0) { projectileBox.Z1 += 1.5 * ServerPos.Motion.Z; } else { projectileBox.Z2 += 1.5 * ServerPos.Motion.Z; } Entity entity = World.GetNearestEntity(ServerPos.XYZ, 5f, 5f, (e) => { if (e.EntityId == this.EntityId || !e.IsInteractable) { return(false); } if (FiredBy != null && e.EntityId == FiredBy.EntityId && World.ElapsedMilliseconds - msLaunch < 500) { return(false); } Cuboidd eBox = e.CollisionBox.ToDouble().Translate(e.ServerPos.X, e.ServerPos.Y, e.ServerPos.Z); return(eBox.IntersectsOrTouches(projectileBox)); }); if (entity != null) { IServerPlayer fromPlayer = null; if (FiredBy is EntityPlayer) { fromPlayer = (FiredBy as EntityPlayer).Player as IServerPlayer; } bool targetIsPlayer = entity is EntityPlayer; bool targetIsCreature = entity is EntityAgent; bool canDamage = true; ICoreServerAPI sapi = World.Api as ICoreServerAPI; if (fromPlayer != null) { if (targetIsPlayer && (!sapi.Server.Config.AllowPvP || !fromPlayer.HasPrivilege("attackplayers"))) { canDamage = false; } if (targetIsCreature && !fromPlayer.HasPrivilege("attackcreatures")) { canDamage = false; } } msCollide = World.ElapsedMilliseconds; World.PlaySoundAt(new AssetLocation("sounds/arrow-impact"), this, null, false, 24); if (canDamage) { bool didDamage = entity.ReceiveDamage(new DamageSource() { Source = EnumDamageSource.Entity, SourceEntity = FiredBy == null ? this : FiredBy, Type = EnumDamageType.PiercingAttack }, Damage); float kbresist = entity.Properties.KnockbackResistance; entity.LocalPos.Motion.Add(kbresist * pos.Motion.X * Weight, kbresist * pos.Motion.Y * Weight, kbresist * pos.Motion.Z * Weight); int leftDurability = ProjectileStack == null ? 1 : ProjectileStack.Attributes.GetInt("durability", 1); if (World.Rand.NextDouble() < DropOnImpactChance && leftDurability > 0) { pos.Motion.Set(0, 0, 0); } else { Die(); } if (FiredBy is EntityPlayer && didDamage) { World.PlaySoundFor(new AssetLocation("sounds/player/projectilehit"), (FiredBy as EntityPlayer).Player, false, 24); } } else { pos.Motion.Set(0, 0, 0); } return(true); } return(false); }