Skip to content

Commit

Permalink
Fix Merge Conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
Kenny-Hui committed Jun 28, 2024
2 parents 53cfc2a + 82f7ade commit 5b5c5da
Show file tree
Hide file tree
Showing 22 changed files with 499 additions and 17 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ forge/src/main/java/**/mod
forge/src/main/java/net/londonunderground/mod
forge/src/main/resources/assets
forge/src/main/resources/data
forge/run
#forge/src/main/resources/META-INF

# java
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.lx862.jcm.mixin.modded.mtr;

import com.lx862.jcm.mod.block.FareSaverBlock;
import com.lx862.jcm.mod.data.TransactionLog;
import com.lx862.jcm.mod.data.TransactionEntry;
import com.lx862.jcm.mod.util.TextCategory;
import com.lx862.jcm.mod.util.TextUtil;
import org.mtr.core.data.Station;
Expand All @@ -12,28 +14,48 @@
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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;

@Mixin(value = TicketSystem.class, remap = false)
public abstract class MixinTicketSystem {

private static long fFare;

@Shadow
private static void incrementPlayerScore(World world, PlayerEntity player, String objective, String title, int value) {
}

@Inject(method = "onExit", at = @At(value = "INVOKE", target = "Lorg/mtr/mod/data/TicketSystem;incrementPlayerScore(Lorg/mtr/mapping/holder/World;Lorg/mtr/mapping/holder/PlayerEntity;Ljava/lang/String;Ljava/lang/String;I)V"), locals = LocalCapture.CAPTURE_FAILSOFT)
private static void onExit(World world, Station station, PlayerEntity player, boolean remindIfNoRecord, CallbackInfoReturnable<Boolean> cir, int entryZone1, int entryZone2, int entryZone3, boolean entered, long fare, long finalFare) {
if(entered && FareSaverBlock.discountList.containsKey(player.getUuid())) {
if (entered && FareSaverBlock.discountList.containsKey(player.getUuid())) {
long subsidyAmount = Math.min(finalFare, FareSaverBlock.discountList.get(player.getUuid()));
incrementPlayerScore(world, player, "mtr_balance", "Balance", (int)subsidyAmount);
incrementPlayerScore(world, player, "mtr_balance", "Balance", (int) subsidyAmount);

if(subsidyAmount < 0 && finalFare > 0) {
if (subsidyAmount < 0 && finalFare > 0) {
player.sendMessage(Text.cast(TextUtil.translatable(TextCategory.HUD, "faresaver.saved_sarcasm", -subsidyAmount)), false);
} else if(subsidyAmount > 0) {
} else if (subsidyAmount > 0) {
player.sendMessage(Text.cast(TextUtil.translatable(TextCategory.HUD, "faresaver.saved", subsidyAmount)), false);
}

FareSaverBlock.discountList.remove(player.getUuid());
}

fFare = finalFare;
}

@Inject(method = "onExit", at = @At("TAIL"))
private static void afterExit(World world, Station station, PlayerEntity player, boolean remindIfNoRecord, CallbackInfoReturnable<Boolean> cir) {
if (!world.isClient()) {
TransactionLog.writeLog(player, new TransactionEntry(station.getName(), -fFare, System.currentTimeMillis()));
}
}

@Inject(method = "addBalance", at = @At("TAIL"))
private static void addBalance(World world, PlayerEntity player, int amount, CallbackInfo ci) {
if (!world.isClient()) {
TransactionLog.writeLog(player, new TransactionEntry("Add Value", amount, System.currentTimeMillis()));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.lx862.jcm.mod.block.base.WallAttachedBlock;
import com.lx862.jcm.mod.block.behavior.EnquiryMachineBehavior;
import com.lx862.jcm.mod.data.EnquiryScreenType;
import com.lx862.jcm.mod.util.BlockUtil;
import com.lx862.jcm.mod.util.VoxelUtil;
import org.mtr.mapping.holder.*;
Expand All @@ -18,7 +19,7 @@ public VoxelShape getOutlineShape2(BlockState state, BlockView view, BlockPos po

@Override
public ActionResult onUse2(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
if(!world.isClient()) enquiry(world, player);
if(!world.isClient()) enquiry(EnquiryScreenType.RV, world, player);
return ActionResult.SUCCESS;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.lx862.jcm.mod.block.base.Vertical2Block;
import com.lx862.jcm.mod.block.behavior.EnquiryMachineBehavior;
import com.lx862.jcm.mod.data.EnquiryScreenType;
import com.lx862.jcm.mod.util.BlockUtil;
import com.lx862.jcm.mod.util.VoxelUtil;
import org.mtr.mapping.holder.*;
Expand All @@ -27,7 +28,7 @@ public VoxelShape getOutlineShape2(BlockState state, BlockView view, BlockPos po

@Override
public ActionResult onUse2(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
if(!world.isClient()) enquiry(world, player);
if(!world.isClient()) enquiry(EnquiryScreenType.CLASSIC, world, player);
return ActionResult.SUCCESS;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.lx862.jcm.mod.block.base.WallAttachedBlock;
import com.lx862.jcm.mod.block.behavior.EnquiryMachineBehavior;
import com.lx862.jcm.mod.data.EnquiryScreenType;
import com.lx862.jcm.mod.util.BlockUtil;
import com.lx862.jcm.mod.util.VoxelUtil;
import org.mtr.mapping.holder.*;
Expand All @@ -18,7 +19,7 @@ public VoxelShape getOutlineShape2(BlockState state, BlockView view, BlockPos po

@Override
public ActionResult onUse2(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
if(!world.isClient()) enquiry(world, player);
if(!world.isClient()) enquiry(EnquiryScreenType.CLASSIC, world, player);
return ActionResult.SUCCESS;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.lx862.jcm.mod.block.base.Vertical2Block;
import com.lx862.jcm.mod.block.behavior.EnquiryMachineBehavior;
import com.lx862.jcm.mod.data.EnquiryScreenType;
import com.lx862.jcm.mod.util.BlockUtil;
import com.lx862.jcm.mod.util.VoxelUtil;
import org.mtr.mapping.holder.*;
Expand All @@ -25,7 +26,7 @@ public VoxelShape getOutlineShape2(BlockState state, BlockView view, BlockPos po

@Override
public ActionResult onUse2(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
if(!world.isClient()) enquiry(world, player);
if(!world.isClient()) enquiry(EnquiryScreenType.RV, world, player);;
return ActionResult.SUCCESS;
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
package com.lx862.jcm.mod.block.behavior;

import com.lx862.jcm.mod.util.TextUtil;
import com.lx862.jcm.mod.data.EnquiryScreenType;
import com.lx862.jcm.mod.data.TransactionEntry;
import com.lx862.jcm.mod.data.TransactionLog;
import com.lx862.jcm.mod.network.gui.EnquiryUpdateGUIPacket;
import com.lx862.jcm.mod.registry.Networking;
import org.mtr.mapping.holder.PlayerEntity;
import org.mtr.mapping.holder.SoundCategory;
import org.mtr.mapping.holder.Text;
import org.mtr.mapping.holder.World;
import org.mtr.mod.SoundEvents;
import org.mtr.mod.data.TicketSystem;

import java.util.List;

public interface EnquiryMachineBehavior {
default void enquiry(World world, PlayerEntity player) {
int score = TicketSystem.getBalance(world, player);
player.sendMessage(Text.cast(TextUtil.translatable("gui.mtr.balance", String.valueOf(score))), true);
world.playSound((PlayerEntity) null, player.getBlockPos(), SoundEvents.TICKET_PROCESSOR_ENTRY.get(), SoundCategory.BLOCKS, 1, 1);
default void enquiry(EnquiryScreenType type, World world, PlayerEntity player) {
world.playSound(null, player.getBlockPos(), SoundEvents.TICKET_PROCESSOR_ENTRY.get(), SoundCategory.BLOCKS, 1, 1);

List<TransactionEntry> entries = TransactionLog.readLog(player, player.getUuidAsString());
Networking.sendPacketToClient(player, new EnquiryUpdateGUIPacket(type, entries, TicketSystem.getBalance(world, player)));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.lx862.jcm.mod.data;

public enum EnquiryScreenType {
RV,
CLASSIC,
NONE
}
38 changes: 38 additions & 0 deletions fabric/src/main/java/com/lx862/jcm/mod/data/TransactionEntry.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.lx862.jcm.mod.data;

import com.google.gson.JsonObject;

import java.text.SimpleDateFormat;

public class TransactionEntry {
public static final SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy HH:mm");
public final String source;
public final long time;
public final long amount;

public TransactionEntry(String source, long amount, long time) {
this.source = source;
this.amount = amount;
this.time = time;
}

public String getFormattedDate() {
return formatter.format(time);
}

public static TransactionEntry fromJson(JsonObject jsonObject) {
return new TransactionEntry(
jsonObject.get("source").getAsString(),
jsonObject.get("amount").getAsInt(),
jsonObject.get("time").getAsLong()
);
}

public JsonObject toJson() {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("source", source);
jsonObject.addProperty("amount", amount);
jsonObject.addProperty("time", time);
return jsonObject;
}
}
67 changes: 67 additions & 0 deletions fabric/src/main/java/com/lx862/jcm/mod/data/TransactionLog.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.lx862.jcm.mod.data;

import com.google.gson.*;
import com.lx862.jcm.mod.Constants;
import com.lx862.jcm.mod.util.JCMLogger;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

import org.mtr.mapping.holder.PlayerEntity;
import org.mtr.mapping.holder.WorldSavePath;

public class TransactionLog {
public static final int MAX_ENTRY_LIMIT = 50;

public static void writeLog(PlayerEntity player, TransactionEntry entry) {
Path savePath = getSavePath(player);
savePath.getParent().toFile().mkdirs();

JsonObject jsonObject = new JsonObject();
JsonArray entryArray = new JsonArray();

try {
if (Files.exists(savePath)) {
jsonObject = new JsonParser().parse(String.join("", Files.readAllLines(savePath))).getAsJsonObject();
entryArray = jsonObject.getAsJsonArray("entries");
}

entryArray.add(entry.toJson());
if(entryArray.size() > MAX_ENTRY_LIMIT) entryArray.remove(0);
jsonObject.add("entries", entryArray);

Gson gson = new GsonBuilder().setPrettyPrinting().create();
Files.write(savePath, gson.toJson(jsonObject).getBytes());
} catch (IOException e) {
JCMLogger.error("Error saving data to JSON file: {}", e.getMessage());
}
}

public static List<TransactionEntry> readLog(PlayerEntity player, String playerName) {
Path savePath = getSavePath(player);
savePath.getParent().toFile().mkdirs();

List<TransactionEntry> entries = new ArrayList<>();
try {
if (Files.exists(savePath)) {
JsonObject jsonObject = new JsonParser().parse(String.join("", Files.readAllLines(savePath))).getAsJsonObject();
JsonArray playerDataArray = jsonObject.getAsJsonArray("entries");
for (JsonElement element : playerDataArray) {
entries.add(TransactionEntry.fromJson(element.getAsJsonObject()));
}
}
} catch (IOException e) {
JCMLogger.error("Error reading data from JSON file: {}", e.getMessage());
}
return entries;
}

public static Path getSavePath(PlayerEntity player) {
Path saveDirectory = player.getServer().getSavePath(WorldSavePath.getRootMapped()).resolve(Constants.MOD_ID).resolve("player_data");
saveDirectory.toFile().mkdirs();
return saveDirectory.resolve(player.getUuidAsString() + ".json");
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
package com.lx862.jcm.mod.network.gui;

import com.lx862.jcm.mod.data.EnquiryScreenType;
import com.lx862.jcm.mod.data.TransactionEntry;
import com.lx862.jcm.mod.render.gui.screen.*;
import org.mtr.mapping.holder.BlockPos;
import org.mtr.mapping.holder.MinecraftClient;
import org.mtr.mapping.holder.Screen;

import java.util.List;

/**
* Because Network Packet class is shared between Client and Server, they must not contain any client code
* This serves as an abstraction to perform client-specific operation.
*/
public final class ClientHelper {

public static void openButterflyLightScreen(BlockPos blockPos, int secondsToBlink) {
Expand All @@ -26,4 +34,13 @@ public static void openSoundLooperGUIScreen(BlockPos blockPos, BlockPos corner1,
public static void openSubsidyMachineGUIScreen(BlockPos blockPos, int pricePerUse,int cooldown) {
MinecraftClient.getInstance().openScreen(new Screen(new SubsidyMachineScreen(blockPos, pricePerUse, cooldown)));
}

public static void openEnquiryScreen(EnquiryScreenType type, List<TransactionEntry> entries, int remainingBalance) {
if(type == EnquiryScreenType.RV) {
MinecraftClient.getInstance().openScreen(new Screen(new RVEnquiryScreen(entries, remainingBalance)));
}
if(type == EnquiryScreenType.CLASSIC) {
MinecraftClient.getInstance().openScreen(new Screen(new EnquiryScreen(entries, remainingBalance)));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.lx862.jcm.mod.network.gui;

import com.lx862.jcm.mod.data.EnquiryScreenType;
import com.lx862.jcm.mod.data.TransactionEntry;
import org.mtr.mapping.registry.PacketHandler;
import org.mtr.mapping.tool.PacketBufferReceiver;
import org.mtr.mapping.tool.PacketBufferSender;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public class EnquiryUpdateGUIPacket extends PacketHandler {

private final EnquiryScreenType type;
private final List<TransactionEntry> entries;
private final int entryCount;
private final int remainingBalance;

public EnquiryUpdateGUIPacket(PacketBufferReceiver packetBufferReceiver) {
this.entries = new ArrayList<>();
this.type = EnquiryScreenType.valueOf(packetBufferReceiver.readString());
this.remainingBalance = packetBufferReceiver.readInt();

this.entryCount = packetBufferReceiver.readInt();
for (int i = 0; i < entryCount; i++) {
String source = packetBufferReceiver.readString();
long amount = packetBufferReceiver.readLong();
long time = packetBufferReceiver.readLong();
entries.add(new TransactionEntry(source, amount, time));
}
}

public EnquiryUpdateGUIPacket(EnquiryScreenType type, List<TransactionEntry> entries, int remainingBalance) {
this.type = type;
this.entries = entries.stream().sorted((a, b) -> (int)(b.time - a.time)).collect(Collectors.toList());
this.entryCount = entries.size();
this.remainingBalance = remainingBalance;
}

@Override
public void write(PacketBufferSender packetBufferSender) {
packetBufferSender.writeString(type.toString());
packetBufferSender.writeInt(remainingBalance);
packetBufferSender.writeInt(entries.size());

for (TransactionEntry transactionEntry : entries) {
packetBufferSender.writeString(transactionEntry.source);
packetBufferSender.writeLong(transactionEntry.amount);
packetBufferSender.writeLong(transactionEntry.time);
}
}

@Override
public void runClient() {
ClientHelper.openEnquiryScreen(type, entries, remainingBalance);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public static void register() {
registerPacket(PIDSUpdatePacket.class, PIDSUpdatePacket::new);
registerPacket(SoundLooperUpdatePacket.class, SoundLooperUpdatePacket::new);
registerPacket(SubsidyMachineUpdatePacket.class, SubsidyMachineUpdatePacket::new);
registerPacket(EnquiryUpdateGUIPacket.class, EnquiryUpdateGUIPacket::new);

// GUI Screen
registerPacket(ButterflyLightGUIPacket.class, ButterflyLightGUIPacket::new);
Expand Down
Loading

0 comments on commit 5b5c5da

Please sign in to comment.