aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jonas Gunz <himself@jonasgunz.de> 2020-05-14 23:30:02 +0200
committerGravatar Jonas Gunz <himself@jonasgunz.de> 2020-05-14 23:30:02 +0200
commit31980644504896aaf4b2ebdcdee3a18b9296f8c8 (patch)
treee2e9db475b1d90a885639a66c6a359dbc4b874c1
parent5fdacd274f92a976702cca515000cb22d3054f31 (diff)
parent5331f9ed822bf7e8853c4f1c352bc87844b5d4f0 (diff)
downloadparquet-31980644504896aaf4b2ebdcdee3a18b9296f8c8.tar.gz
Merge remote-tracking branch 'origin/master' into pre116
-rw-r--r--Readme.md21
-rw-r--r--src/main/java/re/jag/parquet/CustomStats.java14
-rw-r--r--src/main/java/re/jag/parquet/commands/Savedata.java123
-rw-r--r--src/main/java/re/jag/parquet/mixin/AbstractTraderEntityMixin.java26
-rw-r--r--src/main/java/re/jag/parquet/mixin/StatsMixin.java29
-rw-r--r--src/main/resources/fabric.mod.json9
-rw-r--r--src/main/resources/parquet.mixins.json4
7 files changed, 159 insertions, 67 deletions
diff --git a/Readme.md b/Readme.md
index 6c5576b..609f1ea 100644
--- a/Readme.md
+++ b/Readme.md
@@ -22,11 +22,13 @@ List all player savefiles, UUIDs are resolved to names if in usercache
#### `stats`
-Query user statistics and import them to the scoreboard. This work for both online and offline players, if they are in usercache.
+Query user statistics and import them to the scoreboard. This work for both online and offline players, if they are in
+usercache.
`/savedata stats PLAYER CRITERIA [import OBJECTIVE [MULTIPLIER]]`
-If `MULTIPLIER < 0` the score is modified with `1/MULTIPLIER`, since FloatArgumentType does not support exponentials like 1.3e-4
+If `MULTIPLIER < 0` the score is modified with `1/MULTIPLIER`, since FloatArgumentType does not support exponentials
+like 1.3e-4
## Features
@@ -45,14 +47,25 @@ A dispenser pointing into a cauldron can:
A dispenser pointing into an undyed Shulker Box can apply a color.
+### Advanced Villager Trade tracking
+
+`minecraft.custom:minecraft.traded_with_villager` only counts the amount of interactions with a Villager.
+Parquet provides more granular tracking of trades by counting every item purchased from Villagers under
+`minecraft.traded:<item>`.
+
+**Note:** Since `/scoreboard` command completion is handled client-side, they might not show up and have to be entered
+manually.
+
## Fixes
### [MC-111534](https://bugs.mojang.com/browse/MC-111534)
-Stat `minecraft.used:minecraft.firework_rocket` is only incremented, when the rocket is used on the ground, not during elytra flight.
+Stat `minecraft.used:minecraft.firework_rocket` is only incremented, when the rocket is used on the ground, not during
+elytra flight.
## "Fixes"
### [MC-126244](https://bugs.mojang.com/browse/MC-126244)
-Cartographer map trade replaced with dummy map around (0,0) to mitigate server crash in large worlds due to poor implementation of locateStructure.
+Cartographer map trade replaced with dummy map around (0,0) to mitigate server crash in large worlds due to poor
+implementation of locateStructure.
diff --git a/src/main/java/re/jag/parquet/CustomStats.java b/src/main/java/re/jag/parquet/CustomStats.java
new file mode 100644
index 0000000..c9d69b8
--- /dev/null
+++ b/src/main/java/re/jag/parquet/CustomStats.java
@@ -0,0 +1,14 @@
+package re.jag.parquet;
+
+import net.minecraft.item.Item;
+import net.minecraft.stat.StatType;
+import net.minecraft.util.Identifier;
+import net.minecraft.util.registry.Registry;
+
+public class CustomStats {
+ public static final StatType<Item> TRADED;
+
+ static {
+ TRADED = (StatType<Item>) Registry.STAT_TYPE.get(new Identifier("traded"));
+ }
+}
diff --git a/src/main/java/re/jag/parquet/commands/Savedata.java b/src/main/java/re/jag/parquet/commands/Savedata.java
index 3a8e6d6..11978ef 100644
--- a/src/main/java/re/jag/parquet/commands/Savedata.java
+++ b/src/main/java/re/jag/parquet/commands/Savedata.java
@@ -1,12 +1,13 @@
package re.jag.parquet.commands;
import java.io.File;
-import java.util.UUID;
+import java.util.*;
import static net.minecraft.server.command.CommandManager.literal;
import static net.minecraft.server.command.CommandSource.suggestMatching;
import static net.minecraft.server.command.CommandManager.argument;
+import com.google.common.collect.Lists;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.arguments.FloatArgumentType;
@@ -16,10 +17,6 @@ import com.mojang.authlib.GameProfile;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.command.arguments.ObjectiveArgumentType;
-import net.minecraft.command.arguments.ObjectiveCriteriaArgumentType;
-import net.minecraft.entity.EntityType;
-import net.minecraft.item.Item;
-import net.minecraft.scoreboard.ScoreboardCriterion;
import net.minecraft.scoreboard.ScoreboardObjective;
import net.minecraft.scoreboard.ScoreboardPlayerScore;
import net.minecraft.scoreboard.ServerScoreboard;
@@ -31,7 +28,6 @@ import re.jag.parquet.Parquet;
import net.minecraft.stat.ServerStatHandler;
import net.minecraft.stat.Stat;
import net.minecraft.stat.StatType;
-import net.minecraft.block.Block;
public class Savedata {
public static void register(CommandDispatcher<ServerCommandSource> dispatcher) {
@@ -46,23 +42,24 @@ public class Savedata {
then(literal("stats").
then(argument("player", StringArgumentType.word()).
suggests( (c, b) -> suggestMatching(c.getSource().getPlayerNames() , b)).
- then(argument("criteria", ObjectiveCriteriaArgumentType.objectiveCriteria()).
+ then(argument("criteria", StringArgumentType.string()).
+ suggests((c,b) -> suggestMatching(get_stat_list(), b)).
executes((c) -> print_player_stat (
c.getSource(),
StringArgumentType.getString(c, "player"),
- ObjectiveCriteriaArgumentType.getCriteria(c, "criteria")
+ StringArgumentType.getString(c, "criteria")
)).
then(literal("import").then(argument("score", ObjectiveArgumentType.objective()).
executes((c) -> import_stat_to_scoreboard (
c.getSource(),
- StringArgumentType.getString(c, "player"),
- ObjectiveCriteriaArgumentType.getCriteria(c, "criteria"),
+ StringArgumentType.getString(c, "player"),
+ StringArgumentType.getString(c, "criteria"),
ObjectiveArgumentType.getWritableObjective(c, "score"), 1)).
then(argument("multiplier", FloatArgumentType.floatArg()).
executes((c) -> import_stat_to_scoreboard(
c.getSource(),
- StringArgumentType.getString(c, "player"),
- ObjectiveCriteriaArgumentType.getCriteria(c, "criteria"),
+ StringArgumentType.getString(c, "player"),
+ StringArgumentType.getString(c, "criteria"),
ObjectiveArgumentType.getWritableObjective(c, "score"),
FloatArgumentType.getFloat(c, "multiplier"))
)
@@ -78,7 +75,52 @@ public class Savedata {
source.sendFeedback(new LiteralText("Hölp goes here"), false);
return 1;
}
-
+
+ private static int test(ServerCommandSource source, String string) {
+ source.sendFeedback(new LiteralText(string),false);
+ return 1;
+ }
+
+ private static List<String> get_stat_list() {
+ List<String> ret = Lists.newArrayList();
+ Iterator stat_type_iter = Registry.STAT_TYPE.iterator();
+
+ while(stat_type_iter.hasNext()) {
+ StatType<Object> statType = (StatType)stat_type_iter.next();
+ Iterator stat_iter = statType.getRegistry().iterator();
+
+ while(stat_iter.hasNext()) {
+ Object object = stat_iter.next();
+ String stat_name = "\"" + Stat.getName(statType, object) + "\"";
+ ret.add(stat_name);
+ }
+ }
+
+ return ret;
+ }
+
+ private static Stat<?> get_stat_from_string(String argument) {
+
+ int criteria_name_seperator = argument.indexOf(':');
+
+ String registry_name="";
+ String stat_name="";
+
+ if (criteria_name_seperator < 0) {
+ return null;
+ } else {
+ registry_name = argument.substring(0,criteria_name_seperator);
+ stat_name = argument.substring(criteria_name_seperator + 1, argument.length() );
+ }
+
+ StatType<Object> stat_type = (StatType<Object>) Registry.STAT_TYPE.get(Identifier.splitOn(registry_name, '.'));
+ Object stat_obj = stat_type.getRegistry().get(Identifier.splitOn(stat_name, '.'));
+
+ Stat stat = stat_type.getOrCreateStat(stat_obj);
+
+ return stat;
+ }
+
private static int list_local_saves(ServerCommandSource source) {
//TODO 1.16 fix
@@ -100,7 +142,7 @@ public class Savedata {
return 1;
}
- private static int import_stat_to_scoreboard(ServerCommandSource source, String player,ScoreboardCriterion stat, ScoreboardObjective objective, float multiplier) {
+ private static int import_stat_to_scoreboard(ServerCommandSource source, String player,String stat, ScoreboardObjective objective, float multiplier) {
int score = get_player_stat(source, player, stat);
if (score < 0)
return 0;
@@ -115,7 +157,7 @@ public class Savedata {
return 1;
}
- public static ServerStatHandler get_player_stat_handler(ServerCommandSource source, String player_name) {
+ private static ServerStatHandler get_player_stat_handler(ServerCommandSource source, String player_name) {
ServerPlayerEntity player = source.getMinecraftServer().getPlayerManager().getPlayer(player_name);
if (player != null) {
return player.getStatHandler();
@@ -148,7 +190,7 @@ public class Savedata {
*/
}
- private static int print_player_stat(ServerCommandSource source, String player, ScoreboardCriterion stat) {
+ private static int print_player_stat(ServerCommandSource source, String player, String stat) {
Integer stat_value = get_player_stat(source, player, stat);
if (stat_value >= 0)
@@ -159,54 +201,21 @@ public class Savedata {
return 0;
}
- private static int get_player_stat(ServerCommandSource source, String player_name, ScoreboardCriterion criteria) {
+ private static int get_player_stat(ServerCommandSource source, String player_name, String stat_name) {
ServerStatHandler stat_handler = get_player_stat_handler(source, player_name);
if (stat_handler == null) {
source.sendError(new LiteralText("Failed to get Statistics for Player " + player_name));
return -1;
}
-
- String criteria_name = criteria.getName();
- int criteria_name_seperator = criteria_name.indexOf(':');
-
- String registry_name="";
- String stat_name="";
-
- if (criteria_name_seperator < 0) {
- source.sendError(new LiteralText("Expected valid registry and stat ID"));
- return -1;
- } else {
- registry_name = criteria_name.substring(0,criteria_name_seperator);
- stat_name = criteria_name.substring(criteria_name_seperator + 1, criteria_name.length() );
- }
-
- StatType<?> stat_type = Registry.STAT_TYPE.get(Identifier.splitOn(registry_name, '.'));
- Object stat_obj = stat_type.getRegistry().get(Identifier.splitOn(stat_name, '.'));
-
- if (stat_obj instanceof Block) {
- @SuppressWarnings("unchecked")
- StatType<Block> stat_type_block = (StatType<Block>) stat_type;
- Stat<Block> stat = stat_type_block.getOrCreateStat((Block) stat_obj);
- return stat_handler.getStat(stat);
- } else if (stat_obj instanceof Item) {
- @SuppressWarnings("unchecked")
- StatType<Item> stat_type_item = (StatType<Item>) stat_type;
- Stat<Item> stat = stat_type_item.getOrCreateStat((Item) stat_obj);
- return stat_handler.getStat(stat);
- } else if (stat_obj instanceof Identifier) {
- @SuppressWarnings("unchecked")
- StatType<Identifier> stat_type_ident = (StatType<Identifier>) stat_type;
- Stat<Identifier> stat = stat_type_ident.getOrCreateStat((Identifier) stat_obj);
- return stat_handler.getStat(stat);
- } else if (stat_obj instanceof EntityType<?>) {
- @SuppressWarnings("unchecked")
- StatType<EntityType<?>> stat_type_ident = (StatType<EntityType<?>>) stat_type;
- Stat<EntityType<?>> stat = stat_type_ident.getOrCreateStat((EntityType<?>) stat_obj);
- return stat_handler.getStat(stat);
- } else {
- source.sendError(new LiteralText("Unknown Object " + stat_obj.getClass().getName()));
+
+ Stat stat = get_stat_from_string(stat_name);
+
+ if (stat == null) {
+ source.sendError(new LiteralText("Invalid stat: " + stat_name));
return -1;
}
+
+ return stat_handler.getStat(stat);
}
}
diff --git a/src/main/java/re/jag/parquet/mixin/AbstractTraderEntityMixin.java b/src/main/java/re/jag/parquet/mixin/AbstractTraderEntityMixin.java
new file mode 100644
index 0000000..654c7cd
--- /dev/null
+++ b/src/main/java/re/jag/parquet/mixin/AbstractTraderEntityMixin.java
@@ -0,0 +1,26 @@
+package re.jag.parquet.mixin;
+
+import net.minecraft.entity.passive.AbstractTraderEntity;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.server.network.ServerPlayerEntity;
+import net.minecraft.village.TradeOffer;
+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.CallbackInfo;
+import re.jag.parquet.CustomStats;
+import re.jag.parquet.Parquet;
+
+@Mixin(AbstractTraderEntity.class)
+public class AbstractTraderEntityMixin {
+ @Shadow
+ PlayerEntity customer;
+
+ @Inject(method="trade", at = @At("RETURN"))
+ private void onTrade(TradeOffer tradeOffer, CallbackInfo ci) {
+ if (this.customer instanceof ServerPlayerEntity) {
+ ((ServerPlayerEntity)customer).incrementStat( CustomStats.TRADED.getOrCreateStat( tradeOffer.getMutableSellItem().getItem() ) );
+ }
+ }
+}
diff --git a/src/main/java/re/jag/parquet/mixin/StatsMixin.java b/src/main/java/re/jag/parquet/mixin/StatsMixin.java
new file mode 100644
index 0000000..89463d8
--- /dev/null
+++ b/src/main/java/re/jag/parquet/mixin/StatsMixin.java
@@ -0,0 +1,29 @@
+package re.jag.parquet.mixin;
+
+import net.minecraft.item.Item;
+import net.minecraft.stat.StatFormatter;
+import net.minecraft.stat.StatType;
+import net.minecraft.stat.Stats;
+import net.minecraft.util.Identifier;
+import net.minecraft.util.registry.Registry;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+
+/**
+ * Has to be a Mixin for the game to load on startup.
+ * */
+
+@Mixin(Stats.class)
+public class StatsMixin {
+ @Shadow
+ private static StatType<Item> registerType(String string, Registry<Item> registry){ return null; };
+
+ @Shadow
+ private static Identifier register(String string, StatFormatter statFormatter) { return null; }
+
+ private static final StatType<Item> TRADED;
+
+ static {
+ TRADED = registerType("traded", Registry.ITEM);
+ }
+}
diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json
index a303dea..08363c8 100644
--- a/src/main/resources/fabric.mod.json
+++ b/src/main/resources/fabric.mod.json
@@ -2,15 +2,14 @@
"schemaVersion": 1,
"id": "parquet",
"version": "${version}",
-
- "name": "Vanilla",
- "description": "Who knows",
+ "name": "parquet",
+ "description": "Random stuff",
"authors": [
"kompetenzbolzen"
],
"contact": {
- "homepage": "https://jag.re/",
- "sources": "https://github.com/"
+ "homepage": "https://github.com/kompetenzbolzen/parquet",
+ "sources": "https://github.com/kompetenzbolzen/parquet"
},
"license": "",
diff --git a/src/main/resources/parquet.mixins.json b/src/main/resources/parquet.mixins.json
index 710b231..5aa1f0a 100644
--- a/src/main/resources/parquet.mixins.json
+++ b/src/main/resources/parquet.mixins.json
@@ -9,7 +9,9 @@
"ServerPlayerEntityMixin",
"BootstrapMixin",
"FireWorkItemMixin",
- "SellMapFactoryMixin"
+ "SellMapFactoryMixin",
+ "AbstractTraderEntityMixin",
+ "StatsMixin"
],
"server": [
],