Skip to content
Closed

V3 #138

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ org.gradle.configuration-cache=false
minecraft_version=1.21.11
loader_version=0.18.4
# Mod Properties
mod_version=2.19.2
mod_version=3.0.0-alpha.6
maven_group=net.legitimoose
archives_base_name=Legitimoose-Bot
# Dependencies
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ private static void rejoin() {
if ((now - lastJoinTimestamp) >= REJOIN_COOLDOWN_MS) {
lastJoinTimestamp = now;
LOGGER.info("Attempting to reconnect to server");
ServerData info = new ServerData("Server", "legitimoose.com", ServerData.Type.OTHER);
ServerData info = new ServerData("Legitimoose", "legitimoose.com", ServerData.Type.OTHER);
ConnectScreen.startConnecting(
new JoinMultiplayerScreen(null),
Minecraft.getInstance(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.mongodb.client.MongoCollection;
import net.legitimoose.bot.scraper.Database;
import net.legitimoose.bot.scraper.Player;
import net.legitimoose.bot.scraper.Rank;
import net.legitimoose.bot.scraper.Scraper;
import net.legitimoose.bot.util.McUtil;
import org.bson.Document;

import java.time.Instant;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand All @@ -32,11 +32,19 @@ public JsonArray handleRequest() {
}
}

for (String user : usernames.keySet()) {
for (String username : usernames.keySet()) {
try {
if (Database.getPlayers().countDocuments(new Document("name", username)) == 0) {
new Player(McUtil.getUuid(username), username, Rank.Unknown, List.of(), new Player.Streak(1, false), Instant.EPOCH).write();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}

for (Player dbPlayer : Database.getPlayers().find()) {
JsonObject player = new JsonObject();
try {
String uuid = McUtil.getUuid(user);
Player dbPlayer = Database.getPlayers().find(eq("uuid", uuid)).first();
Rank rank;
if (dbPlayer == null) {
rank = Rank.Unknown;
Expand All @@ -45,10 +53,18 @@ public JsonArray handleRequest() {
rank = dbPlayer.rank();
}

player.addProperty("uuid", uuid);
player.addProperty("name", user);
boolean online = false;
String world = "";
if (usernames.get(dbPlayer.name()) != null) {
online = true;
world = usernames.get(dbPlayer.name());
}

player.addProperty("uuid", dbPlayer.uuid());
player.addProperty("name", dbPlayer.name());
player.addProperty("rank", rank.toString());
player.addProperty("world", usernames.get(user));
player.addProperty("online", online);
player.addProperty("world", world);
response.add(player);
} catch (Exception e) {
throw new RuntimeException(e);
Expand All @@ -70,28 +86,35 @@ public JsonObject handleRequest(String uuid) {
}
}

for (String user : usernames.keySet()) {
for (String username : usernames.keySet()) {
try {
if (!McUtil.getUuid(user).equals(uuid)) {
continue;
}
Player dbPlayer = Database.getPlayers().find(eq("uuid", uuid)).first();
Rank rank;
if (dbPlayer == null) {
rank = Rank.Unknown;
} else {
response.addProperty("streak", dbPlayer.streak().days());
rank = dbPlayer.rank();
if (Database.getPlayers().countDocuments(new Document("name", username)) == 0) {
new Player(McUtil.getUuid(username), username, Rank.Unknown, List.of(), new Player.Streak(1, false), Instant.EPOCH).write();
}

response.addProperty("name", user);
response.addProperty("rank", rank.toString());
response.addProperty("world", usernames.get(user));
} catch (Exception e) {
throw new RuntimeException(e);
}
}

Player dbPlayer = Database.getPlayers().find(eq("uuid", uuid)).first();
try {
boolean online = false;
String world = "";
if (usernames.get(dbPlayer.name()) != null) {
online = true;
world = usernames.get(dbPlayer.name());
}

response.addProperty("uuid", dbPlayer.uuid());
response.addProperty("name", dbPlayer.name());
response.addProperty("rank", dbPlayer.rank().toString());
response.addProperty("streak", dbPlayer.streak().days());
response.addProperty("online", online);
response.addProperty("world", world);
} catch (Exception e) {
throw new RuntimeException(e);
}

return response;
}
}
2 changes: 1 addition & 1 deletion src/client/java/net/legitimoose/bot/scraper/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public void write() {
Updates.set("uuid", this.uuid),
Updates.set("name", this.name),
Updates.set("rank", this.rank),
Updates.set("blocked", this.blocked),
Updates.setOnInsert("blocked", this.blocked),
Updates.set("streak", this.streak),
Updates.set("last_joined", new BsonDateTime(this.last_joined.toEpochMilli())));
Database.getPlayers().updateOne(eq("uuid", this.uuid), updates, new UpdateOptions().upsert(true));
Expand Down
130 changes: 118 additions & 12 deletions src/client/java/net/legitimoose/bot/scraper/Scraper.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import net.legitimoose.bot.LegitimooseBotClient;
import net.legitimoose.bot.util.DiscordUtil;
import net.legitimoose.bot.util.DiscordWebhook;
import net.legitimoose.bot.util.Unicode;
import net.minecraft.client.Minecraft;
import net.minecraft.core.component.DataComponents;
import net.minecraft.nbt.CompoundTag;
Expand All @@ -25,6 +26,7 @@

import java.io.IOException;
import java.net.URISyntaxException;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
Expand All @@ -46,7 +48,7 @@ public class Scraper {
private final DiscordWebhook errorWebhook = new DiscordWebhook(CONFIG.getString("errorWebhook"));

private final Pattern jamScorePattern = Pattern.compile("^CategoryScore\\(rank=(.*), score=(.*)\\)");
private final Pattern ownerNamePattern = Pattern.compile("^by (?:[^|]+\\|\\s*)?(.+)");
private final Pattern ownerNamePattern = Pattern.compile("^by (?:([^|]+) \\|\\s*)?(.+)");

private void waitSeconds(int time) {
try {
Expand Down Expand Up @@ -88,7 +90,7 @@ private void error(String message, Exception exception) throws IOException, URIS
errorWebhook.execute();
}

public void scrape() {
public void scrape() throws IOException, URISyntaxException, InterruptedException {
if (!CONFIG.getBoolean("scrape", true)) return;
Minecraft client = Minecraft.getInstance();
MongoCollection<Document> stats = Database.getStats();
Expand Down Expand Up @@ -130,6 +132,57 @@ public void scrape() {

client.player.closeContainer();

String lobbyRawDescription = "[";


World lobby = new World(
"Nov 28, 2023, 4:57 PM",
1701219420,

false,
true,

"5f4641cb-a718-4556-8c87-fbf153a8cc9a",
"Legitermoose",
Rank.Moose,

Minecraft.getInstance().getConnection().getOnlinePlayers().size(),

100,
100,

"",
"lobby",

// Change on moose/bot update
"1.21.10",

300000,
300000,

false,

"Legitimoose Lobby",
Unicode.normalize("Legitimoose Lobby"),
Minecraft.getInstance().getCurrentServer().motd.getString(),

"{\"text\":\"Legitimoose Lobby\",\"color\":\"white\",\"italic\":false}",
lobbyRawDescription + ComponentSerialization.CODEC.encodeStart(JsonOps.INSTANCE, Minecraft.getInstance().getCurrentServer().motd)
.result()
.get()
.toString() + "]",

-1,

new JsonObject(),

"minecraft:grass_block",

System.currentTimeMillis() / 1000L,
System.currentTimeMillis()
);
bulkUpsert(List.of(lobby), List.of());

client.player.connection.sendCommand("worlds");

waitSeconds(1);
Expand All @@ -140,6 +193,7 @@ public void scrape() {
LOGGER.info("Last page is: {}", max_pages);
for (int i = 1; i <= max_pages; i++) {
List<World> worlds = new ArrayList<>();
List<Player> players = new ArrayList<>();

Container inv = client.player.containerMenu.getSlot(0).container;
for (int j = 0; j <= 26; j++) {
Expand All @@ -159,14 +213,41 @@ public void scrape() {
}

String owner_name = "";
Rank owner_rank = Rank.Unknown;
int ownerLine = descriptionLines;
while (!itemStack.get(DataComponents.LORE).lines().get(ownerLine).getString().startsWith("by")) {
ownerLine++;
}
Matcher ownerNameMatcher = ownerNamePattern.matcher(itemStack.get(DataComponents.LORE).lines().get(ownerLine).getString());
if (ownerNameMatcher.find()) {
owner_name = ownerNameMatcher.group(1);
owner_name = ownerNameMatcher.group(2);
if (ownerNameMatcher.group(1) == null) {
owner_rank = Rank.Non;
} else {
owner_rank = Rank.getEnum(ownerNameMatcher.group(1));
}
}

String owner_uuid = getNbtString(publicBukkitValues, "owner");
Player dbPlayer = Database.getPlayers().find(eq("uuid", owner_uuid)).first();
int streak;
Instant last_joined;
if (dbPlayer == null) {
last_joined = Instant.EPOCH;
streak = 0;
} else {
if (dbPlayer.last_joined() != null) {
last_joined = dbPlayer.last_joined();
} else {
last_joined = Instant.EPOCH;
}
if (dbPlayer.streak() == null) {
streak = 0;
} else {
streak = dbPlayer.streak().days();
}
}
players.add(new Player(owner_uuid, owner_name, owner_rank, List.of(), new Player.Streak(streak, false), last_joined));

StringBuilder description = new StringBuilder();
for (int k = 0; k < descriptionLines; k++) {
Expand Down Expand Up @@ -211,15 +292,18 @@ public void scrape() {
}
}

String itemName = itemStack.get(DataComponents.CUSTOM_NAME).getString();

World world = new World(
getNbtString(publicBukkitValues, "creation_date"),
getNbtInt(publicBukkitValues, "creation_date_unix_seconds"),

getNbtBoolean(publicBukkitValues, "enforce_whitelist"),
getNbtBoolean(publicBukkitValues, "locked"),

getNbtString(publicBukkitValues, "owner"),
owner_uuid,
owner_name,
owner_rank,

getNbtInt(publicBukkitValues, "player_count"),
getNbtInt(publicBukkitValues, "max_players"),
Expand All @@ -234,7 +318,8 @@ public void scrape() {

getNbtBoolean(publicBukkitValues, "whitelist_on_version_change"),

itemStack.get(DataComponents.CUSTOM_NAME).getString(),
itemName,
Unicode.normalize(itemName),
description.toString(),

ComponentSerialization.CODEC.encodeStart(JsonOps.INSTANCE, itemStack.get(DataComponents.CUSTOM_NAME))
Expand All @@ -245,19 +330,17 @@ public void scrape() {

featured_instant,

jam_world,
jam_id,

jam,

itemStack.toString().substring(2),
System.currentTimeMillis() / 1000L,
System.currentTimeMillis()
);

worlds.add(world);
LOGGER.info("Scraped World {} {}: {}", j, world.world_uuid(), world.name());
}
bulkUpsert(worlds);
bulkUpsert(worlds, players);
// finally, click on next page button
LOGGER.info("Scraped page #{}", i);
Minecraft.getInstance()
Expand All @@ -271,8 +354,9 @@ public void scrape() {
LOGGER.info("Finished Scraping");
}

private void bulkUpsert(List<World> worlds) {
private void bulkUpsert(List<World> worlds, List<Player> players) {
List<WriteModel<World>> operations = new ArrayList<>();
List<WriteModel<Player>> playerOperations = new ArrayList<>();
LOGGER.info("writing world");
for (World world : worlds) {
Bson updates =
Expand All @@ -283,6 +367,7 @@ private void bulkUpsert(List<World> worlds) {
Updates.set("locked", world.locked()),
Updates.set("owner_uuid", world.owner_uuid()),
Updates.set("owner_name", world.owner_name()),
Updates.set("owner_rank", world.owner_rank()),
Updates.set("player_count", world.player_count()),
Updates.set("max_players", world.max_players()),
Updates.set("max_datapack_size", world.max_datapack_size()),
Expand All @@ -292,12 +377,11 @@ private void bulkUpsert(List<World> worlds) {
Updates.set("votes", world.votes()),
Updates.set("whitelist_on_version_change", world.whitelist_on_version_change()),
Updates.set("name", world.name()),
Updates.set("normalized_name", world.normalized_name()),
Updates.set("description", world.description()),
Updates.set("raw_name", Document.parse(world.raw_name())),
Updates.set("raw_description", BsonArray.parse(world.raw_description())),
Updates.set("featured_instant", world.featured_instant()),
Updates.set("jam_world", world.jam_world()),
Updates.set("jam_id", world.jam_id()),
Updates.set("jam", Document.parse(world.jam().toString())),
Updates.set("icon", world.icon()),
Updates.set("last_scraped", world.last_scraped()),
Expand All @@ -309,10 +393,32 @@ private void bulkUpsert(List<World> worlds) {
));
}

for (Player player : players) {
Bson playerUpdates =
Updates.combine(
Updates.set("uuid", player.uuid()),
Updates.set("name", player.name()),
Updates.set("rank", player.rank()),
Updates.set("streak", player.streak()),
Updates.set("last_joined", new BsonDateTime(player.last_joined().toEpochMilli())),
Updates.setOnInsert("blocked", player.blocked()));

playerOperations.add(new UpdateOneModel<>(
eq("uuid", player.uuid()),
playerUpdates,
new UpdateOptions().upsert(true)
));
}

if (!operations.isEmpty()) {
Database.getWorlds().bulkWrite(operations);
}

if (!playerOperations.isEmpty()) {
Database.getPlayers().bulkWrite(playerOperations);
}
LOGGER.info("Bulk wrote {} worlds", operations.size());
LOGGER.info("Bulk wrote {} players", playerOperations.size());
}

private String getNbtString(CompoundTag tag, String field) {
Expand Down
Loading
Loading