feat: better kill command, Host Privileges check (#135)
i changed a bit the kill command because it was not working properly, then i added a check for HostPrivileges for each command
This commit is contained in:
@@ -1,26 +1,197 @@
|
||||
#include "stdafx.h"
|
||||
#include "stdafx.h"
|
||||
#include "net.minecraft.commands.h"
|
||||
#include "net.minecraft.world.entity.player.h"
|
||||
#include "net.minecraft.world.damagesource.h"
|
||||
#include "net.minecraft.world.level.h"
|
||||
#include "BasicTypeContainers.h"
|
||||
#include "KillCommand.h"
|
||||
#include "EntityTypeMap.h"
|
||||
|
||||
|
||||
static void killEntity(shared_ptr<Entity> entity)
|
||||
{
|
||||
if (entity->instanceof(eTYPE_LIVINGENTITY))
|
||||
{
|
||||
auto living = dynamic_pointer_cast<LivingEntity>(entity);
|
||||
if (living != nullptr)
|
||||
{
|
||||
living->hurt(DamageSource::outOfWorld, Float::MAX_VALUE);
|
||||
return;
|
||||
}
|
||||
|
||||
entity->remove();
|
||||
return;
|
||||
}
|
||||
entity->remove();
|
||||
}
|
||||
|
||||
EGameCommand KillCommand::getId()
|
||||
{
|
||||
return eGameCommand_Kill;
|
||||
return eGameCommand_Kill;
|
||||
}
|
||||
|
||||
int KillCommand::getPermissionLevel()
|
||||
{
|
||||
return LEVEL_ALL;
|
||||
return LEVEL_ALL;
|
||||
}
|
||||
|
||||
void KillCommand::execute(shared_ptr<CommandSender> source, byteArray commandData)
|
||||
{
|
||||
shared_ptr<Player> player = dynamic_pointer_cast<Player>(source);
|
||||
shared_ptr<Player> senderPlayer = dynamic_pointer_cast<Player>(source);
|
||||
if (senderPlayer == nullptr)
|
||||
return;
|
||||
|
||||
player->hurt(DamageSource::outOfWorld, Float::MAX_VALUE);
|
||||
Level *level = senderPlayer->level;
|
||||
if (level == nullptr)
|
||||
return;
|
||||
|
||||
source->sendMessage(L"Ouch. That look like it hurt.");
|
||||
//source.sendMessage(ChatMessageComponent.forTranslation("commands.kill.success"));
|
||||
|
||||
//nothing is the same of @s
|
||||
if (commandData.length == 0 || commandData.data == nullptr)
|
||||
{
|
||||
senderPlayer->hurt(DamageSource::outOfWorld, Float::MAX_VALUE);
|
||||
return;
|
||||
}
|
||||
|
||||
ByteArrayInputStream bais(commandData);
|
||||
DataInputStream dis(&bais);
|
||||
wstring targetName = dis.readUTF();
|
||||
|
||||
wstring targetLower = targetName;
|
||||
transform(targetLower.begin(), targetLower.end(), targetLower.begin(), towlower);
|
||||
|
||||
//@s
|
||||
if (targetLower == L"@s")
|
||||
{
|
||||
senderPlayer->hurt(DamageSource::outOfWorld, Float::MAX_VALUE);
|
||||
return;
|
||||
}
|
||||
|
||||
//@a
|
||||
if (targetLower == L"@a")
|
||||
{
|
||||
vector<shared_ptr<Player>> toKill;
|
||||
for (auto& p : level->players)
|
||||
if (p != nullptr && !p->removed)
|
||||
toKill.push_back(p);
|
||||
for (auto& p : toKill)
|
||||
p->hurt(DamageSource::outOfWorld, Float::MAX_VALUE);
|
||||
return;
|
||||
}
|
||||
|
||||
//@p
|
||||
if (targetLower == L"@p")
|
||||
{
|
||||
shared_ptr<Player> nearest = level->getNearestPlayer(
|
||||
dynamic_pointer_cast<Entity>(senderPlayer), 9999.0);
|
||||
if (nearest != nullptr)
|
||||
{
|
||||
nearest->hurt(DamageSource::outOfWorld, Float::MAX_VALUE);
|
||||
source->sendMessage(L"Killed " + nearest->getName() + L".");
|
||||
}
|
||||
else
|
||||
{
|
||||
source->sendMessage(L"No player found.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//@r
|
||||
if (targetLower == L"@r")
|
||||
{
|
||||
if (level->players.empty())
|
||||
{
|
||||
source->sendMessage(L"No player found.");
|
||||
return;
|
||||
}
|
||||
int idx = rand() % (int)level->players.size();
|
||||
auto& p = level->players[idx];
|
||||
if (p != nullptr && !p->removed)
|
||||
{
|
||||
p->hurt(DamageSource::outOfWorld, Float::MAX_VALUE);
|
||||
source->sendMessage(L"Killed " + p->getName() + L".");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// @e
|
||||
if (targetLower.size() >= 2 && targetLower.substr(0, 2) == L"@e")
|
||||
{
|
||||
eINSTANCEOF filterType = eTYPE_NOTSET;
|
||||
bool invertFilter = false;
|
||||
bool filterIsPlayer = false;
|
||||
|
||||
if (targetLower.size() > 3 && targetLower[2] == L'[')
|
||||
{
|
||||
wstring inner = targetLower.substr(3, targetLower.size() - 4);
|
||||
wstring key = L"type=";
|
||||
size_t pos = inner.find(key);
|
||||
if (pos == wstring::npos)
|
||||
{
|
||||
source->sendMessage(L"Invalid selector syntax. Usage: @e[type=<entity_type>]");
|
||||
return;
|
||||
}
|
||||
|
||||
wstring typeStr = inner.substr(pos + key.size());
|
||||
if (!typeStr.empty() && typeStr[0] == L'!')
|
||||
{
|
||||
invertFilter = true;
|
||||
typeStr = typeStr.substr(1);
|
||||
}
|
||||
|
||||
if (typeStr == L"player")
|
||||
{
|
||||
filterIsPlayer = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
filterType = EntityTypeMap::getTypeFromName(typeStr);
|
||||
if (filterType == eTYPE_NOTSET)
|
||||
{
|
||||
source->sendMessage(L"Unknown entity type: " + typeStr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vector<shared_ptr<Entity>> toKill;
|
||||
for (auto& entity : level->entities)
|
||||
{
|
||||
if (entity == nullptr || entity->removed) continue;
|
||||
|
||||
bool isPlayer = entity->instanceof(eTYPE_PLAYER);
|
||||
|
||||
|
||||
bool matchesFilter;
|
||||
if (filterType == eTYPE_NOTSET && !filterIsPlayer)
|
||||
matchesFilter = true;
|
||||
else if (filterIsPlayer)
|
||||
matchesFilter = isPlayer;
|
||||
else
|
||||
matchesFilter = entity->instanceof(filterType);
|
||||
|
||||
if (invertFilter) matchesFilter = !matchesFilter;
|
||||
|
||||
if (matchesFilter)
|
||||
toKill.push_back(entity);
|
||||
}
|
||||
|
||||
for (auto& entity : toKill)
|
||||
if (!entity->removed)
|
||||
killEntity(entity);
|
||||
|
||||
source->sendMessage(L"Killed " + to_wstring(toKill.size()) + L" entities.");
|
||||
return;
|
||||
}
|
||||
|
||||
// by player name
|
||||
shared_ptr<Player> targetPlayer = level->getPlayerByName(targetName);
|
||||
if (targetPlayer != nullptr)
|
||||
{
|
||||
targetPlayer->hurt(DamageSource::outOfWorld, Float::MAX_VALUE);
|
||||
source->sendMessage(L"Killed " + targetName + L".");
|
||||
return;
|
||||
}
|
||||
|
||||
source->sendMessage(L"No entity was found.");
|
||||
}
|
||||
Reference in New Issue
Block a user