commit 701912347f252fa5ede2d9f4ed1086e9358fcc05 Author: Gæmer <78032176+BigGaemer@users.noreply.github.com> Date: Tue May 6 13:42:46 2025 +0200 Initial commit diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..09cd281 --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +# gradle + +.gradle/ +build/ +out/ +classes/ + +# eclipse + +*.launch + +# idea + +.idea/ +*.iml +*.ipr +*.iws + +# vscode + +.settings/ +.vscode/ +bin/ +.classpath +.project + +# macos + +*.DS_Store + +# fabric + +run/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3167d76 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 IAmSneak + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..7e17da0 --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ +Basic economy for the fabric modloader using diamonds as currency. Uses the "/diamonds" command along with the following subcommands + +- balance [Optional: player] - tells user how much money the player has + +- deposit - takes currency from your inventory and adds it to your account + +- send [player] [int] - takes $[int] from your account and adds them to [player]'s account + +- top [Optional: int] - tells user current rank along with who has the most money, int for page # + +- withdraw [int] - takes $[int] from your account and puts it into your inventory in as many high value currency items as possible + + +Operator only subcommands: + +- modify [players] [int] - modifies [players] money by $[int] + +- take [players] [int] - takes $[int] from [players] + + +Placeholders: +- %diamondeconomy:rank_from_player% +- %diamondeconomy:rank_from_string_uuid% +- %diamondeconomy:balance_from_player% +- %diamondeconomy:balance_from_name% +- %diamondeconomy:balance_from_rank% +- %diamondeconomy:balance_from_string_uuid% + + +Downloads: +- https://www.curseforge.com/minecraft/mc-mods/diamond-economy +- https://modrinth.com/mod/diamond-economy diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..4b70e8b --- /dev/null +++ b/build.gradle @@ -0,0 +1,64 @@ +plugins { + id 'fabric-loom' version '1.2-SNAPSHOT' + id 'maven-publish' +} + +sourceCompatibility = JavaVersion.VERSION_17 +targetCompatibility = JavaVersion.VERSION_17 + +archivesBaseName = project.archives_base_name +version = project.mod_version +group = project.maven_group + +repositories { + mavenCentral() + maven { url "https://maven.fabricmc.net/" } + maven { url "https://maven.shedaniel.me/" } + maven { url "https://maven.nucleoid.xyz/" } +} + +dependencies { + // To change the versions see the gradle.properties file + minecraft "com.mojang:minecraft:${project.minecraft_version}" + mappings loom.officialMojangMappings() + modImplementation "net.fabricmc:fabric-loader:${project.fabric_loader_version}" + modApi "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}" + implementation(include("org.xerial:sqlite-jdbc:${project.sqlite_version}")) + modApi("me.shedaniel.cloth:cloth-config-fabric:${project.cloth_config_version}") { + exclude(group: "net.fabricmc.fabric-api") + } + modImplementation include("eu.pb4:placeholder-api:${project.placeholder_api_version}") +} + +processResources { + inputs.property "version", project.version + + filesMatching("fabric.mod.json") { + expand "version": project.version + } +} + +tasks.withType(JavaCompile).configureEach { + it.options.encoding = "UTF-8" + it.options.release = 17 +} +java { + withSourcesJar() +} + +jar { + from("LICENSE") { + rename { "${it}_${project.archivesBaseName}"} + } +} + +publishing { + publications { + mavenJava(MavenPublication) { + from components.java + } + } + + repositories { + } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..6a9ea43 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,18 @@ +# Done to increase the memory available to gradle. +org.gradle.jvmargs=-Xmx1G + +minecraft_version=1.20 + +# Fabric Properties +fabric_loader_version=0.14.21 +fabric_api_version=0.83.0+1.20 + +# Mod Properties +mod_version = 1.5.6 +maven_group = com.gmail.sneakdevs.diamondeconomy +archives_base_name = diamondeconomy + +# Dependencies +cloth_config_version=11.0.99 +placeholder_api_version=2.1.1+1.20 +sqlite_version=3.36.0.3 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..c1962a7 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..37aef8d --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip +networkTimeout=10000 +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..37292d5 --- /dev/null +++ b/gradlew @@ -0,0 +1,232 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" \ No newline at end of file diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..477c896 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega \ No newline at end of file diff --git a/jitpack.yml b/jitpack.yml new file mode 100644 index 0000000..8ac1587 --- /dev/null +++ b/jitpack.yml @@ -0,0 +1,5 @@ +jdk: + - openjdk17 +before_install: + - sdk install java 17.0.5-open + - sdk use java 17.0.5-open \ No newline at end of file diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..2875cde --- /dev/null +++ b/settings.gradle @@ -0,0 +1,9 @@ +pluginManagement { + repositories { + maven { + name = 'Fabric' + url = 'https://maven.fabricmc.net/' + } + gradlePluginPortal() + } +} \ No newline at end of file diff --git a/src/main/java/com/gmail/sneakdevs/diamondeconomy/DiamondEconomy.java b/src/main/java/com/gmail/sneakdevs/diamondeconomy/DiamondEconomy.java new file mode 100644 index 0000000..8c04559 --- /dev/null +++ b/src/main/java/com/gmail/sneakdevs/diamondeconomy/DiamondEconomy.java @@ -0,0 +1,82 @@ +package com.gmail.sneakdevs.diamondeconomy; + +import com.gmail.sneakdevs.diamondeconomy.command.DiamondEconomyCommands; +import com.gmail.sneakdevs.diamondeconomy.config.DiamondEconomyConfig; +import com.gmail.sneakdevs.diamondeconomy.sql.SQLiteDatabaseManager; +import eu.pb4.placeholders.api.PlaceholderResult; +import eu.pb4.placeholders.api.Placeholders; +import me.shedaniel.autoconfig.AutoConfig; +import me.shedaniel.autoconfig.serializer.JanksonConfigSerializer; +import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.level.storage.LevelResource; + +import java.io.File; +import java.util.ArrayList; + +public class DiamondEconomy implements ModInitializer { + public static final String MODID = "diamondeconomy"; + public static ArrayList tableRegistry = new ArrayList<>(); + + public static void initServer(MinecraftServer server) { + DiamondUtils.registerTable("CREATE TABLE IF NOT EXISTS diamonds (uuid text PRIMARY KEY, name text NOT NULL, money integer DEFAULT 0);"); + SQLiteDatabaseManager.createNewDatabase((DiamondEconomyConfig.getInstance().fileLocation != null) ? (new File(DiamondEconomyConfig.getInstance().fileLocation)) : server.getWorldPath(LevelResource.ROOT).resolve(DiamondEconomy.MODID + ".sqlite").toFile()); + } + + public static void registerPlaceholders() { + Placeholders.register(new ResourceLocation(MODID, "rank_from_player"), (ctx, arg) -> { + if (ctx.hasPlayer()) { + return PlaceholderResult.value(Component.literal(DiamondUtils.getDatabaseManager().playerRank(ctx.player().getStringUUID()) + "")); + } else { + return PlaceholderResult.invalid(); + } + }); + Placeholders.register(new ResourceLocation(MODID, "rank_from_string_uuid"), (ctx, arg) -> { + if (arg != null) { + return PlaceholderResult.value(Component.literal(DiamondUtils.getDatabaseManager().playerRank(arg) + "")); + } else { + return PlaceholderResult.invalid(); + } + }); + Placeholders.register(new ResourceLocation(MODID, "balance_from_player"), (ctx, arg) -> { + if (ctx.hasPlayer()) { + return PlaceholderResult.value(Component.literal(DiamondUtils.getDatabaseManager().getBalanceFromUUID(ctx.player().getStringUUID()) + "")); + } else { + return PlaceholderResult.invalid(); + } + }); + Placeholders.register(new ResourceLocation(MODID, "balance_from_string_uuid"), (ctx, arg) -> { + if (arg != null) { + return PlaceholderResult.value(Component.literal(DiamondUtils.getDatabaseManager().getBalanceFromUUID(arg) + "")); + } else { + return PlaceholderResult.invalid(); + } + }); + Placeholders.register(new ResourceLocation(MODID, "balance_from_name"), (ctx, arg) -> { + if (arg != null) { + return PlaceholderResult.value(Component.literal(DiamondUtils.getDatabaseManager().getBalanceFromName(arg) + "")); + } else { + return PlaceholderResult.invalid(); + } + }); + Placeholders.register(new ResourceLocation(MODID, "player_from_rank"), (ctx, arg) -> { + if (arg != null) { + return PlaceholderResult.value(Component.literal(DiamondUtils.getDatabaseManager().rank(Integer.parseInt(arg)))); + } else { + return PlaceholderResult.invalid(); + } + }); + } + + @Override + public void onInitialize() { + AutoConfig.register(DiamondEconomyConfig.class, JanksonConfigSerializer::new); + registerPlaceholders(); + CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> DiamondEconomyCommands.register(dispatcher)); + ServerLifecycleEvents.SERVER_STARTING.register(DiamondEconomy::initServer); + } +} diff --git a/src/main/java/com/gmail/sneakdevs/diamondeconomy/DiamondUtils.java b/src/main/java/com/gmail/sneakdevs/diamondeconomy/DiamondUtils.java new file mode 100644 index 0000000..35ddfc6 --- /dev/null +++ b/src/main/java/com/gmail/sneakdevs/diamondeconomy/DiamondUtils.java @@ -0,0 +1,69 @@ +package com.gmail.sneakdevs.diamondeconomy; + +import com.gmail.sneakdevs.diamondeconomy.config.DiamondEconomyConfig; +import com.gmail.sneakdevs.diamondeconomy.sql.DatabaseManager; +import com.gmail.sneakdevs.diamondeconomy.sql.SQLiteDatabaseManager; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; + +public class DiamondUtils { + public static void registerTable(String query){ + DiamondEconomy.tableRegistry.add(query); + } + + public static DatabaseManager getDatabaseManager() { + return new SQLiteDatabaseManager(); + } + + public static int dropItem(int amount, ServerPlayer player) { + + + if (DiamondEconomyConfig.getInstance().greedyWithdraw) { + + for (int i = DiamondEconomyConfig.getCurrencyValues().length - 1; i >= 0 && amount > 0; i--) { + + int val = DiamondEconomyConfig.getCurrencyValues()[i]; + int currSize = DiamondEconomyConfig.getCurrency(i).getMaxStackSize(); + Item curr = DiamondEconomyConfig.getCurrency(i); + + while (amount >= val * currSize) { + ItemEntity itemEntity = player.drop(new ItemStack(curr, currSize), true); + itemEntity.setNoPickUpDelay(); + amount -= val * currSize; + } + + if (amount >= val) { + ItemEntity itemEntity = player.drop(new ItemStack(curr, amount / val), true); + itemEntity.setNoPickUpDelay(); + amount -= amount / val * val; + } + + } + + } else { + + int val = DiamondEconomyConfig.getCurrencyValues()[0]; + int currSize = DiamondEconomyConfig.getCurrency(0).getMaxStackSize(); + Item curr = DiamondEconomyConfig.getCurrency(0); + + while (amount >= val * currSize) { + ItemEntity itemEntity = player.drop(new ItemStack(curr, currSize), true); + itemEntity.setNoPickUpDelay(); + amount -= val * currSize; + } + + if (amount >= val) { + ItemEntity itemEntity = player.drop(new ItemStack(curr, amount / val), true); + itemEntity.setNoPickUpDelay(); + amount -= amount / val * val; + } + } + + DatabaseManager dm = getDatabaseManager(); + dm.changeBalance(player.getStringUUID(), amount); + + return amount; + } +} diff --git a/src/main/java/com/gmail/sneakdevs/diamondeconomy/command/BalanceCommand.java b/src/main/java/com/gmail/sneakdevs/diamondeconomy/command/BalanceCommand.java new file mode 100644 index 0000000..def7d78 --- /dev/null +++ b/src/main/java/com/gmail/sneakdevs/diamondeconomy/command/BalanceCommand.java @@ -0,0 +1,40 @@ +package com.gmail.sneakdevs.diamondeconomy.command; + +import com.gmail.sneakdevs.diamondeconomy.DiamondUtils; +import com.gmail.sneakdevs.diamondeconomy.config.DiamondEconomyConfig; +import com.gmail.sneakdevs.diamondeconomy.sql.DatabaseManager; +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; +import net.minecraft.commands.arguments.EntityArgument; +import net.minecraft.network.chat.Component; + +public class BalanceCommand { + public static LiteralArgumentBuilder buildCommand(){ + return Commands.literal(DiamondEconomyConfig.getInstance().balanceCommandName) + .then( + Commands.argument("playerName", StringArgumentType.string()) + .executes(e -> { + String string = StringArgumentType.getString(e, "playerName"); + return balanceCommand(e, string); + }) + ) + .then( + Commands.argument("player", EntityArgument.player()) + .executes(e -> { + String player = EntityArgument.getPlayer(e, "player").getName().getString(); + return balanceCommand(e, player); + }) + ) + .executes(e -> balanceCommand(e, e.getSource().getPlayerOrException().getName().getString())); + } + + public static int balanceCommand(CommandContext ctx, String player) { + DatabaseManager dm = DiamondUtils.getDatabaseManager(); + int bal = dm.getBalanceFromName(player); + ctx.getSource().sendSuccess(() -> Component.literal((bal > -1) ? (player + " has $" + bal) : ("No account was found for player with the name \"" + player + "\"")), false); + return 1; + } +} diff --git a/src/main/java/com/gmail/sneakdevs/diamondeconomy/command/DepositCommand.java b/src/main/java/com/gmail/sneakdevs/diamondeconomy/command/DepositCommand.java new file mode 100644 index 0000000..cd262a6 --- /dev/null +++ b/src/main/java/com/gmail/sneakdevs/diamondeconomy/command/DepositCommand.java @@ -0,0 +1,42 @@ +package com.gmail.sneakdevs.diamondeconomy.command; + +import com.gmail.sneakdevs.diamondeconomy.DiamondUtils; +import com.gmail.sneakdevs.diamondeconomy.config.DiamondEconomyConfig; +import com.gmail.sneakdevs.diamondeconomy.sql.DatabaseManager; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; + +public class DepositCommand { + public static LiteralArgumentBuilder buildCommand(){ + return Commands.literal(DiamondEconomyConfig.getInstance().depositCommandName) + .executes(DepositCommand::depositCommand); + } + + public static int depositCommand(CommandContext ctx) throws CommandSyntaxException { + ServerPlayer player = ctx.getSource().getPlayerOrException(); + DatabaseManager dm = DiamondUtils.getDatabaseManager(); + int currencyCount = 0; + for (int i = DiamondEconomyConfig.getCurrencyValues().length - 1; i >= 0; i--) { + for (int j = 0; j < player.getInventory().getContainerSize(); j++) { + if (player.getInventory().getItem(j).getItem().equals(DiamondEconomyConfig.getCurrency(i))) { + currencyCount += player.getInventory().getItem(j).getCount() * DiamondEconomyConfig.getCurrencyValues()[i]; + player.getInventory().setItem(j, new ItemStack(Items.AIR)); + } + } + } + if (dm.changeBalance(player.getStringUUID(), currencyCount)) { + String output = "Added $" + currencyCount + " to your account"; + ctx.getSource().sendSuccess(() -> Component.literal(output), false); + } else { + DiamondUtils.dropItem(currencyCount, player); + } + return 1; + } +} diff --git a/src/main/java/com/gmail/sneakdevs/diamondeconomy/command/DiamondEconomyCommands.java b/src/main/java/com/gmail/sneakdevs/diamondeconomy/command/DiamondEconomyCommands.java new file mode 100644 index 0000000..917e19c --- /dev/null +++ b/src/main/java/com/gmail/sneakdevs/diamondeconomy/command/DiamondEconomyCommands.java @@ -0,0 +1,56 @@ +package com.gmail.sneakdevs.diamondeconomy.command; + +import com.gmail.sneakdevs.diamondeconomy.config.DiamondEconomyConfig; +import com.mojang.brigadier.CommandDispatcher; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; + +public class DiamondEconomyCommands { + public static void register(CommandDispatcher dispatcher) { + if (DiamondEconomyConfig.getInstance().commandName == null) { + if (DiamondEconomyConfig.getInstance().modifyCommandName != null) { + dispatcher.register(ModifyCommand.buildCommand()); + } + if (DiamondEconomyConfig.getInstance().balanceCommandName != null) { + dispatcher.register(BalanceCommand.buildCommand()); + } + if (DiamondEconomyConfig.getInstance().topCommandName != null) { + dispatcher.register(TopCommand.buildCommand()); + } + if (DiamondEconomyConfig.getInstance().depositCommandName != null) { + dispatcher.register(DepositCommand.buildCommand()); + } + if (DiamondEconomyConfig.getInstance().sendCommandName != null) { + dispatcher.register(SendCommand.buildCommand()); + } + if (DiamondEconomyConfig.getInstance().setCommandName != null) { + dispatcher.register(SetCommand.buildCommand()); + } + if (DiamondEconomyConfig.getInstance().withdrawCommandName != null) { + dispatcher.register(WithdrawCommand.buildCommand()); + } + } else { + if (DiamondEconomyConfig.getInstance().modifyCommandName != null) { + dispatcher.register(Commands.literal(DiamondEconomyConfig.getInstance().commandName).then(ModifyCommand.buildCommand())); + } + if (DiamondEconomyConfig.getInstance().balanceCommandName != null) { + dispatcher.register(Commands.literal(DiamondEconomyConfig.getInstance().commandName).then(BalanceCommand.buildCommand())); + } + if (DiamondEconomyConfig.getInstance().topCommandName != null) { + dispatcher.register(Commands.literal(DiamondEconomyConfig.getInstance().commandName).then(TopCommand.buildCommand())); + } + if (DiamondEconomyConfig.getInstance().depositCommandName != null) { + dispatcher.register(Commands.literal(DiamondEconomyConfig.getInstance().commandName).then(DepositCommand.buildCommand())); + } + if (DiamondEconomyConfig.getInstance().sendCommandName != null) { + dispatcher.register(Commands.literal(DiamondEconomyConfig.getInstance().commandName).then(SendCommand.buildCommand())); + } + if (DiamondEconomyConfig.getInstance().setCommandName != null) { + dispatcher.register(Commands.literal(DiamondEconomyConfig.getInstance().commandName).then(SetCommand.buildCommand())); + } + if (DiamondEconomyConfig.getInstance().withdrawCommandName != null) { + dispatcher.register(Commands.literal(DiamondEconomyConfig.getInstance().commandName).then(WithdrawCommand.buildCommand())); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/com/gmail/sneakdevs/diamondeconomy/command/ModifyCommand.java b/src/main/java/com/gmail/sneakdevs/diamondeconomy/command/ModifyCommand.java new file mode 100644 index 0000000..a6e0dae --- /dev/null +++ b/src/main/java/com/gmail/sneakdevs/diamondeconomy/command/ModifyCommand.java @@ -0,0 +1,63 @@ +package com.gmail.sneakdevs.diamondeconomy.command; + +import com.gmail.sneakdevs.diamondeconomy.DiamondUtils; +import com.gmail.sneakdevs.diamondeconomy.config.DiamondEconomyConfig; +import com.mojang.brigadier.arguments.BoolArgumentType; +import com.mojang.brigadier.arguments.IntegerArgumentType; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; +import net.minecraft.commands.arguments.EntityArgument; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerPlayer; + +import java.util.Collection; + +public class ModifyCommand { + public static LiteralArgumentBuilder buildCommand(){ + return Commands.literal(DiamondEconomyConfig.getInstance().modifyCommandName) + .requires((permission) -> permission.hasPermission(DiamondEconomyConfig.getInstance().opCommandsPermissionLevel)) + .then( + Commands.argument("players", EntityArgument.players()) + .then( + Commands.argument("amount", IntegerArgumentType.integer()) + .executes(e -> { + int amount = IntegerArgumentType.getInteger(e, "amount"); + return modifyCommand(e, EntityArgument.getPlayers(e, "players").stream().toList(), amount); + })) + ) + .then( + Commands.argument("amount", IntegerArgumentType.integer()) + .then( + Commands.argument("shouldModifyAll", BoolArgumentType.bool()) + .executes(e -> { + int amount = IntegerArgumentType.getInteger(e, "amount"); + boolean shouldModifyAll = BoolArgumentType.getBool(e, "shouldModifyAll"); + return modifyCommand(e, amount, shouldModifyAll); + }) + ) + .executes(e -> { + int amount = IntegerArgumentType.getInteger(e, "amount"); + return modifyCommand(e, amount, false); + }) + ); + } + + public static int modifyCommand(CommandContext ctx, Collection players, int amount) { + players.forEach(player -> ctx.getSource().sendSuccess(() -> Component.literal((DiamondUtils.getDatabaseManager().changeBalance(player.getStringUUID(), amount)) ? ("Modified " + players.size() + " players money by $" + amount) : ("That would go out of the valid money range for " + player.getName().getString())), true)); + return players.size(); + } + + public static int modifyCommand(CommandContext ctx, int amount, boolean shouldModifyAll) throws CommandSyntaxException { + if (shouldModifyAll) { + DiamondUtils.getDatabaseManager().changeAllBalance(amount); + ctx.getSource().sendSuccess(() -> Component.literal(("Modified everyones account by $" + amount)), true); + } else { + String output = (DiamondUtils.getDatabaseManager().changeBalance(ctx.getSource().getPlayerOrException().getStringUUID(), amount)) ? ("Modified your money by $" + amount) : ("That would go out of your valid money range"); + ctx.getSource().sendSuccess(() -> Component.literal(output), true); + } + return 1; + } +} diff --git a/src/main/java/com/gmail/sneakdevs/diamondeconomy/command/SendCommand.java b/src/main/java/com/gmail/sneakdevs/diamondeconomy/command/SendCommand.java new file mode 100644 index 0000000..fed35a5 --- /dev/null +++ b/src/main/java/com/gmail/sneakdevs/diamondeconomy/command/SendCommand.java @@ -0,0 +1,42 @@ +package com.gmail.sneakdevs.diamondeconomy.command; + +import com.gmail.sneakdevs.diamondeconomy.DiamondUtils; +import com.gmail.sneakdevs.diamondeconomy.config.DiamondEconomyConfig; +import com.gmail.sneakdevs.diamondeconomy.sql.DatabaseManager; +import com.mojang.brigadier.arguments.IntegerArgumentType; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; +import net.minecraft.commands.arguments.EntityArgument; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerPlayer; + +public class SendCommand { + public static LiteralArgumentBuilder buildCommand(){ + return Commands.literal(DiamondEconomyConfig.getInstance().sendCommandName) + .then( + Commands.argument("player", EntityArgument.player()) + .then( + Commands.argument("amount", IntegerArgumentType.integer(1)) + .executes(e -> { + ServerPlayer player = EntityArgument.getPlayer(e, "player"); + int amount = IntegerArgumentType.getInteger(e, "amount"); + return sendCommand(e, player, e.getSource().getPlayerOrException(), amount); + }))); + } + + public static int sendCommand(CommandContext ctx, ServerPlayer player, ServerPlayer player1, int amount) throws CommandSyntaxException { + DatabaseManager dm = DiamondUtils.getDatabaseManager(); + long newValue = dm.getBalanceFromUUID(player.getStringUUID()) + amount; + if (newValue < Integer.MAX_VALUE && dm.changeBalance(player1.getStringUUID(), -amount)) { + dm.changeBalance(player.getStringUUID(), amount); + player.displayClientMessage(Component.literal("You received $" + amount + " from " + player1.getName().getString()), false); + ctx.getSource().sendSuccess(() -> Component.literal("Sent $" + amount + " to " + player.getName().getString()), false); + } else { + ctx.getSource().sendSuccess(() -> Component.literal("Failed because that would go over the max value"), false); + } + return 1; + } +} diff --git a/src/main/java/com/gmail/sneakdevs/diamondeconomy/command/SetCommand.java b/src/main/java/com/gmail/sneakdevs/diamondeconomy/command/SetCommand.java new file mode 100644 index 0000000..9355fbf --- /dev/null +++ b/src/main/java/com/gmail/sneakdevs/diamondeconomy/command/SetCommand.java @@ -0,0 +1,66 @@ +package com.gmail.sneakdevs.diamondeconomy.command; + +import com.gmail.sneakdevs.diamondeconomy.DiamondUtils; +import com.gmail.sneakdevs.diamondeconomy.config.DiamondEconomyConfig; +import com.gmail.sneakdevs.diamondeconomy.sql.DatabaseManager; +import com.mojang.brigadier.arguments.BoolArgumentType; +import com.mojang.brigadier.arguments.IntegerArgumentType; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; +import net.minecraft.commands.arguments.EntityArgument; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerPlayer; + +import java.util.Collection; + +public class SetCommand { + public static LiteralArgumentBuilder buildCommand(){ + return Commands.literal(DiamondEconomyConfig.getInstance().setCommandName) + .requires((permission) -> permission.hasPermission(DiamondEconomyConfig.getInstance().opCommandsPermissionLevel)) + .then( + Commands.argument("players", EntityArgument.players()) + .then( + Commands.argument("amount", IntegerArgumentType.integer(0)) + .executes(e -> { + int amount = IntegerArgumentType.getInteger(e, "amount"); + return setCommand(e, EntityArgument.getPlayers(e, "players").stream().toList(), amount); + })) + ) + .then( + Commands.argument("amount", IntegerArgumentType.integer(0)) + .then( + Commands.argument("shouldModifyAll", BoolArgumentType.bool()) + .executes(e -> { + int amount = IntegerArgumentType.getInteger(e, "amount"); + boolean shouldModifyAll = BoolArgumentType.getBool(e, "shouldModifyAll"); + return setCommand(e, amount, shouldModifyAll); + }) + ) + .executes(e -> { + int amount = IntegerArgumentType.getInteger(e, "amount"); + return setCommand(e, amount, false); + }) + ); + } + + public static int setCommand(CommandContext ctx, Collection players, int amount) { + DatabaseManager dm = DiamondUtils.getDatabaseManager(); + players.forEach(player -> dm.setBalance(player.getStringUUID(), amount)); + ctx.getSource().sendSuccess(() -> Component.literal("Updated balance of " + players.size() + " players to " + amount), true); + return players.size(); + } + + public static int setCommand(CommandContext ctx, int amount, boolean shouldModifyAll) throws CommandSyntaxException { + if (shouldModifyAll) { + DiamondUtils.getDatabaseManager().setAllBalance(amount); + ctx.getSource().sendSuccess(() -> Component.literal("All accounts balance to " + amount), true); + } else { + DiamondUtils.getDatabaseManager().setBalance(ctx.getSource().getPlayerOrException().getStringUUID(), amount); + ctx.getSource().sendSuccess(() -> Component.literal("Updated your balance to " + amount), true); + } + return 1; + } +} diff --git a/src/main/java/com/gmail/sneakdevs/diamondeconomy/command/TopCommand.java b/src/main/java/com/gmail/sneakdevs/diamondeconomy/command/TopCommand.java new file mode 100644 index 0000000..a82b6da --- /dev/null +++ b/src/main/java/com/gmail/sneakdevs/diamondeconomy/command/TopCommand.java @@ -0,0 +1,33 @@ +package com.gmail.sneakdevs.diamondeconomy.command; + +import com.gmail.sneakdevs.diamondeconomy.DiamondUtils; +import com.gmail.sneakdevs.diamondeconomy.config.DiamondEconomyConfig; +import com.gmail.sneakdevs.diamondeconomy.sql.DatabaseManager; +import com.mojang.brigadier.arguments.IntegerArgumentType; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; +import net.minecraft.network.chat.Component; + +public class TopCommand { + public static LiteralArgumentBuilder buildCommand(){ + return Commands.literal(DiamondEconomyConfig.getInstance().topCommandName) + .then( + Commands.argument("page", IntegerArgumentType.integer(1)) + .executes(e -> { + int page = IntegerArgumentType.getInteger(e, "page"); + return topCommand(e, page); + }) + ) + .executes(e -> topCommand(e, 1)); + } + + public static int topCommand(CommandContext ctx, int page) throws CommandSyntaxException { + DatabaseManager dm = DiamondUtils.getDatabaseManager(); + String output = dm.top(ctx.getSource().getPlayerOrException().getStringUUID(), page); + ctx.getSource().sendSuccess(() -> Component.literal(output), false); + return 1; + } +} diff --git a/src/main/java/com/gmail/sneakdevs/diamondeconomy/command/WithdrawCommand.java b/src/main/java/com/gmail/sneakdevs/diamondeconomy/command/WithdrawCommand.java new file mode 100644 index 0000000..25966a0 --- /dev/null +++ b/src/main/java/com/gmail/sneakdevs/diamondeconomy/command/WithdrawCommand.java @@ -0,0 +1,38 @@ +package com.gmail.sneakdevs.diamondeconomy.command; + +import com.gmail.sneakdevs.diamondeconomy.DiamondUtils; +import com.gmail.sneakdevs.diamondeconomy.config.DiamondEconomyConfig; +import com.gmail.sneakdevs.diamondeconomy.sql.DatabaseManager; +import com.mojang.brigadier.arguments.IntegerArgumentType; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerPlayer; + +public class WithdrawCommand { + public static LiteralArgumentBuilder buildCommand(){ + return Commands.literal(DiamondEconomyConfig.getInstance().withdrawCommandName) + .then( + Commands.argument("amount", IntegerArgumentType.integer(1)) + .executes(e -> { + int amount = IntegerArgumentType.getInteger(e, "amount"); + return withdrawCommand(e, amount); + }) + ); + } + + public static int withdrawCommand(CommandContext ctx, int amount) throws CommandSyntaxException { + ServerPlayer player = ctx.getSource().getPlayerOrException(); + DatabaseManager dm = DiamondUtils.getDatabaseManager(); + if (dm.changeBalance(player.getStringUUID(), -amount)) { + ctx.getSource().sendSuccess(() -> Component.literal("Withdrew $" + (amount - DiamondUtils.dropItem(amount, player))), false); + } else { + ctx.getSource().sendSuccess(() -> Component.literal("You have less than $" + amount), false); + } + return 1; + } + +} diff --git a/src/main/java/com/gmail/sneakdevs/diamondeconomy/config/DiamondEconomyConfig.java b/src/main/java/com/gmail/sneakdevs/diamondeconomy/config/DiamondEconomyConfig.java new file mode 100644 index 0000000..2d73f12 --- /dev/null +++ b/src/main/java/com/gmail/sneakdevs/diamondeconomy/config/DiamondEconomyConfig.java @@ -0,0 +1,71 @@ +package com.gmail.sneakdevs.diamondeconomy.config; + +import com.gmail.sneakdevs.diamondeconomy.DiamondEconomy; +import me.shedaniel.autoconfig.AutoConfig; +import me.shedaniel.autoconfig.ConfigData; +import me.shedaniel.autoconfig.annotation.Config; +import me.shedaniel.cloth.clothconfig.shadowed.blue.endless.jankson.Comment; +import net.minecraft.core.RegistryCodecs; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Item; + +@Config(name = DiamondEconomy.MODID) +public class DiamondEconomyConfig implements ConfigData { + + @Comment("List of items used as currency") + public String[] currencies = {"minecraft:diamond","minecraft:diamond_block"}; + + @Comment("Values of each currency in the same order, decimals not allowed (must be in ascending order unless greedyWithdraw is disabled)") + public int[] currencyValues = {1,9}; + + @Comment("Where the diamondeconomy.sqlite file is located (ex: \"C:/Users/example/Desktop/server/world/diamondeconomy.sqlite\")") + public String fileLocation = null; + + @Comment("Name of the base command (null to disable base command)") + public String commandName = "diamonds"; + + @Comment("Names of the subcommands (null to disable command)") + public String topCommandName = "top"; + public String balanceCommandName = "balance"; + public String depositCommandName = "deposit"; + public String sendCommandName = "send"; + public String withdrawCommandName = "withdraw"; + + @Comment("Names of the admin subcommands (null to disable command)") + public String setCommandName = "set"; + public String modifyCommandName = "modify"; + + @Comment("Try to withdraw items using the most high value items possible (ex. diamond blocks then diamonds) \n If disabled withdraw will give player the first item in the list") + public boolean greedyWithdraw = true; + + @Comment("Money the player starts with when they first join the server") + public int startingMoney = 0; + + @Comment("How often to add money to each player, in seconds (0 to disable)") + public int moneyAddTimer = 0; + + @Comment("Amount of money to add each cycle") + public int moneyAddAmount = 0; + + @Comment("Permission level (1-4) of the op commands in diamond economy. Set to 2 to allow command blocks to use these commands.") + public int opCommandsPermissionLevel = 4; + + public static Item getCurrency(int num) { + return BuiltInRegistries.ITEM.get(ResourceLocation.tryParse(DiamondEconomyConfig.getInstance().currencies[num])); + } + + public static String getCurrencyName(int num) { + return BuiltInRegistries.ITEM.get(ResourceLocation.tryParse(DiamondEconomyConfig.getInstance().currencies[num])).getDescription().getString(); + } + + public static int[] getCurrencyValues() { + return DiamondEconomyConfig.getInstance().currencyValues; + } + + public static DiamondEconomyConfig getInstance() { + return AutoConfig.getConfigHolder(DiamondEconomyConfig.class).getConfig(); + } +} \ No newline at end of file diff --git a/src/main/java/com/gmail/sneakdevs/diamondeconomy/mixin/PlayerListMixin_DiamondEconomy.java b/src/main/java/com/gmail/sneakdevs/diamondeconomy/mixin/PlayerListMixin_DiamondEconomy.java new file mode 100644 index 0000000..114f2da --- /dev/null +++ b/src/main/java/com/gmail/sneakdevs/diamondeconomy/mixin/PlayerListMixin_DiamondEconomy.java @@ -0,0 +1,23 @@ +package com.gmail.sneakdevs.diamondeconomy.mixin; + +import com.gmail.sneakdevs.diamondeconomy.DiamondUtils; +import com.gmail.sneakdevs.diamondeconomy.sql.DatabaseManager; +import net.minecraft.network.Connection; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.players.PlayerList; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(PlayerList.class) +public class PlayerListMixin_DiamondEconomy { + @Inject(method = "placeNewPlayer", at = @At("TAIL")) + private void diamondeconomy_onPlayerConnectMixin(Connection connection, ServerPlayer serverPlayer, CallbackInfo ci) { + DatabaseManager dm = DiamondUtils.getDatabaseManager(); + String uuid = serverPlayer.getStringUUID(); + String name = serverPlayer.getName().getString(); + dm.addPlayer(uuid, name); + dm.setName(uuid, name); + } +} \ No newline at end of file diff --git a/src/main/java/com/gmail/sneakdevs/diamondeconomy/mixin/ServerPlayerMixin.java b/src/main/java/com/gmail/sneakdevs/diamondeconomy/mixin/ServerPlayerMixin.java new file mode 100644 index 0000000..52be0d3 --- /dev/null +++ b/src/main/java/com/gmail/sneakdevs/diamondeconomy/mixin/ServerPlayerMixin.java @@ -0,0 +1,23 @@ +package com.gmail.sneakdevs.diamondeconomy.mixin; + +import com.gmail.sneakdevs.diamondeconomy.DiamondUtils; +import com.gmail.sneakdevs.diamondeconomy.config.DiamondEconomyConfig; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.stats.Stats; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ServerPlayer.class) +public class ServerPlayerMixin { + @Inject(method = "tick", at = @At("TAIL")) + private void diamondeconomy_tickMixin(CallbackInfo ci) { + if (DiamondEconomyConfig.getInstance().moneyAddAmount != 0 && DiamondEconomyConfig.getInstance().moneyAddTimer > 0) { + int playTime = ((ServerPlayer)(Object)this).getStats().getValue(Stats.CUSTOM.get(Stats.PLAY_TIME)); + if (playTime > 0 && playTime % (DiamondEconomyConfig.getInstance().moneyAddTimer * 20) == 0) { + DiamondUtils.getDatabaseManager().changeBalance(((ServerPlayer)(Object)this).getStringUUID(), DiamondEconomyConfig.getInstance().moneyAddAmount); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/com/gmail/sneakdevs/diamondeconomy/sql/DatabaseManager.java b/src/main/java/com/gmail/sneakdevs/diamondeconomy/sql/DatabaseManager.java new file mode 100644 index 0000000..981ab46 --- /dev/null +++ b/src/main/java/com/gmail/sneakdevs/diamondeconomy/sql/DatabaseManager.java @@ -0,0 +1,23 @@ +package com.gmail.sneakdevs.diamondeconomy.sql; + +import java.io.File; + +public interface DatabaseManager { + static void createNewDatabase(File file) {} + + void addPlayer(String uuid, String name); + void updateName(String uuid, String name); + void setName(String uuid, String name); + String getNameFromUUID(String uuid); + + int getBalanceFromUUID(String uuid); + int getBalanceFromName(String name); + boolean setBalance(String uuid, int money); + void setAllBalance(int money); + boolean changeBalance(String uuid, int money); + void changeAllBalance(int money); + + String top(String uuid, int topAmount); + String rank(int rank); + int playerRank(String uuid); +} diff --git a/src/main/java/com/gmail/sneakdevs/diamondeconomy/sql/SQLiteDatabaseManager.java b/src/main/java/com/gmail/sneakdevs/diamondeconomy/sql/SQLiteDatabaseManager.java new file mode 100644 index 0000000..2d70cc7 --- /dev/null +++ b/src/main/java/com/gmail/sneakdevs/diamondeconomy/sql/SQLiteDatabaseManager.java @@ -0,0 +1,234 @@ +package com.gmail.sneakdevs.diamondeconomy.sql; + +import com.gmail.sneakdevs.diamondeconomy.DiamondEconomy; +import com.gmail.sneakdevs.diamondeconomy.config.DiamondEconomyConfig; + +import java.io.File; +import java.sql.*; + +public class SQLiteDatabaseManager implements DatabaseManager { + public static String url; + + public static void createNewDatabase(File file) { + url = "jdbc:sqlite:" + file.getPath().replace('\\', '/'); + + Connection conn = null; + try { + conn = DriverManager.getConnection(url); + } catch (SQLException e) { + System.out.println(e.getMessage()); + } + + createNewTable(); + } + + public Connection connect() { + Connection conn = null; + try { + conn = DriverManager.getConnection(url); + } catch (SQLException e) { + System.out.println(e.getMessage()); + } + return conn; + } + + private static void createNewTable() { + try (Connection conn = DriverManager.getConnection(url); Statement stmt = conn.createStatement()) { + for (String query : DiamondEconomy.tableRegistry) { + stmt.execute(query); + } + } catch (SQLException e) { + e.printStackTrace(); + } + } + + public void addPlayer(String uuid, String name) { + String sql = "INSERT INTO diamonds(uuid,name,money) VALUES(?,?,?)"; + + try (Connection conn = this.connect(); PreparedStatement pstmt = conn.prepareStatement(sql)){ + pstmt.setString(1, uuid); + pstmt.setString(2, name); + pstmt.setInt(3, DiamondEconomyConfig.getInstance().startingMoney); + pstmt.executeUpdate(); + } catch (SQLException e) { + updateName(uuid, name); + } + } + + public void updateName(String uuid, String name) { + String sql = "UPDATE diamonds SET name = ? WHERE uuid = ?"; + + try (Connection conn = this.connect(); PreparedStatement pstmt = conn.prepareStatement(sql)) { + pstmt.setString(1, name); + pstmt.setString(2, uuid); + pstmt.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + public void setName(String uuid, String name) { + String sql = "UPDATE diamonds SET name = ? WHERE uuid != ? AND name = ?"; + + try (Connection conn = this.connect(); PreparedStatement pstmt = conn.prepareStatement(sql)) { + pstmt.setString(1, "a"); + pstmt.setString(2, uuid); + pstmt.setString(3, name); + pstmt.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + public int getBalanceFromUUID(String uuid){ + String sql = "SELECT uuid, money FROM diamonds WHERE uuid = '" + uuid + "'"; + + try (Connection conn = this.connect(); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql)){ + rs.next(); + return rs.getInt("money"); + } catch (SQLException e) { + e.printStackTrace(); + } + return -1; + } + + public String getNameFromUUID(String uuid){ + String sql = "SELECT uuid, name FROM diamonds WHERE uuid = '" + uuid + "'"; + + try (Connection conn = this.connect(); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql)){ + rs.next(); + return rs.getString("name"); + } catch (SQLException e) { + e.printStackTrace(); + } + return null; + } + + public int getBalanceFromName(String name){ + String sql = "SELECT name, money FROM diamonds WHERE name = '" + name + "'"; + + try (Connection conn = this.connect(); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql)){ + rs.next(); + return rs.getInt("money"); + } catch (SQLException e) { + e.printStackTrace(); + } + return -1; + } + + public boolean setBalance(String uuid, int money) { + String sql = "UPDATE diamonds SET money = ? WHERE uuid = ?"; + + try (Connection conn = this.connect(); PreparedStatement pstmt = conn.prepareStatement(sql)) { + if (money >= 0 && money < Integer.MAX_VALUE) { + pstmt.setInt(1, money); + pstmt.setString(2, uuid); + pstmt.executeUpdate(); + return true; + } + } catch (SQLException e) { + e.printStackTrace(); + } + return false; + } + + public void setAllBalance(int money) { + String sql = "UPDATE diamonds SET money = ?"; + + try (Connection conn = this.connect(); PreparedStatement pstmt = conn.prepareStatement(sql)) { + if (money >= 0 && money < Integer.MAX_VALUE) { + pstmt.setInt(1, money); + pstmt.executeUpdate(); + } + } catch (SQLException e) { + e.printStackTrace(); + } + } + + public boolean changeBalance(String uuid, int money) { + String sql = "UPDATE diamonds SET money = ? WHERE uuid = ?"; + + try (Connection conn = this.connect(); PreparedStatement pstmt = conn.prepareStatement(sql)) { + int bal = getBalanceFromUUID(uuid); + if (bal + money >= 0 && bal + money < Integer.MAX_VALUE) { + pstmt.setInt(1, bal + money); + pstmt.setString(2, uuid); + pstmt.executeUpdate(); + return true; + } + } catch (SQLException e) { + e.printStackTrace(); + } + return false; + } + + public void changeAllBalance(int money) { + String sql = "UPDATE diamonds SET money = money + " + money + " WHERE " + Integer.MAX_VALUE + " > money + " + money + " AND 0 <= money + " + money; + + try (Connection conn = this.connect(); PreparedStatement pstmt = conn.prepareStatement(sql)) { + pstmt.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + public String top(String uuid, int page){ + String sql = "SELECT uuid, name, money FROM diamonds ORDER BY money DESC"; + String rankings = ""; + int i = 0; + int playerRank = 0; + int repeats = 0; + + try (Connection conn = this.connect(); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql)){ + while (rs.next() && (repeats < 10 || playerRank == 0)) { + if (repeats / 10 + 1 == page) { + rankings = rankings.concat(rs.getRow() + ") " + rs.getString("name") + ": $" + rs.getInt("money") + "\n"); + i++; + } + repeats++; + if (uuid.equals(rs.getString("uuid"))) { + playerRank = repeats; + } + } + if (i < 10) { + rankings = rankings.concat("---End--- \n"); + } + } catch (SQLException e) { + e.printStackTrace(); + } + return rankings.concat("Your rank is: " + playerRank); + } + + public String rank(int rank){ + int repeats = 0; + String sql = "SELECT name FROM diamonds ORDER BY money DESC"; + try (Connection conn = this.connect(); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql)){ + while (rs.next() ) { + repeats++; + if (repeats == rank) { + return rs.getString("name"); + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + return "No Player"; + } + + public int playerRank(String uuid){ + String sql = "SELECT uuid FROM diamonds ORDER BY money DESC"; + int repeats = 1; + + try (Connection conn = this.connect(); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql)){ + rs.next(); + while (!rs.getString("uuid").equals(uuid)) { + rs.next(); + repeats++; + } + return repeats; + } catch (SQLException e) { + e.printStackTrace(); + } + return -1; + } +} diff --git a/src/main/resources/assets.diamondeconomy/icon.png b/src/main/resources/assets.diamondeconomy/icon.png new file mode 100644 index 0000000..ac4635a Binary files /dev/null and b/src/main/resources/assets.diamondeconomy/icon.png differ diff --git a/src/main/resources/diamondeconomy.mixins.json b/src/main/resources/diamondeconomy.mixins.json new file mode 100644 index 0000000..06827ac --- /dev/null +++ b/src/main/resources/diamondeconomy.mixins.json @@ -0,0 +1,13 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "com.gmail.sneakdevs.diamondeconomy.mixin", + "compatibilityLevel": "JAVA_8", + "mixins": [ + "PlayerListMixin_DiamondEconomy", + "ServerPlayerMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} \ No newline at end of file diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json new file mode 100644 index 0000000..80be8cd --- /dev/null +++ b/src/main/resources/fabric.mod.json @@ -0,0 +1,32 @@ +{ + "schemaVersion": 1, + "id": "diamondeconomy", + "version": "${version}", + + "name": "Diamond Economy", + "description": "Serverside economy mod with diamonds", + "authors": [ + "IAmSneak" + ], + "contact": { + "homepage": "", + "sources": "" + }, + + "license": "MIT", + + "environment": "*", + "entrypoints": { + "main": [ + "com.gmail.sneakdevs.diamondeconomy.DiamondEconomy" + ] + }, + "mixins": [ + "diamondeconomy.mixins.json" + ], + "depends": { + "fabricloader": ">=0.7.4", + "fabric": "*", + "cloth-config2": ">=6.2.57" + } +} \ No newline at end of file