diff --git a/Minecraft.World/Commands/Command.cpp b/Minecraft.World/Commands/Command.cpp index 8da161daa..16cc7a5fd 100644 --- a/Minecraft.World/Commands/Command.cpp +++ b/Minecraft.World/Commands/Command.cpp @@ -7,6 +7,8 @@ AdminLogCommand* Command::logger; +int Command::getPermissionLevel() { return LEVEL_OWNERS; } + bool Command::canExecute(std::shared_ptr source) { return source->hasPermission(getId()); } @@ -40,4 +42,4 @@ std::shared_ptr Command::getPlayer(PlayerUID playerId) { } else { return player; } -} +} \ No newline at end of file diff --git a/Minecraft.World/Commands/Command.h b/Minecraft.World/Commands/Command.h index 4667f6cec..6a8fb5220 100644 --- a/Minecraft.World/Commands/Command.h +++ b/Minecraft.World/Commands/Command.h @@ -10,11 +10,24 @@ class CommandSender; class ServerPlayer; class Command { +public: + // commands such as "help" and "emote" + static const int LEVEL_ALL = 0; + // commands such as "mute" + static const int LEVEL_MODERATORS = 1; + // commands such as "seed", "tp", "spawnpoint" and "give" + static const int LEVEL_GAMEMASTERS = 2; + // commands such as "whitelist", "ban", etc + static const int LEVEL_ADMINS = 3; + // commands such as "stop", "save-all", etc + static const int LEVEL_OWNERS = 4; + private: static AdminLogCommand* logger; public: virtual EGameCommand getId() = 0; + virtual int getPermissionLevel(); virtual void execute(std::shared_ptr source, byteArray commandData) = 0; virtual bool canExecute(std::shared_ptr source); diff --git a/Minecraft.World/Commands/CommandDispatcher.cpp b/Minecraft.World/Commands/CommandDispatcher.cpp index 499391256..7e8d60b0a 100644 --- a/Minecraft.World/Commands/CommandDispatcher.cpp +++ b/Minecraft.World/Commands/CommandDispatcher.cpp @@ -2,9 +2,9 @@ #include "../Headers/net.minecraft.commands.h" #include "CommandDispatcher.h" -void CommandDispatcher::performCommand(std::shared_ptr sender, - EGameCommand command, - byteArray commandData) { +int CommandDispatcher::performCommand(std::shared_ptr sender, + EGameCommand command, + byteArray commandData) { AUTO_VAR(it, commandsById.find(command)); if (it != commandsById.end()) { @@ -20,10 +20,12 @@ void CommandDispatcher::performCommand(std::shared_ptr sender, } else { app.DebugPrintf("Command %d not found!\n", command); } + + return 0; } Command* CommandDispatcher::addCommand(Command* command) { commandsById[command->getId()] = command; commands.insert(command); return command; -} +} \ No newline at end of file diff --git a/Minecraft.World/Commands/CommandDispatcher.h b/Minecraft.World/Commands/CommandDispatcher.h index b84d37513..82019d213 100644 --- a/Minecraft.World/Commands/CommandDispatcher.h +++ b/Minecraft.World/Commands/CommandDispatcher.h @@ -13,7 +13,7 @@ private: std::unordered_set commands; public: - void performCommand(std::shared_ptr sender, - EGameCommand command, byteArray commandData); + int performCommand(std::shared_ptr sender, + EGameCommand command, byteArray commandData); Command* addCommand(Command* command); }; \ No newline at end of file diff --git a/Minecraft.World/Commands/CommandsEnum.h b/Minecraft.World/Commands/CommandsEnum.h index 3c86dd80e..0d3eeeafb 100644 --- a/Minecraft.World/Commands/CommandsEnum.h +++ b/Minecraft.World/Commands/CommandsEnum.h @@ -2,6 +2,7 @@ enum EGameCommand { eGameCommand_DefaultGameMode, + eGameCommand_Effect, eGameCommand_EnchantItem, eGameCommand_Experience, eGameCommand_GameMode, diff --git a/Minecraft.World/Commands/DefaultGameModeCommand.cpp b/Minecraft.World/Commands/DefaultGameModeCommand.cpp index 1ceae7732..b40001083 100644 --- a/Minecraft.World/Commands/DefaultGameModeCommand.cpp +++ b/Minecraft.World/Commands/DefaultGameModeCommand.cpp @@ -8,17 +8,29 @@ EGameCommand DefaultGameModeCommand::getId() { void DefaultGameModeCommand::execute(std::shared_ptr source, byteArray commandData) { - // if (args.length > 0) - //{ + // if (args.length > 0) { // GameType newMode = getModeForString(source, args[0]); // doSetGameType(newMode); - // String modeName = I18n.get("gameMode." + newMode.getName()); - // logAdminAction(source, "commands.defaultgamemode.success", modeName); + // logAdminAction(source, "commands.defaultgamemode.success", + // ChatMessageComponent.forTranslation("gameMode." + newMode.getName())); + // return; //} + + // throw new UsageException("commands.defaultgamemode.usage"); } void DefaultGameModeCommand::doSetGameType(GameType* newGameType) { - // MinecraftServer::getInstance()->setDefaultGameMode(newGameType); + // MinecraftServer minecraftServer = MinecraftServer.getInstance(); + // minecraftServer.setDefaultGameMode(newGameType); + + // if (minecraftServer.getForceGameType()) { + // for (ServerPlayer player : + // MinecraftServer.getInstance().getPlayers().players) { + // player.setGameMode(newGameType); + // player.fallDistance = 0; // reset falldistance so flying people + // do not die :P + // } + // } } \ No newline at end of file diff --git a/Minecraft.World/Commands/EffectCommand.cpp b/Minecraft.World/Commands/EffectCommand.cpp new file mode 100644 index 000000000..890e03d66 --- /dev/null +++ b/Minecraft.World/Commands/EffectCommand.cpp @@ -0,0 +1,88 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.commands.common.h" +#include "../../Minecraft.Client/MinecraftServer.h" + +EGameCommand EffectCommand::getId() { return eGameCommand_Effect; } + +int EffectCommand::getPermissionLevel() { return LEVEL_GAMEMASTERS; } + +std::wstring EffectCommand::getUsage(CommandSender* source) { + return L"commands.effect.usage"; +} + +void EffectCommand::execute(std::shared_ptr source, + byteArray commandData) { + // if (args.length >= 2) + //{ + // Player player = convertToPlayer(source, args[0]); + + // if (args[1].equals("clear")) { + // if (player.getActiveEffects().isEmpty()) { + // throw new + // CommandException("commands.effect.failure.notActive.all", + // player.getAName()); } else { + // player.removeAllEffects(); logAdminAction(source, + //"commands.effect.success.removed.all", player.getAName()); + // } + // } else { + // int effectId = convertArgToInt(source, args[1], 1); + // int duration = SharedConstants.TICKS_PER_SECOND * 30; + // int seconds = 30; + // int amplifier = 0; + + // if (effectId < 0 || effectId >= MobEffect.effects.length || + // MobEffect.effects[effectId] == null) { throw new + // InvalidNumberException("commands.effect.notFound", effectId); + // } + + // if (args.length >= 3) { + // seconds = convertArgToInt(source, args[2], 0, 1000000); + // if (MobEffect.effects[effectId].isInstantenous()) { + // duration = seconds; + // } else { + // duration = seconds * + // SharedConstants.TICKS_PER_SECOND; + // } + // } else if (MobEffect.effects[effectId].isInstantenous()) { + // duration = 1; + // } + + // if (args.length >= 4) { + // amplifier = convertArgToInt(source, args[3], 0, 255); + // } + + // if (seconds == 0) { + // if (player.hasEffect(effectId)) { + // player.removeEffect(effectId); + // logAdminAction(source, + //"commands.effect.success.removed", + // ChatMessageComponent.forTranslation(MobEffect.effects[effectId].getDescriptionId()), + // player.getAName()); } else { + // throw new CommandException("commands.effect.failure.notActive", + // ChatMessageComponent.forTranslation(MobEffect.effects[effectId].getDescriptionId()), + // player.getAName()); + // } + // } else { + // MobEffectInstance instance = new + // MobEffectInstance(effectId, duration, amplifier); + // player.addEffect(instance); + // logAdminAction(source, "commands.effect.success", + // ChatMessageComponent.forTranslation(instance.getDescriptionId()), + // effectId, amplifier, player.getAName(), seconds); + // } + // } + + // return; + //} + + // throw new UsageException("commands.effect.usage"); +} + +std::wstring EffectCommand::getPlayerNames() { + return L""; // MinecraftServer::getInstance()->getPlayerNames(); +} + +bool EffectCommand::isValidWildcardPlayerArgument(std::wstring args, + int argumentIndex) { + return argumentIndex == 0; +} \ No newline at end of file diff --git a/Minecraft.World/Commands/EffectCommand.h b/Minecraft.World/Commands/EffectCommand.h new file mode 100644 index 000000000..71842af45 --- /dev/null +++ b/Minecraft.World/Commands/EffectCommand.h @@ -0,0 +1,17 @@ +#pragma once + +#include "Command.h" + +class EffectCommand : public Command { +public: + EGameCommand getId(); + int getPermissionLevel(); + std::wstring getUsage(CommandSender* source); + void execute(std::shared_ptr source, byteArray commandData); + +protected: + std::wstring getPlayerNames(); + +public: + bool isValidWildcardPlayerArgument(std::wstring args, int argumentIndex); +}; \ No newline at end of file diff --git a/Minecraft.World/Commands/EnchantItemCommand.cpp b/Minecraft.World/Commands/EnchantItemCommand.cpp index 9de07abb5..7fd8a14c2 100644 --- a/Minecraft.World/Commands/EnchantItemCommand.cpp +++ b/Minecraft.World/Commands/EnchantItemCommand.cpp @@ -7,9 +7,7 @@ EGameCommand EnchantItemCommand::getId() { return eGameCommand_EnchantItem; } -int EnchantItemCommand::getPermissionLevel() { - return 0; // aLEVEL_GAMEMASTERS; -} +int EnchantItemCommand::getPermissionLevel() { return LEVEL_GAMEMASTERS; } void EnchantItemCommand::execute(std::shared_ptr source, byteArray commandData) { @@ -82,4 +80,4 @@ std::shared_ptr EnchantItemCommand::preparePacket( return std::shared_ptr( new GameCommandPacket(eGameCommand_EnchantItem, baos.toByteArray())); -} +} \ No newline at end of file diff --git a/Minecraft.World/Commands/ExperienceCommand.cpp b/Minecraft.World/Commands/ExperienceCommand.cpp index 73fd19ed8..3ccf5012e 100644 --- a/Minecraft.World/Commands/ExperienceCommand.cpp +++ b/Minecraft.World/Commands/ExperienceCommand.cpp @@ -2,38 +2,56 @@ #include "../Headers/net.minecraft.commands.h" #include "../../Minecraft.Client/MinecraftServer.h" #include "../../Minecraft.Client/Network/PlayerList.h" +#include "../Headers/net.minecraft.world.level.h" #include "ExperienceCommand.h" EGameCommand ExperienceCommand::getId() { return eGameCommand_Experience; } +int ExperienceCommand::getPermissionLevel() { return LEVEL_GAMEMASTERS; } + void ExperienceCommand::execute(std::shared_ptr source, byteArray commandData) { - // if (args.length > 0) - //{ - // Player player; - // int amount = convertArgToInt(source, args[0], 0, 5000); - - // if (args.length > 1) { - // player = getPlayer(args[1]); - // } else { - // player = convertSourceToPlayer(source); + // if (args.length > 0) { + // Player player; + // String inputAmount = args[0]; + // + // boolean levels = inputAmount.endsWith("l") || + // inputAmount.endsWith("L"); if (levels && + // inputAmount.length() > 1) inputAmount = inputAmount.substring(0, + // inputAmount.length() - 1); + // + // int amount = convertArgToInt(source, inputAmount); + // boolean take = amount < 0; + // + // if (take) amount *= -1; + // + // if (args.length > 1) { + // player = convertToPlayer(source, args[1]); + // } else { + // player = convertSourceToPlayer(source); + // } + // + // if (levels) { + // if (take) { + // player.giveExperienceLevels(-amount); + // logAdminAction(source, + //"commands.xp.success.negative.levels", amount, player.getAName()); + //} else { player.giveExperienceLevels(amount); + // logAdminAction(source, "commands.xp.success.levels", amount, + // player.getAName()); + // } + // } else { + // if (take) { + // throw new + // UsageException("commands.xp.failure.widthdrawXp"); + // } else { player.increaseXp(amount); + // logAdminAction(source, + //"commands.xp.success", amount, player.getAName()); + // } + // } + // + // return; // } - - // player.increaseXp(amount); - // logAdminAction(source, "commands.xp.success", amount, - //player.getAName()); - //} -} - -std::shared_ptr ExperienceCommand::getPlayer(PlayerUID playerId) { - return nullptr; - // std::shared_ptr player = - // MinecraftServer::getInstance()->getPlayers()->getPlayer(playerId); - - // if (player == null) - //{ - // throw new PlayerNotFoundException(); - // } else { - // return player; - // } -} + // + // throw new UsageException("commands.xp.usage"); +} \ No newline at end of file diff --git a/Minecraft.World/Commands/ExperienceCommand.h b/Minecraft.World/Commands/ExperienceCommand.h index 0f4564b94..4f41f03b1 100644 --- a/Minecraft.World/Commands/ExperienceCommand.h +++ b/Minecraft.World/Commands/ExperienceCommand.h @@ -7,9 +7,7 @@ class CommandSender; class ExperienceCommand : public Command { public: virtual EGameCommand getId(); + virtual int getPermissionLevel(); virtual void execute(std::shared_ptr source, byteArray commandData); - -protected: - std::shared_ptr getPlayer(PlayerUID playerId); }; \ No newline at end of file diff --git a/Minecraft.World/Commands/GameDifficultyCommand.h b/Minecraft.World/Commands/GameDifficultyCommand.h new file mode 100644 index 000000000..e268d689a --- /dev/null +++ b/Minecraft.World/Commands/GameDifficultyCommand.h @@ -0,0 +1,75 @@ +#pragma once +/* +package net.minecraft.commands.common; + +import java.util.List; + +import net.minecraft.commands.*; +import net.minecraft.commands.exceptions.UsageException; +import net.minecraft.locale.I18n; +import net.minecraft.network.chat.ChatMessageComponent; +import net.minecraft.server.MinecraftServer; + +public class GameDifficultyCommand extends BaseCommand { + + // note: copied from Options.java, move to shared location? + private static final String[] DIFFICULTY_NAMES = { + "options.difficulty.peaceful", "options.difficulty.easy", +"options.difficulty.normal", "options.difficulty.hard" + }; + + @Override + public String getName() { + return "difficulty"; + } + + @Override + public int getPermissionLevel() { + return LEVEL_GAMEMASTERS; + } + + + @Override + public String getUsage(CommandSender source) { + return "commands.difficulty.usage"; + } + + @Override + public void execute(CommandSender source, String[] args) { + if (args.length > 0) { + int newDiff = getDifficultyForString(source, args[0]); + + MinecraftServer.getInstance().setDifficulty(newDiff); + + logAdminAction(source, "commands.difficulty.success", +ChatMessageComponent.forTranslation(DIFFICULTY_NAMES[newDiff])); + + return; + } + + throw new UsageException("commands.difficulty.usage"); + } + + protected int getDifficultyForString(CommandSender source, String name) { + if (name.equalsIgnoreCase("peaceful") || name.equalsIgnoreCase("p")) { + return 0; + } else if (name.equalsIgnoreCase("easy") || name.equalsIgnoreCase("e")) +{ return 1; } else if (name.equalsIgnoreCase("normal") || +name.equalsIgnoreCase("n")) { return 2; } else if (name.equalsIgnoreCase("hard") +|| name.equalsIgnoreCase("h")) { return 3; } else { return +convertArgToInt(source, name, 0, 3); + } + } + + @Override + public List matchArguments(CommandSender source, String[] args) { + if (args.length == 1) { + return matchArguments(args, "peaceful", "easy", "normal", "hard"); + } + + return null; + } + +} + +*/ \ No newline at end of file diff --git a/Minecraft.World/Commands/GameModeCommand.cpp b/Minecraft.World/Commands/GameModeCommand.cpp index 9d8d208dd..631d1682f 100644 --- a/Minecraft.World/Commands/GameModeCommand.cpp +++ b/Minecraft.World/Commands/GameModeCommand.cpp @@ -4,27 +4,35 @@ EGameCommand GameModeCommand::getId() { return eGameCommand_GameMode; } +int GameModeCommand::getPermissionLevel() { return LEVEL_GAMEMASTERS; } + void GameModeCommand::execute(std::shared_ptr source, byteArray commandData) { - // if (args.length > 0) - //{ + // if (args.length > 0) { // GameType newMode = getModeForString(source, args[0]); - // Player player = args.length >= 2 ? getPlayer(args[1]) : - //convertSourceToPlayer(source); + // Player player = args.length >= 2 ? convertToPlayer(source, args[1]) : + // convertSourceToPlayer(source); // player.setGameMode(newMode); + // player.fallDistance = 0; // reset falldistance so flying people do not + // die :P - // String mode = I18n.get("gameMode." + newMode.getName()); + // ChatMessageComponent mode = + // ChatMessageComponent.forTranslation("gameMode." + newMode.getName()); // if (player != source) { // logAdminAction(source, - //AdminLogCommand.LOGTYPE_DONT_SHOW_TO_SELF, + // AdminLogCommand.LOGTYPE_DONT_SHOW_TO_SELF, //"commands.gamemode.success.other", player.getAName(), mode); } else { // logAdminAction(source, - //AdminLogCommand.LOGTYPE_DONT_SHOW_TO_SELF, + // AdminLogCommand.LOGTYPE_DONT_SHOW_TO_SELF, //"commands.gamemode.success.self", mode); // } + + // return; //} + + // throw new UsageException("commands.gamemode.usage"); } GameType* GameModeCommand::getModeForString( @@ -35,20 +43,9 @@ GameType* GameModeCommand::getModeForString( // (name.equalsIgnoreCase(GameType.CREATIVE.getName()) || // name.equalsIgnoreCase("c")) { return GameType.CREATIVE; } else if // (name.equalsIgnoreCase(GameType.ADVENTURE.getName()) || - // name.equalsIgnoreCase("a")) { return GameType.ADVENTURE; } else { return - //LevelSettings.validateGameType(convertArgToInt(source, name, 0, - //GameType.values().length - 2)); - // } -} - -std::shared_ptr GameModeCommand::getPlayer(PlayerUID playerId) { - return nullptr; - // Player player = - // MinecraftServer.getInstance().getPlayers().getPlayer(name); - - // if (player == null) { - // throw new PlayerNotFoundException(); - // } else { - // return player; + // name.equalsIgnoreCase("a")) { return GameType.ADVENTURE; } else { + // return + // LevelSettings.validateGameType(convertArgToInt(source, name, 0, + // GameType.values().length - 2)); // } } \ No newline at end of file diff --git a/Minecraft.World/Commands/GameModeCommand.h b/Minecraft.World/Commands/GameModeCommand.h index ef0c4c0cd..514cf1969 100644 --- a/Minecraft.World/Commands/GameModeCommand.h +++ b/Minecraft.World/Commands/GameModeCommand.h @@ -7,11 +7,11 @@ class GameType; class GameModeCommand : public Command { public: virtual EGameCommand getId(); + int getPermissionLevel(); virtual void execute(std::shared_ptr source, byteArray commandData); protected: GameType* getModeForString(std::shared_ptr source, const std::wstring& name); - std::shared_ptr getPlayer(PlayerUID playerId); }; \ No newline at end of file diff --git a/Minecraft.World/Commands/GameRuleCommand.h b/Minecraft.World/Commands/GameRuleCommand.h new file mode 100644 index 000000000..27baea538 --- /dev/null +++ b/Minecraft.World/Commands/GameRuleCommand.h @@ -0,0 +1,84 @@ +#pragma once +/* +package net.minecraft.commands.common; + +import net.minecraft.commands.BaseCommand; +import net.minecraft.commands.CommandSender; +import net.minecraft.commands.exceptions.UsageException; +import net.minecraft.network.chat.ChatMessageComponent; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.level.GameRules; + +import java.util.List; + +public class GameRuleCommand extends BaseCommand { + @Override + public String getName() { + return "gamerule"; + } + + @Override + public int getPermissionLevel() { + return LEVEL_GAMEMASTERS; + } + + + @Override + public String getUsage(CommandSender source) { + return "commands.gamerule.usage"; + } + + @Override + public void execute(CommandSender source, String[] args) { + if (args.length == 2) { + String rule = args[0]; + String value = args[1]; + + GameRules rules = getRules(); + + if (rules.contains(rule)) { + rules.set(rule, value); + logAdminAction(source, "commands.gamerule.success"); + } else { + logAdminAction(source, "commands.gamerule.norule", rule); + } + + return; + } else if (args.length == 1) { + String rule = args[0]; + GameRules rules = getRules(); + + if (rules.contains(rule)) { + String value = rules.get(rule); + source.sendMessage(ChatMessageComponent.forPlainText(rule).addPlainText(" += ").addPlainText(value)); } else { logAdminAction(source, +"commands.gamerule.norule", rule); + } + + return; + } else if (args.length == 0) { + GameRules rules = getRules(); + source.sendMessage(ChatMessageComponent.forPlainText(joinStrings(rules.getRuleNames()))); + return; + } + + throw new UsageException("commands.gamerule.usage"); + } + + @Override + public List matchArguments(CommandSender source, String[] args) { + if (args.length == 1) { + return matchArguments(args, getRules().getRuleNames()); + } else if (args.length == 2) { + return matchArguments(args, "true", "false"); + } + + return null; + } + + private GameRules getRules() { + return MinecraftServer.getInstance().getLevel(0).getGameRules(); + } +} + +*/ \ No newline at end of file diff --git a/Minecraft.World/Commands/GiveItemCommand.cpp b/Minecraft.World/Commands/GiveItemCommand.cpp index 2e9435e3a..b44d20136 100644 --- a/Minecraft.World/Commands/GiveItemCommand.cpp +++ b/Minecraft.World/Commands/GiveItemCommand.cpp @@ -1,5 +1,6 @@ #include "../Platform/stdafx.h" #include "../Headers/net.minecraft.commands.h" +#include "../Headers/net.minecraft.world.entity.item.h" #include "../Headers/net.minecraft.world.item.h" #include "../Headers/net.minecraft.network.packet.h" #include "../../Minecraft.Client/Player/ServerPlayer.h" @@ -7,6 +8,8 @@ EGameCommand GiveItemCommand::getId() { return eGameCommand_Give; } +int GiveItemCommand::getPermissionLevel() { return LEVEL_GAMEMASTERS; } + void GiveItemCommand::execute(std::shared_ptr source, byteArray commandData) { ByteArrayInputStream bais(commandData); @@ -24,7 +27,8 @@ void GiveItemCommand::execute(std::shared_ptr source, if (player != NULL && item > 0 && Item::items[item] != NULL) { std::shared_ptr itemInstance = std::shared_ptr(new ItemInstance(item, amount, aux)); - player->drop(itemInstance); + std::shared_ptr drop = player->drop(itemInstance); + drop->throwTime = 0; // logAdminAction(source, L"commands.give.success", // ChatPacket::e_ChatCustom, Item::items[item]->getName(itemInstance), // item, amount, player->getAName()); @@ -49,4 +53,4 @@ std::shared_ptr GiveItemCommand::preparePacket( return std::shared_ptr( new GameCommandPacket(eGameCommand_Give, baos.toByteArray())); -} +} \ No newline at end of file diff --git a/Minecraft.World/Commands/GiveItemCommand.h b/Minecraft.World/Commands/GiveItemCommand.h index fbde95335..9bf214056 100644 --- a/Minecraft.World/Commands/GiveItemCommand.h +++ b/Minecraft.World/Commands/GiveItemCommand.h @@ -7,6 +7,7 @@ class GameCommandPacket; class GiveItemCommand : public Command { public: virtual EGameCommand getId(); + virtual int getPermissionLevel(); virtual void execute(std::shared_ptr source, byteArray commandData); diff --git a/Minecraft.World/Commands/KillCommand.cpp b/Minecraft.World/Commands/KillCommand.cpp index fc144fc00..ac72f6211 100644 --- a/Minecraft.World/Commands/KillCommand.cpp +++ b/Minecraft.World/Commands/KillCommand.cpp @@ -2,15 +2,19 @@ #include "../Headers/net.minecraft.commands.h" #include "../Headers/net.minecraft.world.entity.player.h" #include "../Headers/net.minecraft.world.damagesource.h" +#include "../Util/BasicTypeContainers.h" #include "KillCommand.h" EGameCommand KillCommand::getId() { return eGameCommand_Kill; } +int KillCommand::getPermissionLevel() { return LEVEL_ALL; } + void KillCommand::execute(std::shared_ptr source, byteArray commandData) { std::shared_ptr player = std::dynamic_pointer_cast(source); - player->hurt(DamageSource::outOfWorld, 1000); + player->hurt(DamageSource::outOfWorld, Float::MAX_VALUE); source->sendMessage(L"Ouch. That look like it hurt."); + // source.sendMessage(ChatMessageComponent.forTranslation("commands.kill.success")); } \ No newline at end of file diff --git a/Minecraft.World/Commands/KillCommand.h b/Minecraft.World/Commands/KillCommand.h index a274d6631..a69b23b66 100644 --- a/Minecraft.World/Commands/KillCommand.h +++ b/Minecraft.World/Commands/KillCommand.h @@ -5,6 +5,7 @@ class KillCommand : public Command { public: virtual EGameCommand getId(); + virtual int getPermissionLevel(); virtual void execute(std::shared_ptr source, byteArray commandData); }; \ No newline at end of file diff --git a/Minecraft.World/Commands/PlaySoundCommand.h b/Minecraft.World/Commands/PlaySoundCommand.h new file mode 100644 index 000000000..a59d65ccf --- /dev/null +++ b/Minecraft.World/Commands/PlaySoundCommand.h @@ -0,0 +1,92 @@ +#pragma once +/* +package net.minecraft.commands.common; + +import net.minecraft.commands.BaseCommand; +import net.minecraft.commands.CommandSender; +import net.minecraft.commands.exceptions.CommandException; +import net.minecraft.commands.exceptions.UsageException; +import net.minecraft.network.packet.LevelSoundPacket; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.player.Player; + +public class PlaySoundCommand extends BaseCommand { + @Override + public String getName() { + return "playsound"; + } + + @Override + public int getPermissionLevel() { + return LEVEL_GAMEMASTERS; + } + + @Override + public String getUsage(CommandSender source) { + return "commands.playsound.usage"; + } + + @Override + public void execute(CommandSender source, String[] args) { + if (args.length < 2) { + throw new UsageException(getUsage(source)); + } + + int index = 0; + String sound = args[index++]; + ServerPlayer player = convertToPlayer(source, args[index++]); + double x = player.getCommandSenderWorldPosition().x; + double y = player.getCommandSenderWorldPosition().y; + double z = player.getCommandSenderWorldPosition().z; + double volume = 1; + double pitch = 1; + double minVolume = 0; + + if (args.length > index) x = convertArgToCoordinate(source, x, +args[index++]); if (args.length > index) y = convertArgToCoordinate(source, y, +args[index++], 0, 0); if (args.length > index) z = +convertArgToCoordinate(source, z, args[index++]); + + if (args.length > index) volume = convertArgToDouble(source, +args[index++], 0, Float.MAX_VALUE); if (args.length > index) pitch = +convertArgToDouble(source, args[index++], 0, 2); if (args.length > index) +minVolume = convertArgToDouble(source, args[index++], 0, 1); + + double maxDist = volume > 1 ? volume * 16 : 16; + double dist = player.distanceTo(x, y, z); + + if (dist > maxDist) { + if (minVolume > 0) { + double deltaX = x - player.x; + double deltaY = y - player.y; + double deltaZ = z - player.z; + double length = Math.sqrt(deltaX * deltaX + deltaY * deltaY + +deltaZ * deltaZ); double soundX = player.x; double soundY = player.y; double +soundZ = player.z; + + if (length > 0) { + soundX += deltaX / length * 2; + soundY += deltaY / length * 2; + soundZ += deltaZ / length * 2; + } + + player.connection.send(new LevelSoundPacket(sound, soundX, +soundY, soundZ, (float) minVolume, (float) pitch)); } else { throw new +CommandException("commands.playsound.playerTooFar", player.getAName()); + } + } else { + player.connection.send(new LevelSoundPacket(sound, x, y, z, (float) +volume, (float) pitch)); + } + + logAdminAction(source, "commands.playsound.success", sound, +player.getAName()); + } + + @Override + public boolean isValidWildcardPlayerArgument(String[] args, int +argumentIndex) { return argumentIndex == 1; + } +} + +*/ \ No newline at end of file diff --git a/Minecraft.World/Commands/PlayerSelector.h b/Minecraft.World/Commands/PlayerSelector.h new file mode 100644 index 000000000..de581f085 --- /dev/null +++ b/Minecraft.World/Commands/PlayerSelector.h @@ -0,0 +1,253 @@ +#pragma once +/* +package net.minecraft.commands; + +import net.minecraft.Pos; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.util.Mth; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelSettings; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class PlayerSelector { + private static final Pattern PATTERN_TARGETS = +Pattern.compile("^@([parf])(?:\\[([\\w=,!-]*)\\])?$"); private static final +Pattern PATTERN_SHORT_ARGUMENT = Pattern.compile("\\G([-!]?[\\w-]*)(?:$|,)"); + private static final Pattern PATTERN_LONG_ARGUMENT = +Pattern.compile("\\G(\\w+)=([-!]?[\\w-]*)(?:$|,)"); + + private static final int TARGETS_GROUP_TYPE = 1; + private static final int TARGETS_GROUP_ARGS = 2; // Null if not specified + + private static final String TARGET_NEAREST = "p"; + private static final String TARGET_ALL = "a"; + private static final String TARGET_RANDOM = "r"; + + private static final String ARGUMENT_RANGE_MAX = "r"; + private static final String ARGUMENT_RANGE_MIN = "rm"; + private static final String ARGUMENT_LEVEL_MAX = "l"; + private static final String ARGUMENT_LEVEL_MIN = "lm"; + private static final String ARGUMENT_COORDINATE_X = "x"; + private static final String ARGUMENT_COORDINATE_Y = "y"; + private static final String ARGUMENT_COORDINATE_Z = "z"; + private static final String ARGUMENT_COUNT = "c"; + private static final String ARGUMENT_MODE = "m"; + private static final String ARGUMENT_SCORE_PREFIX = "score_"; + private static final String ARGUMENT_TEAM_NAME = "team"; + private static final String ARGUMENT_PLAYER_NAME = "name"; + + public static ServerPlayer getPlayer(CommandSender source, String input) { + ServerPlayer[] result = getPlayers(source, input); + + if (result == null || result.length != 1) return null; + + return result[0]; + } + + public static String getPlayerNames(CommandSender source, String input) { + ServerPlayer[] result = getPlayers(source, input); + if (result == null || result.length == 0) return null; + String[] names = new String[result.length]; + + for (int i = 0; i < names.length; i++) { + names[i] = result[i].getDisplayName(); + } + + return BaseCommand.joinStrings(names); + } + + public static ServerPlayer[] getPlayers(CommandSender source, String input) +{ Matcher matcher = PATTERN_TARGETS.matcher(input); + + if (matcher.matches()) { + Map args = +getArguments(matcher.group(TARGETS_GROUP_ARGS)); String type = +matcher.group(TARGETS_GROUP_TYPE); int rangeMin = getDefaultRangeMin(type); int +rangeMax = getDefaultRangeMax(type); int levelMin = getDefaultLevelMin(type); + int levelMax = getDefaultLevelMax(type); + int count = getDefaultCount(type); + int mode = LevelSettings.GameType.NOT_SET.getId(); + Pos pos = source.getCommandSenderWorldPosition(); + Map scores = getScores(args); + String name = null; + String team = null; + boolean requireLevel = false; + + if (args.containsKey(ARGUMENT_RANGE_MIN)) { + rangeMin = Mth.getInt(args.get(ARGUMENT_RANGE_MIN), rangeMin); + requireLevel = true; + } + if (args.containsKey(ARGUMENT_RANGE_MAX)) { + rangeMax = Mth.getInt(args.get(ARGUMENT_RANGE_MAX), rangeMax); + requireLevel = true; + } + if (args.containsKey(ARGUMENT_LEVEL_MIN)) { + levelMin = Mth.getInt(args.get(ARGUMENT_LEVEL_MIN), levelMin); + } + if (args.containsKey(ARGUMENT_LEVEL_MAX)) { + levelMax = Mth.getInt(args.get(ARGUMENT_LEVEL_MAX), levelMax); + } + if (args.containsKey(ARGUMENT_COORDINATE_X)) { + pos.x = Mth.getInt(args.get(ARGUMENT_COORDINATE_X), pos.x); + requireLevel = true; + } + if (args.containsKey(ARGUMENT_COORDINATE_Y)) { + pos.y = Mth.getInt(args.get(ARGUMENT_COORDINATE_Y), pos.y); + requireLevel = true; + } + if (args.containsKey(ARGUMENT_COORDINATE_Z)) { + pos.z = Mth.getInt(args.get(ARGUMENT_COORDINATE_Z), pos.z); + requireLevel = true; + } + if (args.containsKey(ARGUMENT_MODE)) { + mode = Mth.getInt(args.get(ARGUMENT_MODE), mode); + } + if (args.containsKey(ARGUMENT_COUNT)) { + count = Mth.getInt(args.get(ARGUMENT_COUNT), count); + } + if (args.containsKey(ARGUMENT_TEAM_NAME)) { + team = args.get(ARGUMENT_TEAM_NAME); + } + if (args.containsKey(ARGUMENT_PLAYER_NAME)) { + name = args.get(ARGUMENT_PLAYER_NAME); + } + + Level level = requireLevel ? source.getCommandSenderWorld() : null; + + if (type.equals(TARGET_NEAREST) || type.equals(TARGET_ALL)) { + List players = +MinecraftServer.getInstance().getPlayers().getPlayers(pos, rangeMin, rangeMax, +count, mode, levelMin, levelMax, scores, name, team, level); return players == +null || players.isEmpty() ? new ServerPlayer[0] : players.toArray(new +ServerPlayer[0]); } else if (type.equals(TARGET_RANDOM)) { List +players = MinecraftServer.getInstance().getPlayers().getPlayers(pos, rangeMin, +rangeMax, 0, mode, levelMin, levelMax, scores, name, team, level); + Collections.shuffle(players); + players = players.subList(0, Math.min(count, players.size())); + return players == null || players.isEmpty() ? new +ServerPlayer[0] : players.toArray(new ServerPlayer[0]); } else { return null; + } + } else { + return null; + } + } + + public static Map getScores(Map input) { + Map result = new HashMap(); + + for (String key : input.keySet()) { + if (key.startsWith(ARGUMENT_SCORE_PREFIX) && key.length() > +ARGUMENT_SCORE_PREFIX.length()) { String name = +key.substring(ARGUMENT_SCORE_PREFIX.length()); result.put(name, +Mth.getInt(input.get(key), 1)); + } + } + + return result; + } + + public static boolean isList(String input) { + Matcher matcher = PATTERN_TARGETS.matcher(input); + + if (matcher.matches()) { + Map args = +getArguments(matcher.group(TARGETS_GROUP_ARGS)); String type = +matcher.group(TARGETS_GROUP_TYPE); int count = getDefaultCount(type); if +(args.containsKey(ARGUMENT_COUNT)) count = Mth.getInt(args.get(ARGUMENT_COUNT), +count); return count != 1; + } + + return false; + } + + public static boolean isPattern(String input, String onlyType) { + Matcher matcher = PATTERN_TARGETS.matcher(input); + + if (matcher.matches()) { + String type = matcher.group(TARGETS_GROUP_TYPE); + if (onlyType != null && !onlyType.equals(type)) return false; + + return true; + } + + return false; + } + + public static boolean isPattern(String input) { + return isPattern(input, null); + } + + private static final int getDefaultRangeMin(String type) { + return 0; + } + + private static final int getDefaultRangeMax(String type) { + return 0; + } + + private static final int getDefaultLevelMax(String type) { + return Integer.MAX_VALUE; + } + + private static final int getDefaultLevelMin(String type) { + return 0; + } + + private static final int getDefaultCount(String type) { + if (type.equals(TARGET_ALL)) { + return 0; + } else { + return 1; + } + } + + private static Map getArguments(String input) { + HashMap result = new HashMap(); + if (input == null) return result; + Matcher matcher = PATTERN_SHORT_ARGUMENT.matcher(input); + int count = 0; + int last = -1; + + while (matcher.find()) { + String name = null; + + switch (count++) { + case 0: + name = ARGUMENT_COORDINATE_X; + break; + case 1: + name = ARGUMENT_COORDINATE_Y; + break; + case 2: + name = ARGUMENT_COORDINATE_Z; + break; + case 3: + name = ARGUMENT_RANGE_MAX; + break; + } + + if (name != null && matcher.group(1).length() > 0) result.put(name, +matcher.group(1)); last = matcher.end(); + } + + if (last < input.length()) { + matcher = PATTERN_LONG_ARGUMENT.matcher(last == -1 ? input : +input.substring(last)); + + while (matcher.find()) { + result.put(matcher.group(1), matcher.group(2)); + } + } + + return result; + } +} + +*/ \ No newline at end of file diff --git a/Minecraft.World/Commands/SetPlayerTimeoutCommand.h b/Minecraft.World/Commands/SetPlayerTimeoutCommand.h new file mode 100644 index 000000000..11bf91033 --- /dev/null +++ b/Minecraft.World/Commands/SetPlayerTimeoutCommand.h @@ -0,0 +1,37 @@ +#pragma once +/* +package net.minecraft.commands.common; + +import net.minecraft.commands.BaseCommand; +import net.minecraft.commands.CommandSender; +import net.minecraft.commands.exceptions.UsageException; +import net.minecraft.server.MinecraftServer; + +public class SetPlayerTimeoutCommand extends BaseCommand { + public String getName() { + return "setidletimeout"; + } + + @Override + public int getPermissionLevel() { + return LEVEL_ADMINS; + } + + @Override + public String getUsage(CommandSender source) { + return "commands.setidletimeout.usage"; + } + + public void execute(CommandSender source, String[] args) { + if (args.length == 1) { + int timeout = convertArgToInt(source, args[0], 0); + MinecraftServer.getInstance().setPlayerIdleTimeout(timeout); + logAdminAction(source, "commands.setidletimeout.success", timeout); + return; + } + + throw new UsageException("commands.setidletimeout.usage"); + } +} + +*/ \ No newline at end of file diff --git a/Minecraft.World/Commands/ShowSeedCommand.h b/Minecraft.World/Commands/ShowSeedCommand.h new file mode 100644 index 000000000..7ed06651d --- /dev/null +++ b/Minecraft.World/Commands/ShowSeedCommand.h @@ -0,0 +1,42 @@ +#pragma once +/* +package net.minecraft.commands.common; + +import net.minecraft.commands.*; +import net.minecraft.network.chat.ChatMessageComponent; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; + +public class ShowSeedCommand extends BaseCommand { + @Override + public boolean canExecute(CommandSender source) { + return MinecraftServer.getInstance().isSingleplayer() || +super.canExecute(source); + } + + @Override + public String getName() { + return "seed"; + } + + @Override + public int getPermissionLevel() { + return LEVEL_GAMEMASTERS; + } + + @Override + public String getUsage(CommandSender source) { + return "commands.seed.usage"; + } + + @Override + public void execute(CommandSender source, String[] args) { + Level level = source instanceof Player ? ((Player) source).level : +MinecraftServer.getInstance().getLevel(0); + source.sendMessage(ChatMessageComponent.forTranslation("commands.seed.success", +level.getSeed())); + } +} + +*/ \ No newline at end of file diff --git a/Minecraft.World/Commands/SpreadPlayersCommand.h b/Minecraft.World/Commands/SpreadPlayersCommand.h new file mode 100644 index 000000000..e103a8ae9 --- /dev/null +++ b/Minecraft.World/Commands/SpreadPlayersCommand.h @@ -0,0 +1,340 @@ +#pragma once +/* +package net.minecraft.commands.common; + +import java.util.*; + +import net.minecraft.commands.*; +import net.minecraft.commands.exceptions.*; +import net.minecraft.network.chat.ChatMessageComponent; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.material.Material; +import net.minecraft.world.level.tile.Tile; +import net.minecraft.world.scores.Team; + +import com.google.common.collect.*; + +public class SpreadPlayersCommand extends BaseCommand { + private static final int MAX_ITERATION_COUNT = 10000; + + @Override + public String getName() { + return "spreadplayers"; + } + + @Override + public int getPermissionLevel() { + return LEVEL_GAMEMASTERS; + } + + @Override + public String getUsage(CommandSender source) { + return "commands.spreadplayers.usage"; + } + + @Override + public void execute(CommandSender source, String[] args) { + if (args.length < 6) throw new +UsageException("commands.spreadplayers.usage"); int index = 0; double x = +convertArgToCoordinate(source, Double.NaN, args[index++]); double z = +convertArgToCoordinate(source, Double.NaN, args[index++]); double minDist = +convertArgToDouble(source, args[index++], 0); double maxDist = +convertArgToDouble(source, args[index++], minDist + 1); boolean respectTeams = +convertArgToBoolean(source, args[index++]); + + List players = Lists.newArrayList(); + + while (index < args.length) { + String arg = args[index++]; + + if (PlayerSelector.isPattern(arg)) { + ServerPlayer[] result = PlayerSelector.getPlayers(source, arg); + + if (result != null && result.length != 0) { + Collections.addAll(players, result); + } else { + throw new PlayerNotFoundException(); + } + } else { + Player player = +MinecraftServer.getInstance().getPlayers().getPlayer(arg); + + if (player != null) { + players.add(player); + } else { + throw new PlayerNotFoundException(); + } + } + } + + if (players.isEmpty()) { + throw new PlayerNotFoundException(); + } + + source.sendMessage(ChatMessageComponent.forTranslation("commands.spreadplayers.spreading." ++ (respectTeams ? "teams" : "players"), joinPlayerNames(players), x, z, minDist, +maxDist)); + + spreadPlayers(source, players, new Position(x, z), minDist, maxDist, +players.get(0).level, respectTeams); + } + + private void spreadPlayers(CommandSender source, List players, +Position center, double spreadDist, double maxDistFromCenter, Level level, +boolean respectTeams) { Random random = new Random(); double minX = center.x - +maxDistFromCenter; double minZ = center.z - maxDistFromCenter; double maxX = +center.x + maxDistFromCenter; double maxZ = center.z + maxDistFromCenter; + + Position[] positions = createInitialPositions(random, respectTeams ? +getNumberOfTeams(players) : players.size(), minX, minZ, maxX, maxZ); int +iterations = spreadPositions(center, spreadDist, level, random, minX, minZ, +maxX, maxZ, positions, respectTeams); double avgDistance = +setPlayerPositions(players, level, positions, respectTeams); + + logAdminAction(source, "commands.spreadplayers.success." + (respectTeams +? "teams" : "players"), positions.length, center.x, center.z); if +(positions.length > 1) +source.sendMessage(ChatMessageComponent.forTranslation("commands.spreadplayers.info." ++ (respectTeams ? "teams" : "players"), String.format("%.2f", avgDistance), + iterations)); + } + + private int getNumberOfTeams(List players) { + Set teams = Sets.newHashSet(); + + for (LivingEntity player : players) { + if (player instanceof Player) { + teams.add(((Player) player).getTeam()); + } else { + teams.add(null); + } + } + + return teams.size(); + } + + private int spreadPositions(Position center, double spreadDist, Level level, +Random random, double minX, double minZ, double maxX, double maxZ, Position[] +positions, boolean respectTeams) { boolean hasCollisions = true; int iteration; + double minDistance = Float.MAX_VALUE; + + for (iteration = 0; iteration < MAX_ITERATION_COUNT && hasCollisions; +iteration++) { hasCollisions = false; minDistance = Float.MAX_VALUE; + + for (int i = 0; i < positions.length; i++) { + Position position = positions[i]; + int neighbourCount = 0; + Position averageNeighbourPos = new Position(); + + for (int j = 0; j < positions.length; j++) { + if (i == j) continue; + Position neighbour = positions[j]; + + double dist = position.dist(neighbour); + minDistance = Math.min(dist, minDistance); + if (dist < spreadDist) { + neighbourCount++; + averageNeighbourPos.x += neighbour.x - position.x; + averageNeighbourPos.z += neighbour.z - position.z; + } + } + + if (neighbourCount > 0) { + averageNeighbourPos.x /= neighbourCount; + averageNeighbourPos.z /= neighbourCount; + double length = averageNeighbourPos.getLength(); + + if (length > 0) { + averageNeighbourPos.normalize(); + + position.moveAway(averageNeighbourPos); + } else { + position.randomize(random, minX, minZ, maxX, maxZ); + } + + hasCollisions = true; + } + + if (position.clamp(minX, minZ, maxX, maxZ)) { + hasCollisions = true; + } + } + + if (!hasCollisions) { + for (Position position : positions) { + if (!position.isSafe(level)) { + position.randomize(random, minX, minZ, maxX, maxZ); + hasCollisions = true; + } + } + } + } + + if (iteration >= MAX_ITERATION_COUNT) { + throw new CommandException("commands.spreadplayers.failure." + +(respectTeams ? "teams" : "players"), positions.length, center.x, center.z, +String.format("%.2f", minDistance)); + } + + return iteration; + } + + private double setPlayerPositions(List players, Level level, +Position[] positions, boolean respectTeams) { double avgDistance = 0; int +positionIndex = 0; Map teamPositions = Maps.newHashMap(); + + for (int i = 0; i < players.size(); i++) { + LivingEntity player = players.get(i); + Position position; + + if (respectTeams) { + Team team = player instanceof Player ? ((Player) +player).getTeam() : null; + + if (!teamPositions.containsKey(team)) { + teamPositions.put(team, positions[positionIndex++]); + } + + position = teamPositions.get(team); + } else { + position = positions[positionIndex++]; + } + + player.teleportTo(Mth.floor(position.x) + 0.5f, +position.getSpawnY(level), Mth.floor(position.z) + 0.5); + + double closest = Double.MAX_VALUE; + for (int j = 0; j < positions.length; j++) { + if (position == positions[j]) continue; + + double dist = position.dist(positions[j]); + closest = Math.min(dist, closest); + } + avgDistance += closest; + } + + avgDistance /= players.size(); + return avgDistance; + } + + private Position[] createInitialPositions(Random random, int count, double +minX, double minZ, double maxX, double maxZ) { Position[] result = new +Position[count]; + + for (int i = 0; i < result.length; i++) { + Position position = new Position(); + + position.randomize(random, minX, minZ, maxX, maxZ); + + result[i] = position; + } + + return result; + } + + private static class Position { + double x; + double z; + + Position() { + } + + Position(double x, double z) { + this.x = x; + this.z = z; + } + + void set(double x, double z) { + this.x = x; + this.z = z; + } + + double dist(Position target) { + double dx = x - target.x; + double dz = z - target.z; + + return Math.sqrt(dx * dx + dz * dz); + } + + void normalize() { + double dist = (double) getLength(); + x /= dist; + z /= dist; + } + + float getLength() { + return Mth.sqrt(x * x + z * z); + } + + public void moveAway(Position pos) { + x -= pos.x; + z -= pos.z; + } + + public boolean clamp(double minX, double minZ, double maxX, double maxZ) +{ boolean changed = false; + + if (x < minX) { + x = minX; + changed = true; + } else if (x > maxX) { + x = maxX; + changed = true; + } + + if (z < minZ) { + z = minZ; + changed = true; + } else if (z > maxZ) { + z = maxZ; + changed = true; + } + + return changed; + } + + public int getSpawnY(Level level) { + int xt = Mth.floor(x); + int zt = Mth.floor(z); + + for (int y = Level.maxBuildHeight; y > 0; y--) { + int tile = level.getTile(xt, y, zt); + + if (tile != 0) { + return y + 1; + } + } + + return Level.maxBuildHeight + 1; + } + + public boolean isSafe(Level level) { + int xt = Mth.floor(x); + int zt = Mth.floor(z); + + for (int y = Level.maxBuildHeight; y > 0; y--) { + int tile = level.getTile(xt, y, zt); + + if (tile != 0) { + Material material = Tile.tiles[tile].material; + + return !material.isLiquid() && material != Material.fire; + } + } + + return false; + } + + public void randomize(Random random, double minX, double minZ, double +maxX, double maxZ) { x = Mth.nextDouble(random, minX, maxX); z = +Mth.nextDouble(random, minZ, maxZ); + } + } +} + +*/ \ No newline at end of file diff --git a/Minecraft.World/Commands/TimeCommand.cpp b/Minecraft.World/Commands/TimeCommand.cpp index 88daf6b5a..051bc2862 100644 --- a/Minecraft.World/Commands/TimeCommand.cpp +++ b/Minecraft.World/Commands/TimeCommand.cpp @@ -7,6 +7,8 @@ EGameCommand TimeCommand::getId() { return eGameCommand_Time; } +int TimeCommand::getPermissionLevel() { return LEVEL_GAMEMASTERS; } + void TimeCommand::execute(std::shared_ptr source, byteArray commandData) { ByteArrayInputStream bais(commandData); @@ -51,15 +53,14 @@ void TimeCommand::execute(std::shared_ptr source, void TimeCommand::doSetTime(std::shared_ptr source, int value) { for (int i = 0; i < MinecraftServer::getInstance()->levels.length; i++) { - MinecraftServer::getInstance()->levels[i]->setTimeAndAdjustTileTicks( - value); + MinecraftServer::getInstance()->levels[i]->setDayTime(value); } } void TimeCommand::doAddTime(std::shared_ptr source, int value) { for (int i = 0; i < MinecraftServer::getInstance()->levels.length; i++) { ServerLevel* level = MinecraftServer::getInstance()->levels[i]; - level->setTimeAndAdjustTileTicks(level->getTime() + value); + level->setDayTime(level->getDayTime() + value); } } @@ -71,4 +72,4 @@ std::shared_ptr TimeCommand::preparePacket(bool night) { return std::shared_ptr( new GameCommandPacket(eGameCommand_Time, baos.toByteArray())); -} +} \ No newline at end of file diff --git a/Minecraft.World/Commands/TimeCommand.h b/Minecraft.World/Commands/TimeCommand.h index dac94253f..2b38a4b9b 100644 --- a/Minecraft.World/Commands/TimeCommand.h +++ b/Minecraft.World/Commands/TimeCommand.h @@ -5,6 +5,7 @@ class TimeCommand : public Command { public: virtual EGameCommand getId(); + virtual int getPermissionLevel(); virtual void execute(std::shared_ptr source, byteArray commandData); diff --git a/Minecraft.World/Commands/ToggleDownfallCommand.cpp b/Minecraft.World/Commands/ToggleDownfallCommand.cpp index 466e8dcb4..fa760f539 100644 --- a/Minecraft.World/Commands/ToggleDownfallCommand.cpp +++ b/Minecraft.World/Commands/ToggleDownfallCommand.cpp @@ -11,6 +11,8 @@ EGameCommand ToggleDownfallCommand::getId() { return eGameCommand_ToggleDownfall; } +int ToggleDownfallCommand::getPermissionLevel() { return LEVEL_GAMEMASTERS; } + void ToggleDownfallCommand::execute(std::shared_ptr source, byteArray commandData) { doToggleDownfall(); @@ -27,4 +29,4 @@ void ToggleDownfallCommand::doToggleDownfall() { std::shared_ptr ToggleDownfallCommand::preparePacket() { return std::shared_ptr( new GameCommandPacket(eGameCommand_ToggleDownfall, byteArray())); -} +} \ No newline at end of file diff --git a/Minecraft.World/Commands/ToggleDownfallCommand.h b/Minecraft.World/Commands/ToggleDownfallCommand.h index 19ea908fc..1b9000b4d 100644 --- a/Minecraft.World/Commands/ToggleDownfallCommand.h +++ b/Minecraft.World/Commands/ToggleDownfallCommand.h @@ -6,6 +6,7 @@ class GameCommandPacket; class ToggleDownfallCommand : public Command { public: virtual EGameCommand getId(); + virtual int getPermissionLevel(); virtual void execute(std::shared_ptr source, byteArray commandData); diff --git a/Minecraft.World/Commands/WeatherCommand.h b/Minecraft.World/Commands/WeatherCommand.h new file mode 100644 index 000000000..353841095 --- /dev/null +++ b/Minecraft.World/Commands/WeatherCommand.h @@ -0,0 +1,74 @@ +#pragma once +/* +package net.minecraft.commands.common; + +import java.util.*; + +import net.minecraft.SharedConstants; +import net.minecraft.commands.*; +import net.minecraft.commands.exceptions.UsageException; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.storage.LevelData; + +public class WeatherCommand extends BaseCommand { + @Override + public String getName() { + return "weather"; + } + + @Override + public int getPermissionLevel() { + return LEVEL_GAMEMASTERS; + } + + @Override + public String getUsage(CommandSender source) { + return "commands.weather.usage"; + } + + @Override + public void execute(CommandSender source, String[] args) { + if (args.length < 1 || args.length > 2) { + throw new UsageException("commands.weather.usage"); + } + + int duration = (300 + new Random().nextInt(600)) * +SharedConstants.TICKS_PER_SECOND; if (args.length >= 2) { duration = +convertArgToInt(source, args[1], 1, 1000000) * SharedConstants.TICKS_PER_SECOND; + } + + Level level = MinecraftServer.getInstance().levels[0]; + LevelData levelData = level.getLevelData(); + levelData.setRainTime(duration); + levelData.setThunderTime(duration); + + if ("clear".equalsIgnoreCase(args[0])) { + levelData.setRaining(false); + levelData.setThundering(false); + logAdminAction(source, "commands.weather.clear"); + } else if ("rain".equalsIgnoreCase(args[0])) { + levelData.setRaining(true); + levelData.setThundering(false); + logAdminAction(source, "commands.weather.rain"); + } else if ("thunder".equalsIgnoreCase(args[0])) { + levelData.setRaining(true); + levelData.setThundering(true); + logAdminAction(source, "commands.weather.thunder"); + } else { + throw new UsageException("commands.weather.usage"); + } + } + + @Override + public List matchArguments(CommandSender source, String[] args) { + if (args.length == 1) { + return matchArguments(args, "clear", "rain", "thunder"); + } + + return null; + } + +} + +*/ \ No newline at end of file