Add a custom currency API

This commit is contained in:
Aria 2023-04-21 17:44:33 -07:00
parent c6ff1afbdc
commit 1842387ec8
23 changed files with 783 additions and 42 deletions

View file

@ -6,9 +6,12 @@ import java.nio.file.Path;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;
import dev.zontreck.ariaslib.events.EventBus;
import dev.zontreck.libzontreck.currency.Bank;
import dev.zontreck.libzontreck.currency.CurrencyHelper;
import dev.zontreck.libzontreck.networking.NetworkEvents;
import org.slf4j.Logger;
import com.mojang.logging.LogUtils;
@ -44,6 +47,7 @@ public class LibZontreck {
public static final Path BASE_CONFIG;
public static final String PLAYER_INFO_URL = "https://api.mojang.com/users/profiles/minecraft/";
public static final String PLAYER_SKIN_URL = "https://sessionserver.mojang.com/session/minecraft/profile/";
public static final UUID NULL_ID;
public static LogicalSide CURRENT_SIDE;
@ -51,6 +55,7 @@ public class LibZontreck {
static{
NULL_ID = new UUID(0,0);
PROFILES = new HashMap<>();
BASE_CONFIG = FileTreeDatastore.of("libzontreck");
@ -74,7 +79,9 @@ public class LibZontreck {
MinecraftForge.EVENT_BUS.register(this);
MinecraftForge.EVENT_BUS.register(new ForgeEventHandlers());
MinecraftForge.EVENT_BUS.register(new Commands());
MinecraftForge.EVENT_BUS.register(new NetworkEvents());
EventBus.BUS.register(CurrencyHelper.class);
EventBus.BUS.register(Bank.class);
}
private void setup(final FMLCommonSetupEvent event)

View file

@ -0,0 +1,85 @@
package dev.zontreck.libzontreck.currency;
import dev.zontreck.ariaslib.events.EventBus;
import dev.zontreck.libzontreck.currency.events.TransactionHistoryFlushEvent;
import net.minecraft.core.UUIDUtil;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.nbt.Tag;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class Account
{
public UUID player_id;
public List<Transaction> history;
public int balance;
public AccountReference getRef()
{
return new AccountReference(player_id);
}
protected Account(UUID ID)
{
player_id=ID;
history=new ArrayList<>();
balance=0;
}
public CompoundTag save()
{
CompoundTag tag = new CompoundTag();
tag.put("id", NbtUtils.createUUID(player_id));
tag.putInt("balance", balance);
ListTag txs = new ListTag();
for(Transaction tx : history)
{
txs.add(tx.save());
}
tag.put("history", txs);
return tag;
}
public Account(CompoundTag tag)
{
player_id = NbtUtils.loadUUID(tag.get("id"));
balance = tag.getInt("balance");
history=new ArrayList<>();
ListTag lst = tag.getList("history", Tag.TAG_COMPOUND);
for(Tag t : lst){
CompoundTag lTag = (CompoundTag) t;
history.add(new Transaction(lTag));
}
}
/**
* Internal function for use only by the garbage collector to reduce memory footprint. Maximum of 20 transactions will be retained in the memory
*
* When the TX history grows beyond 20, the history should clear and it should get transferred to the long-term tx history storage. That file is not retained in memory, and only gets loaded when clearing to merge the lists. It is immediately saved and unloaded
* @see LongTermTransactionHistoryRecord
*/
public void flushTxHistory()
{
LongTermTransactionHistoryRecord rec = LongTermTransactionHistoryRecord.of(player_id);
rec.addHistory(history);
rec.commit();
EventBus.BUS.post(new TransactionHistoryFlushEvent(this, rec, history));
rec = null;
history = new ArrayList<>();
}
/**
* Checks if the account is a player or system account
* @return True if the player has a valid UUID
*/
public boolean isValidPlayer()
{
return !player_id.equals(new UUID(0,0));
}
}

View file

@ -0,0 +1,17 @@
package dev.zontreck.libzontreck.currency;
import java.util.UUID;
public class AccountReference
{
public UUID id;
public Account get()
{
return Bank.getAccount(id);
}
protected AccountReference(UUID ID)
{
id=ID;
}
}

View file

@ -0,0 +1,214 @@
package dev.zontreck.libzontreck.currency;
import com.google.common.collect.Lists;
import dev.zontreck.ariaslib.events.Event;
import dev.zontreck.ariaslib.events.EventBus;
import dev.zontreck.ariaslib.events.annotations.Subscribe;
import dev.zontreck.libzontreck.LibZontreck;
import dev.zontreck.libzontreck.chat.ChatColor;
import dev.zontreck.libzontreck.chat.ChatColorFactory;
import dev.zontreck.libzontreck.currency.events.BankAccountCreatedEvent;
import dev.zontreck.libzontreck.currency.events.BankReadyEvent;
import dev.zontreck.libzontreck.currency.events.TransactionEvent;
import dev.zontreck.libzontreck.currency.events.WalletUpdatedEvent;
import dev.zontreck.libzontreck.exceptions.InvalidSideException;
import dev.zontreck.libzontreck.networking.ModMessages;
import dev.zontreck.libzontreck.networking.packets.S2CWalletUpdatedPacket;
import dev.zontreck.libzontreck.profiles.Profile;
import dev.zontreck.libzontreck.profiles.UserProfileNotYetExistsException;
import dev.zontreck.libzontreck.util.ChatHelpers;
import dev.zontreck.libzontreck.util.ServerUtilities;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NbtIo;
import net.minecraft.nbt.Tag;
import net.minecraftforge.common.MinecraftForge;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
public class Bank
{
public static final Path BANK_DATA;
static {
BANK_DATA = LibZontreck.BASE_CONFIG.resolve("bank.nbt");
}
private Bank(){
load();
}
/**
* Internal function to deserialize NBT
*/
private void load()
{
try {
CompoundTag data = NbtIo.read(BANK_DATA.toFile());
accounts=new ArrayList<>();
ListTag acts = data.getList("accounts", Tag.TAG_COMPOUND);
for(Tag t : acts)
{
accounts.add(new Account((CompoundTag) t));
}
EventBus.BUS.post(new BankReadyEvent());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* Do not use manually, this saves the bank data to disk. This is fired automatically when transactions are posted to accounts.
*/
public void commit()
{
CompoundTag tag = new CompoundTag();
ListTag lst = new ListTag();
for(Account act : accounts)
{
lst.add(act.save());
}
tag.put("accounts", lst);
try {
NbtIo.write(tag, BANK_DATA.toFile());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private static final Bank instance = new Bank();
public List<Account> accounts = new ArrayList<>();
public static Account getAccount(UUID ID)
{
if(!hasAccount(ID))return null;
return instance.accounts.stream().filter(c->c.player_id.equals(ID)).collect(Collectors.toList()).get(0);
}
public static boolean hasAccount(UUID ID)
{
return instance.accounts.stream().filter(c->c.player_id.equals(ID)).collect(Collectors.toList()).stream().count()>0;
}
public static void makeAccount(UUID ID)
{
if(!hasAccount(ID)){
instance.accounts.add(new Account(ID));
instance.commit();
EventBus.BUS.post(new BankAccountCreatedEvent(getAccount(ID)));
}else return;
}
/**
* Attempts to post a transaction and perform the money transfer
*
* Please post your reason to the Reasons list when cancelling.
* @param tx The transaction being attempted
* @return True if the transaction has been accepted. False if the transaction was rejected, or insufficient funds.
*/
public static boolean postTx(Transaction tx) throws InvalidSideException {
if(ServerUtilities.isClient())return false;
TransactionEvent ev = new TransactionEvent(tx);
if(EventBus.BUS.post(ev))
{
// Send the list of reasons to the user
String reasonStr = String.join("\n", ev.reasons);
Account from = ev.tx.from.get();
Account to = ev.tx.to.get();
if(from.isValidPlayer())
{
ChatHelpers.broadcastTo(from.player_id, ChatHelpers.macro("!Dark_Gray![!Dark_Blue!Bank!Dark_Gray!] !Dark_Red!The transaction could not be completed because of the following reasons: " + reasonStr), LibZontreck.THE_SERVER);
}
if(to.isValidPlayer())
{
ChatHelpers.broadcastTo(to.player_id, ChatHelpers.macro("!Dark_Gray![!Dark_Blue!Bank!Dark_Gray!] !Dark_Red!The transaction could not be completed because of the following reasons: " + reasonStr), LibZontreck.THE_SERVER);
}
return false;
}else {
// Tx accepted
// Process funds now
Account from = ev.tx.from.get();
Account to = ev.tx.to.get();
int fromOld = from.balance;
int toOld = to.balance;
from.balance -= tx.amount;
to.balance += tx.amount;
from.history.add(tx);
to.history.add(tx);
Profile toProf = null;
Profile fromProf = null;
try{
fromProf = Profile.get_profile_of(from.player_id.toString());
}catch(UserProfileNotYetExistsException e){
e.printStackTrace();
}
try {
toProf = Profile.get_profile_of(to.player_id.toString());
} catch (UserProfileNotYetExistsException e) {
e.printStackTrace();
}
if(!from.isValidPlayer())
{
fromProf = Profile.SYSTEM;
}
if(!to.isValidPlayer())
{
toProf = Profile.SYSTEM;
}
if(from.isValidPlayer())
ChatHelpers.broadcastTo(from.player_id, ChatHelpers.macro("!Dark_Gray![!Dark_Blue!Bank!Dark_Gray!] !Dark_Green!You sent !White!${0} !Dark_green!to {1}", String.valueOf(tx.amount), toProf.name_color+toProf.nickname), LibZontreck.THE_SERVER);
if(to.isValidPlayer())
ChatHelpers.broadcastTo(from.player_id, ChatHelpers.macro("!Dark_Gray![!Dark_Blue!Bank!Dark_Gray!] {0} !Dark_Green!paid you ${1}", String.valueOf(tx.amount), toProf.name_color+toProf.nickname), LibZontreck.THE_SERVER);
if(to.isValidPlayer() && ServerUtilities.playerIsOffline(to.player_id)) Profile.unload(toProf);
if(from.isValidPlayer() && ServerUtilities.playerIsOffline(from.player_id))
Profile.unload(fromProf);
EventBus.BUS.post(new WalletUpdatedEvent(from.player_id, fromOld, from.balance, tx));
EventBus.BUS.post(new WalletUpdatedEvent(to.player_id, toOld, to.balance, tx));
if(from.isValidPlayer() && !ServerUtilities.playerIsOffline(from.player_id))
{
ModMessages.sendToPlayer(new S2CWalletUpdatedPacket(from.player_id, tx, from.balance, fromOld), ServerUtilities.getPlayerByID(from.player_id.toString()));
}
if(to.isValidPlayer() && !ServerUtilities.playerIsOffline(to.player_id))
{
ModMessages.sendToPlayer(new S2CWalletUpdatedPacket(to.player_id, tx, to.balance, toOld), ServerUtilities.getPlayerByID(to.player_id.toString()));
}
instance.commit();
}
return true;
}
/**
* This event is fired when wallets get updated. It cannot be cancelled
* @param ev The event containing the player ID and new+old wallet data
*/
@Subscribe
public static void onWalletUpdate(WalletUpdatedEvent ev)
{
}
}

View file

@ -1,14 +1,7 @@
package dev.zontreck.libzontreck.currency;
import dev.zontreck.ariaslib.events.annotations.Subscribe;
import dev.zontreck.libzontreck.currency.events.CurrencyBalanceCheckEvent;
import java.util.List;
public class CurrencyHelper {
@Subscribe
public static void onCurrencyBalanceCheck(CurrencyBalanceCheckEvent ev)
{
}
}

View file

@ -0,0 +1,72 @@
package dev.zontreck.libzontreck.currency;
import dev.zontreck.libzontreck.LibZontreck;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NbtIo;
import net.minecraft.nbt.Tag;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class LongTermTransactionHistoryRecord
{
public static final Path BASE;
static{
BASE = LibZontreck.BASE_CONFIG.resolve("transaction_history");
if(!BASE.toFile().exists())
{
BASE.toFile().mkdir();
}
}
public static Path ofPath(String name)
{
return BASE.resolve(name);
}
public void commit()
{
ListTag txs = new ListTag();
for(Transaction tx : history)
{
txs.add(tx.save());
}
CompoundTag tag = new CompoundTag();
tag.put("history", txs);
try {
NbtIo.write(tag, ofPath(player_id.toString()+".nbt").toFile());
}catch(IOException e){}
}
public UUID player_id;
public List<Transaction> history;
private LongTermTransactionHistoryRecord(UUID ID)
{
player_id=ID;
try {
CompoundTag tag = NbtIo.read(ofPath(ID.toString()+".nbt").toFile());
ListTag hist = tag.getList("history", Tag.TAG_COMPOUND);
history = new ArrayList<>();
for(Tag t : hist){
history.add(new Transaction((CompoundTag) t));
}
} catch (IOException e) {
history = new ArrayList<>();
}
}
public void addHistory(List<Transaction> other)
{
for (Transaction tx : other)
{
history.add(tx);
}
}
public static LongTermTransactionHistoryRecord of(UUID ID)
{
return new LongTermTransactionHistoryRecord(ID);
}
}

View file

@ -0,0 +1,42 @@
package dev.zontreck.libzontreck.currency;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtUtils;
import java.util.Date;
public class Transaction
{
public AccountReference from;
public AccountReference to;
public int amount;
public long timestamp;
public CompoundTag save()
{
CompoundTag tag = new CompoundTag();
tag.put("from", NbtUtils.createUUID(from.id));
tag.put("to", NbtUtils.createUUID(to.id));
tag.putInt("amount", amount);
tag.putLong("timestamp", timestamp);
return tag;
}
public Transaction(CompoundTag tag)
{
from = new AccountReference(NbtUtils.loadUUID(tag.get("from")));
to = new AccountReference(NbtUtils.loadUUID(tag.get("to")));
amount = tag.getInt("amount");
timestamp = tag.getLong("timestamp");
}
public Transaction(Account from, Account to, int amount, long ts)
{
this.from = from.getRef();
this.to = to.getRef();
this.amount=amount;
timestamp = ts;
}
}

View file

@ -0,0 +1,19 @@
package dev.zontreck.libzontreck.currency.events;
import dev.zontreck.ariaslib.events.Event;
import dev.zontreck.libzontreck.currency.Account;
public class BankAccountCreatedEvent extends Event
{
public Account account;
public BankAccountCreatedEvent(Account act)
{
account=act;
}
@Override
public boolean isCancellable() {
return false;
}
}

View file

@ -0,0 +1,17 @@
package dev.zontreck.libzontreck.currency.events;
import dev.zontreck.ariaslib.events.Event;
/**
* Contains no information by itself, it only signals that the Bank is open for business
*
* @see dev.zontreck.libzontreck.currency.Bank
*/
public class BankReadyEvent extends Event
{
@Override
public boolean isCancellable() {
return false;
}
}

View file

@ -1,20 +0,0 @@
package dev.zontreck.libzontreck.currency.events;
import dev.zontreck.ariaslib.events.Event;
import net.minecraft.world.entity.player.Player;
public class CurrencyBalanceCheckEvent extends Event
{
public final Player player;
public String balance;
public CurrencyBalanceCheckEvent(Player player)
{
this.player=player;
}
@Override
public boolean isCancellable() {
return false;
}
}

View file

@ -0,0 +1,26 @@
package dev.zontreck.libzontreck.currency.events;
import dev.zontreck.ariaslib.events.Event;
import dev.zontreck.libzontreck.currency.Transaction;
import java.util.List;
public class TransactionEvent extends Event
{
public Transaction tx;
/**
* This is the list of reasons why a transaction was aborted or blocked
*/
public List<String> reasons;
public TransactionEvent(Transaction txNew)
{
tx=txNew;
}
@Override
public boolean isCancellable() {
return true;
}
}

View file

@ -0,0 +1,27 @@
package dev.zontreck.libzontreck.currency.events;
import dev.zontreck.ariaslib.events.Event;
import dev.zontreck.libzontreck.currency.Account;
import dev.zontreck.libzontreck.currency.LongTermTransactionHistoryRecord;
import dev.zontreck.libzontreck.currency.Transaction;
import java.util.List;
public class TransactionHistoryFlushEvent extends Event
{
public LongTermTransactionHistoryRecord txHistory;
public Account associatedAccount;
public List<Transaction> flushed;
public TransactionHistoryFlushEvent(Account act, LongTermTransactionHistoryRecord txHistory, List<Transaction> flushed)
{
associatedAccount=act;
this.txHistory=txHistory;
this.flushed=flushed;
}
@Override
public boolean isCancellable() {
return false;
}
}

View file

@ -0,0 +1,25 @@
package dev.zontreck.libzontreck.currency.events;
import dev.zontreck.libzontreck.currency.Account;
import dev.zontreck.libzontreck.currency.Bank;
import net.minecraftforge.eventbus.api.Event;
import java.util.UUID;
/**
* This event is not cancellable!!
*/
public class WalletSyncEvent extends Event
{
public Account walletInformation;
public WalletSyncEvent(UUID player)
{
walletInformation = Bank.getAccount(player);
}
public WalletSyncEvent(Account act)
{
walletInformation = act;
}
}

View file

@ -0,0 +1,30 @@
package dev.zontreck.libzontreck.currency.events;
import dev.zontreck.ariaslib.events.Event;
import dev.zontreck.libzontreck.currency.Transaction;
import net.minecraft.world.entity.player.Player;
import java.util.UUID;
/**
* This event is dispatched on both the Client and the Server
*/
public class WalletUpdatedEvent extends Event
{
public int newBal;
public int oldBal;
public UUID player;
public Transaction tx;
public WalletUpdatedEvent(UUID player, int old, int newBal, Transaction tx)
{
this.player = player;
this.oldBal = old;
this.newBal = newBal;
this.tx=tx;
}
@Override
public boolean isCancellable() {
return false;
}
}

View file

@ -1,11 +1,13 @@
package dev.zontreck.libzontreck.events;
import dev.zontreck.ariaslib.events.Event;
import dev.zontreck.ariaslib.events.EventBus;
import dev.zontreck.ariaslib.util.DelayedExecutorService;
import dev.zontreck.libzontreck.LibZontreck;
import dev.zontreck.libzontreck.currency.events.CurrencyBalanceCheckEvent;
import dev.zontreck.libzontreck.currency.Account;
import dev.zontreck.libzontreck.currency.Bank;
import dev.zontreck.libzontreck.memory.PlayerContainer;
import dev.zontreck.libzontreck.networking.ModMessages;
import dev.zontreck.libzontreck.networking.packets.S2CWalletInitialSyncPacket;
import dev.zontreck.libzontreck.profiles.Profile;
import dev.zontreck.libzontreck.profiles.UserProfileNotYetExistsException;
import net.minecraft.server.level.ServerLevel;
@ -53,8 +55,8 @@ public class ForgeEventHandlers {
DelayedExecutorService.getInstance().schedule(new Runnable() {
@Override
public void run() {
CurrencyBalanceCheckEvent event= new CurrencyBalanceCheckEvent(ev.getEntity());
EventBus.BUS.post(event);
// Check player wallet, then send wallet to client
ModMessages.sendToPlayer(new S2CWalletInitialSyncPacket(player.getUUID()), player);
}
}, 10);
}

View file

@ -12,19 +12,20 @@ import net.minecraftforge.network.NetworkRegistry;
import net.minecraftforge.network.PacketDistributor;
import net.minecraftforge.network.simple.SimpleChannel;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Networking system!
*/
public class ModMessages {
private static SimpleChannel INSTANCE;
private static int PACKET_ID=0;
/**
* INTERNAL USE ONLY. DO NOT USE THIS, IF YOU ARE NOT LIBZONTRECK!!!!!!
* @return
* INTERNAL USE ONLY
*/
private static AtomicInteger PACKET_ID=new AtomicInteger(0);
public static int id()
{
return PACKET_ID++;
return PACKET_ID.getAndIncrement();
}
public static void register()
{
@ -44,12 +45,13 @@ public class ModMessages {
packet.register(net);
}
net.messageBuilder(ChestGUIOpenC2S.class, id(), NetworkDirection.PLAY_TO_SERVER)
net.messageBuilder(ChestGUIOpenC2S.class, PACKET_ID.getAndIncrement(), NetworkDirection.PLAY_TO_SERVER)
.decoder(ChestGUIOpenC2S::new)
.encoder(ChestGUIOpenC2S::toBytes)
.consumer(ChestGUIOpenC2S::handle)
.consumerMainThread(ChestGUIOpenC2S::handle)
.add();
}

View file

@ -0,0 +1,18 @@
package dev.zontreck.libzontreck.networking;
import dev.zontreck.libzontreck.events.RegisterPacketsEvent;
import dev.zontreck.libzontreck.networking.packets.S2CPlaySoundPacket;
import dev.zontreck.libzontreck.networking.packets.S2CWalletInitialSyncPacket;
import dev.zontreck.libzontreck.networking.packets.S2CWalletUpdatedPacket;
import net.minecraftforge.eventbus.api.SubscribeEvent;
public class NetworkEvents
{
@SubscribeEvent
public void onRegisterPackets(RegisterPacketsEvent ev)
{
ev.packets.add(new S2CWalletUpdatedPacket());
ev.packets.add(new S2CPlaySoundPacket());
ev.packets.add(new S2CWalletInitialSyncPacket());
}
}

View file

@ -6,6 +6,7 @@ import dev.zontreck.libzontreck.util.BinUtil;
import dev.zontreck.libzontreck.util.ServerUtilities;
import net.minecraft.client.Minecraft;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvent;
@ -25,17 +26,15 @@ public class S2CPlaySoundPacket implements IPacket
public S2CPlaySoundPacket(ResourceLocation loc) {
sound=loc;
}
public S2CPlaySoundPacket(){}
@Override
public void deserialize(CompoundTag data) {
// Deserializes the play sound packet
throw new UnsupportedOperationException("This operation is not supported in the play sound packet!");
}
@Override
public void serialize(CompoundTag data) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("Unimplemented method 'serialize'");
}
@Override

View file

@ -0,0 +1,70 @@
package dev.zontreck.libzontreck.networking.packets;
import dev.zontreck.libzontreck.currency.Account;
import dev.zontreck.libzontreck.currency.Bank;
import dev.zontreck.libzontreck.currency.events.WalletSyncEvent;
import dev.zontreck.libzontreck.util.ServerUtilities;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.EventBus;
import net.minecraftforge.network.NetworkDirection;
import net.minecraftforge.network.NetworkEvent;
import net.minecraftforge.network.simple.SimpleChannel;
import java.util.UUID;
import java.util.function.Supplier;
public class S2CWalletInitialSyncPacket implements IPacket
{
public Account act;
public S2CWalletInitialSyncPacket(FriendlyByteBuf buf)
{
act = new Account(buf.readNbt());
}
public S2CWalletInitialSyncPacket(Account act)
{
this.act=act;
}
public S2CWalletInitialSyncPacket(UUID ID)
{
this.act= Bank.getAccount(ID);
}
public S2CWalletInitialSyncPacket(){}
@Override
public void deserialize(CompoundTag data) {
}
@Override
public void serialize(CompoundTag data) {
}
@Override
public void toBytes(FriendlyByteBuf buf) {
buf.writeNbt(act.save());
}
@Override
public boolean handle(Supplier<NetworkEvent.Context> supplier) {
return ServerUtilities.handlePacket(supplier, new Runnable() {
@Override
public void run() {
MinecraftForge.EVENT_BUS.post(new WalletSyncEvent(act));
}
});
}
@Override
public NetworkDirection getDirection() {
return NetworkDirection.PLAY_TO_CLIENT;
}
@Override
public void register(SimpleChannel chan) {
ServerUtilities.registerPacket(chan, S2CWalletInitialSyncPacket.class, this, S2CWalletInitialSyncPacket::new);
}
}

View file

@ -0,0 +1,80 @@
package dev.zontreck.libzontreck.networking.packets;
import dev.zontreck.ariaslib.events.EventBus;
import dev.zontreck.libzontreck.currency.Transaction;
import dev.zontreck.libzontreck.currency.events.WalletUpdatedEvent;
import dev.zontreck.libzontreck.util.ServerUtilities;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.network.NetworkDirection;
import net.minecraftforge.network.NetworkEvent;
import net.minecraftforge.network.simple.SimpleChannel;
import java.util.UUID;
import java.util.function.Supplier;
public class S2CWalletUpdatedPacket implements IPacket
{
public UUID ID;
public Transaction tx;
public int balance;
public int oldBal;
public S2CWalletUpdatedPacket(FriendlyByteBuf buf)
{
ID = buf.readUUID();
tx = new Transaction(buf.readNbt());
balance = buf.readInt();
oldBal = buf.readInt();
}
public S2CWalletUpdatedPacket(UUID ID, Transaction tx, int bal, int old)
{
this.ID= ID;
this.tx=tx;
this.balance=bal;
oldBal=old;
}
public S2CWalletUpdatedPacket(){}
@Override
public void deserialize(CompoundTag data) {
}
@Override
public void serialize(CompoundTag data) {
}
@Override
public void toBytes(FriendlyByteBuf buf) {
buf.writeUUID(ID);
buf.writeNbt(tx.save());
buf.writeInt(balance);
buf.writeInt(oldBal);
}
@Override
public boolean handle(Supplier<NetworkEvent.Context> supplier) {
return ServerUtilities.handlePacket(supplier, new Runnable() {
@Override
public void run() {
EventBus.BUS.post(new WalletUpdatedEvent(ID, oldBal, balance, tx));
}
});
}
@Override
public NetworkDirection getDirection() {
return NetworkDirection.PLAY_TO_CLIENT;
}
@Override
public void register(SimpleChannel chan) {
ServerUtilities.registerPacket(chan, S2CWalletUpdatedPacket.class, this, S2CWalletUpdatedPacket::new);
}
}

View file

@ -27,11 +27,14 @@ public class Profile {
public Boolean flying;
public int available_vaults;
public int deaths;
public ServerPlayer player;
private File accessor;
private CompoundTag miscData;
public static final Path BASE;
public static final Profile SYSTEM;
static{
BASE = LibZontreck.BASE_CONFIG.resolve("profiles");
if(!BASE.toFile().exists())
@ -44,6 +47,8 @@ public class Profile {
LibZontreck.LOGGER.error("Failed to create profiles base directory");
}
}
SYSTEM = new Profile("SYSTEM", "", "SYSTEM", ChatColor.DARK_RED, LibZontreck.NULL_ID.toString(), "", "", false, 0, null, 0, null, null);
}
public Profile(String username, String prefix, String nickname, String name_color, String ID, String prefix_color, String chat_color, Boolean isFlying, int vaults, File vaultFile, int deathCount, ServerPlayer player, CompoundTag misc) {

View file

@ -45,6 +45,9 @@ public class ChatHelpers {
public void run()
{
ServerPlayer play = server.getPlayerList().getPlayer(ID);
if(play==null)return;
play.displayClientMessage(message, actionBar);
LibZontreck.LOGGER.info("[SERVER] -> ["+play.getName().getContents()+"] "+message.getContents());

View file

@ -5,6 +5,7 @@ import java.util.function.Function;
import java.util.function.Supplier;
import dev.zontreck.libzontreck.LibZontreck;
import dev.zontreck.libzontreck.exceptions.InvalidSideException;
import dev.zontreck.libzontreck.networking.ModMessages;
import dev.zontreck.libzontreck.networking.packets.IPacket;
import net.minecraft.network.FriendlyByteBuf;
@ -39,7 +40,7 @@ public class ServerUtilities
channel.messageBuilder(type, ModMessages.id(), packet.getDirection())
.decoder(decoder)
.encoder(X::toBytes)
.consumer(X::handle)
.consumerMainThread(X::handle)
.add();
}
@ -74,4 +75,11 @@ public class ServerUtilities
{
return !isServer();
}
public static boolean playerIsOffline(UUID ID) throws InvalidSideException {
if(isClient())throw new InvalidSideException("This can only be called on the server");
if(LibZontreck.THE_SERVER.getPlayerList().getPlayer(ID) == null) return true;
else return false;
}
}