1
0

Ignore Mojang's names & skins

Being able to control people's names and skins is loads of fun!
This commit is contained in:
Ryan Fox 2023-05-31 03:29:52 -07:00
parent ca09970fda
commit e5a9c1b04d
Signed by: flewkey
GPG Key ID: 94F56ADFD848851E
10 changed files with 232 additions and 10 deletions

View File

@ -14,6 +14,8 @@ import party._2a03.mc.command.FlyCommand;
import party._2a03.mc.command.HatCommand;
import party._2a03.mc.command.HeadCommand;
import party._2a03.mc.command.HomeCommand;
import party._2a03.mc.command.NameCommand;
import party._2a03.mc.command.SkinCommand;
import party._2a03.mc.command.SpawnCommand;
import party._2a03.mc.util.Config;
import party._2a03.mc.util.Database;
@ -56,6 +58,8 @@ public class MinecraftTweaks2a03 implements ModInitializer {
HatCommand.register(dispatcher);
HeadCommand.register(dispatcher);
HomeCommand.register(dispatcher);
NameCommand.register(dispatcher);
SkinCommand.register(dispatcher);
SpawnCommand.register(dispatcher);
}
});

View File

@ -12,6 +12,8 @@ import party._2a03.mc.util.Database;
import party._2a03.mc.util.PlayerData;
import party._2a03.mc.util.PlayerPosition;
import java.util.UUID;
public class HomeCommand {
public static void register(CommandDispatcher<ServerCommandSource> dispatcher) {
LiteralArgumentBuilder<ServerCommandSource> literalargumentbuilder = CommandManager.literal("home").executes(ctx -> {
@ -43,12 +45,13 @@ public class HomeCommand {
return 1;
}));
literalargumentbuilder.then(CommandManager.literal("sudoset").requires(ctx -> {
literalargumentbuilder.then(CommandManager.literal("assign").requires(ctx -> {
return ctx.hasPermissionLevel(2);
}).then(CommandManager.argument("UUID", StringArgumentType.word()).executes(ctx -> {
UUID uuid = UUID.fromString(StringArgumentType.getString(ctx, "UUID"));
ServerCommandSource source = ctx.getSource();
ServerPlayerEntity sender = source.getPlayer();
PlayerData playerdata = Database.getPlayer(StringArgumentType.getString(ctx, "UUID"));
PlayerData playerdata = Database.getPlayer(uuid);
double x = sender.getX();
double y = sender.getY();
double z = sender.getZ();
@ -57,7 +60,7 @@ public class HomeCommand {
RegistryKey registrykey = sender.getWorld().getRegistryKey();
PlayerPosition location = new PlayerPosition(x, y, z, yaw, pitch, registrykey);
playerdata.setHome(location);
source.sendFeedback(Text.of("User's home has been updated (" + StringArgumentType.getString(ctx, "UUID") + ")"), true);
source.sendFeedback(Text.of("User's home has been updated (" + uuid.toString() + ")"), true);
return 1;
})));

View File

@ -0,0 +1,32 @@
package party._2a03.mc.command;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import party._2a03.mc.util.Database;
import party._2a03.mc.util.PlayerData;
import java.util.UUID;
public class NameCommand {
public static void register(CommandDispatcher<ServerCommandSource> dispatcher) {
dispatcher.register(CommandManager.literal("name")
.then(CommandManager.literal("assign")
.requires(ctx -> { return ctx.hasPermissionLevel(2); })
.then(CommandManager.argument("UUID", StringArgumentType.word())
.then(CommandManager.argument("name", StringArgumentType.word())
.executes(ctx -> {
UUID uuid = UUID.fromString(StringArgumentType.getString(ctx, "UUID"));
ServerCommandSource source = ctx.getSource();
ServerPlayerEntity sender = source.getPlayer();
PlayerData playerdata = Database.getPlayer(uuid);
playerdata.setName(StringArgumentType.getString(ctx, "name"));
source.sendFeedback(Text.of("User's name has been updated (" + uuid.toString() + ")"), true);
return 1;
})))));
}
}

View File

@ -0,0 +1,52 @@
package party._2a03.mc.command;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import party._2a03.mc.util.Database;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.net.URL;
import java.util.UUID;
public class SkinCommand {
public static void register(CommandDispatcher<ServerCommandSource> dispatcher) {
LiteralArgumentBuilder literalargumentbuilder = CommandManager.literal("skin");
literalargumentbuilder.then(CommandManager.literal("assign")
.requires(ctx -> { return ctx.hasPermissionLevel(2); })
.then(CommandManager.argument("UUID", StringArgumentType.word())
.then(CommandManager.argument("url", StringArgumentType.greedyString())
.executes(ctx -> {
ServerCommandSource source = ctx.getSource();
String magic, skinval, skinsig;
try {
URL url = new URL(StringArgumentType.getString(ctx, "url"));
BufferedReader read = new BufferedReader(new InputStreamReader(url.openStream()));
magic = read.readLine();
skinval = read.readLine();
skinsig = read.readLine();
read.close();
} catch (IOException e) {
source.sendFeedback(Text.of("Failed to access skin"), false);
return 1;
}
if (!magic.equals("SKIN:1") || skinval == null || skinsig == null) {
source.sendFeedback(Text.of("Invalid skin"), false);
return 1;
}
UUID uuid = UUID.fromString(StringArgumentType.getString(ctx, "UUID"));
Database.getPlayer(uuid).setTextures(skinval, skinsig);
source.sendFeedback(Text.of("User's skin has been updated (" + uuid.toString() + ")"), true);
return 1;
}))));
dispatcher.register(literalargumentbuilder);
}
}

View File

@ -0,0 +1,33 @@
package party._2a03.mc.mixin;
import com.mojang.authlib.GameProfile;
import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import party._2a03.mc.util.Database;
import party._2a03.mc.util.PlayerData;
import java.util.UUID;
@Mixin(value = GameProfile.class, remap = false)
public class MixinGameProfile {
int ready = 0;
String server_name = "";
@Inject(method = "getName", at = @At("RETURN"), cancellable = true)
public void replaceName(CallbackInfoReturnable<String> ci) {
if (ready++ < 2) // wait until authenticated
return;
UUID uuid = ((GameProfile)(Object)this).getId();
if (uuid == null) // wait until UUID is set
return;
if (this.server_name == "") {
PlayerData playerdata = Database.getPlayer(uuid.toString());
this.server_name = playerdata.getName();
}
ci.setReturnValue(this.server_name);
}
}

View File

@ -1,5 +1,6 @@
package party._2a03.mc.mixin;
import com.mojang.authlib.properties.PropertyMap;
import net.minecraft.entity.player.PlayerAbilities;
import net.minecraft.server.PlayerManager;
import net.minecraft.network.ClientConnection;
@ -11,9 +12,19 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import party._2a03.mc.util.Config;
import party._2a03.mc.util.Database;
import party._2a03.mc.util.PlayerData;
@Mixin(PlayerManager.class)
public abstract class MixinPlayerManager {
@Inject(method = "onPlayerConnect", at = @At(value = "HEAD"))
void onConnect(ClientConnection connection, ServerPlayerEntity player, CallbackInfo ci) {
PlayerData playerdata = Database.getPlayer(player.getGameProfile().getId());
PropertyMap map = player.getGameProfile().getProperties();
map.removeAll("textures");
map.put("textures", playerdata.getTextures());
}
@Inject(method = "onPlayerConnect", at = @At(value = "INVOKE",
target = "Lnet/minecraft/server/network/ServerPlayerEntity;getAbilities()Lnet/minecraft/entity/player/PlayerAbilities;"))
public void persistFlight(ClientConnection connection, ServerPlayerEntity player, CallbackInfo ci) {

View File

@ -3,10 +3,12 @@ package party._2a03.mc.mixin;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.registry.RegistryKey;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import party._2a03.mc.util.Config;

View File

@ -13,6 +13,8 @@ import org.json.JSONArray;
import party._2a03.mc.util.PlayerData;
import party._2a03.mc.util.PlayerPosition;
import java.util.UUID;
public class Database {
private static final Logger LOGGER = LogManager.getLogger();
private static Connection conn = null;
@ -32,9 +34,12 @@ public class Database {
stmt = conn.createStatement();
stmt.executeUpdate(
"CREATE TABLE IF NOT EXISTS players (" +
"uuid TEXT NOT NULL UNIQUE," +
"home TEXT," +
"asn INTEGER," +
"uuid TEXT NOT NULL UNIQUE," +
"name TEXT," +
"skinval TEXT," +
"skinsig TEXT," +
"home TEXT," +
"asn INTEGER," +
"PRIMARY KEY(uuid)" +
");");
stmt.executeUpdate(
@ -72,16 +77,26 @@ public class Database {
}
}
public static PlayerData getPlayer(UUID uuid) {
return getPlayer(uuid.toString());
}
public static PlayerData getPlayer(String uuid) {
try {
PreparedStatement pstmt;
pstmt = conn.prepareStatement(
"SELECT home FROM players WHERE uuid = ?;");
"SELECT home, name, skinval, skinsig FROM players WHERE uuid = ?;");
pstmt.setString(1, uuid);
ResultSet res = pstmt.executeQuery();
if (res.next()) {
PlayerPosition home = new PlayerPosition(new JSONArray(res.getString("home")));
return new PlayerData(uuid, home);
String homeData = res.getString("home");
PlayerPosition home = new PlayerPosition();
if (homeData != "" && homeData != null)
home = new PlayerPosition(new JSONArray(homeData));
String name = res.getString("name");
String skinval = res.getString("skinval");
String skinsig = res.getString("skinsig");
return new PlayerData(uuid, home, name, skinval, skinsig);
}
pstmt.close();
} catch (SQLException e) {
@ -90,6 +105,44 @@ public class Database {
return new PlayerData(uuid);
}
public static void setPlayerTextures(String uuid, String skinval, String skinsig) {
try {
PreparedStatement pstmt;
pstmt = conn.prepareStatement(
"INSERT INTO players (uuid, skinval, skinsig) " +
"VALUES(?, ?, ?) " +
"ON CONFLICT(uuid) " +
"DO UPDATE SET skinval=?, skinsig=?;");
pstmt.setString(1, uuid);
pstmt.setString(2, skinval);
pstmt.setString(3, skinsig);
pstmt.setString(4, skinval);
pstmt.setString(5, skinsig);
pstmt.executeUpdate();
pstmt.close();
} catch (SQLException e) {
LOGGER.error(e.getMessage(), e);
}
}
public static void setPlayerName(String uuid, String name) {
try {
PreparedStatement pstmt;
pstmt = conn.prepareStatement(
"INSERT INTO players (uuid, name) " +
"VALUES(?, ?) " +
"ON CONFLICT(uuid) " +
"DO UPDATE SET name=?;");
pstmt.setString(1, uuid);
pstmt.setString(2, name);
pstmt.setString(3, name);
pstmt.executeUpdate();
pstmt.close();
} catch (SQLException e) {
LOGGER.error(e.getMessage(), e);
}
}
public static void setPlayerHome(String uuid, PlayerPosition home) {
try {
PreparedStatement pstmt;

View File

@ -1,5 +1,6 @@
package party._2a03.mc.util;
import com.mojang.authlib.properties.Property;
import org.json.JSONArray;
import org.json.JSONObject;
import party._2a03.mc.util.Database;
@ -8,15 +9,33 @@ import party._2a03.mc.util.PlayerPosition;
public class PlayerData {
private String uuid;
private PlayerPosition home;
private String name;
private String skinval;
private String skinsig;
public PlayerData(String p_uuid) {
this.uuid = p_uuid;
this.home = new PlayerPosition();
}
public PlayerData(String p_uuid, PlayerPosition p_home) {
public PlayerData(String p_uuid, PlayerPosition p_home, String p_name, String p_skinval, String p_skinsig) {
this.uuid = p_uuid;
this.home = p_home;
this.name = p_name;
this.skinval = p_skinval;
this.skinsig = p_skinsig;
}
public Property getTextures() {
// Return a Steve texture if unset
if (this.skinval == null || this.skinsig == null || this.skinval.length() == 0 || this.skinsig.length() == 0)
return new Property("textures", "ewogICJ0aW1lc3RhbXAiIDogMTY2NjMwMjkxNzkzOCwKICAicHJvZmlsZUlkIiA6ICJjOWRlZTM4MDUzYjg0YzI5YjZlZjA5YjJlMDM5OTc0ZiIsCiAgInByb2ZpbGVOYW1lIiA6ICJTQVJfRGVjZW1iZXI1IiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzMxZjQ3N2ViMWE3YmVlZTYzMWMyY2E2NGQwNmY4ZjY4ZmE5M2EzMzg2ZDA0NDUyYWIyN2Y0M2FjZGYxYjYwY2IiCiAgICB9CiAgfQp9", "tTCtASRIyuzlNUgSoXgUr6arxABhCR4EQ9+eHaUoO8bADljmUFoQfb6oba8zqe2gIa2mnu5KQaOPQCxcTDjgNv9aIL2smINKxy/60VE4Mgnrh5ntH+mGuDi00V3Bk2CsObFZXz1vgk2UxdQUQ41eVQYm2xBrXFEbXMSoTafWGv0FMTPFpGxGRdduTe3QTEie3GcfAMHCn/9xMMmUxZZ6UVZ+mDe8ARt9/cmK+GmqT8m3kmrz/vq+i29KV4tWvJqsKIVAXm97jVPH9XxVR3tYlheimQSFNrCU8SzNPum/ZhxNAf5Uw90+/K0eaJE59y8tS7KDV5DHrRrHHXb/ywGGklSri1YjFm9AEBk6BeH8Y3Ot/e+zfQbF3rOny2DkBAm/v28FooYd25gXB4MjUFNPj3KdveQh7DpRAvnkmBZMqJCO+Z9fdY4Dw+jmqjII88r6mukWAODvXed/x8bvv55zzNOAxtqtwBTWHIdqWFr/7pMZF26RY1Tluw+pAWGWaKMHtqlGzyOLGMxMKwXqtLNEpIYw52ETwGKaWh8h34cOoI8dhpjfjym4UOihMmazK9LC0EUEHuBlgy5b/Ae71+6UsLNIX8bJwIvN16sP6wpSTNbV6htWoS7/ehvoxdKhI6XEUqWgEoAwmquClPfWiveCV057reoKeVHB9RdTl0sW+HM=");
// Otherwise...
return new Property("textures", this.skinval, this.skinsig);
}
public String getName() {
return (this.name == null || this.name.length() == 0) ? "Unknown" : this.name;
}
public PlayerPosition getHome() {
@ -27,6 +46,17 @@ public class PlayerData {
return this.uuid;
}
public void setTextures(String skinval, String skinsig) {
this.skinval = skinval;
this.skinsig = skinsig;
Database.setPlayerTextures(this.uuid, this.skinval, this.skinsig);
}
public void setName(String name) {
this.name = name;
Database.setPlayerName(this.uuid, this.name);
}
public void setHome(PlayerPosition location) {
this.home = location;
Database.setPlayerHome(this.uuid, this.home);
@ -36,6 +66,7 @@ public class PlayerData {
JSONObject json = new JSONObject();
json.put("uuid", uuid);
json.put("home", home.getJSON());
json.put("name", name);
return json;
}
}

View File

@ -5,6 +5,7 @@
"server": [
"MixinCreeperEntity",
"MixinGameModeCommand",
"MixinGameProfile",
"MixinPlayerManager",
"MixinRespawnAnchorBlock",
"MixinServerPlayerEntity",