Initial commit
This commit is contained in:
commit
72cde6640c
136
.gitignore
vendored
Executable file
136
.gitignore
vendored
Executable file
@ -0,0 +1,136 @@
|
|||||||
|
Server/world/
|
||||||
|
Server/world_the_end/
|
||||||
|
Server/world_nether/
|
||||||
|
Server/logs/
|
||||||
|
Server/banned-ips.json
|
||||||
|
Server/banned-players.json
|
||||||
|
Server/commands.yml
|
||||||
|
Server/help.yml
|
||||||
|
Server/ops.json
|
||||||
|
Server/permissions.yml
|
||||||
|
Server/plugins/
|
||||||
|
Server/usercache.json
|
||||||
|
Server/version_history.json
|
||||||
|
Server/wepif.yml
|
||||||
|
Server/whitelist.json
|
||||||
|
# User-specific stuff
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
out/
|
||||||
|
# mpeltonen/sbt-idea plugin
|
||||||
|
.idea_modules/
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
# Compiled class file
|
||||||
|
*.class
|
||||||
|
|
||||||
|
# Log file
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# BlueJ files
|
||||||
|
*.ctxt
|
||||||
|
|
||||||
|
# Package Files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.nar
|
||||||
|
*.ear
|
||||||
|
*.zip
|
||||||
|
*.tar.gz
|
||||||
|
*.rar
|
||||||
|
|
||||||
|
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||||
|
hs_err_pid*
|
||||||
|
|
||||||
|
*~
|
||||||
|
|
||||||
|
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||||
|
.fuse_hidden*
|
||||||
|
|
||||||
|
# KDE directory preferences
|
||||||
|
.directory
|
||||||
|
|
||||||
|
# Linux trash folder which might appear on any partition or disk
|
||||||
|
.Trash-*
|
||||||
|
|
||||||
|
# .nfs files are created when an open file is removed but is still being accessed
|
||||||
|
.nfs*
|
||||||
|
|
||||||
|
# General
|
||||||
|
.DS_Store
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
|
||||||
|
# Icon must end with two \r
|
||||||
|
Icon
|
||||||
|
|
||||||
|
# Thumbnails
|
||||||
|
._*
|
||||||
|
|
||||||
|
# Files that might appear in the root of a volume
|
||||||
|
.DocumentRevisions-V100
|
||||||
|
.fseventsd
|
||||||
|
.Spotlight-V100
|
||||||
|
.TemporaryItems
|
||||||
|
.Trashes
|
||||||
|
.VolumeIcon.icns
|
||||||
|
.com.apple.timemachine.donotpresent
|
||||||
|
|
||||||
|
# Directories potentially created on remote AFP share
|
||||||
|
.AppleDB
|
||||||
|
.AppleDesktop
|
||||||
|
Network Trash Folder
|
||||||
|
Temporary Items
|
||||||
|
.apdisk
|
||||||
|
|
||||||
|
# Windows thumbnail cache files
|
||||||
|
Thumbs.db
|
||||||
|
Thumbs.db:encryptable
|
||||||
|
ehthumbs.db
|
||||||
|
ehthumbs_vista.db
|
||||||
|
|
||||||
|
# Dump file
|
||||||
|
*.stackdump
|
||||||
|
|
||||||
|
# Folder config file
|
||||||
|
[Dd]esktop.ini
|
||||||
|
|
||||||
|
# Recycle Bin used on file shares
|
||||||
|
$RECYCLE.BIN/
|
||||||
|
|
||||||
|
# Windows Installer files
|
||||||
|
*.cab
|
||||||
|
*.msi
|
||||||
|
*.msix
|
||||||
|
*.msm
|
||||||
|
*.msp
|
||||||
|
|
||||||
|
# Windows shortcuts
|
||||||
|
*.lnk
|
||||||
|
|
||||||
|
.gradle
|
||||||
|
build/
|
||||||
|
|
||||||
|
# Ignore Gradle GUI config
|
||||||
|
gradle-app.setting
|
||||||
|
|
||||||
|
# Cache of project
|
||||||
|
.gradletasknamecache
|
||||||
|
|
||||||
|
**/build/
|
||||||
|
|
||||||
|
# Common working directory
|
||||||
|
run/
|
||||||
|
|
||||||
|
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
|
||||||
|
!gradle-wrapper.jar
|
||||||
|
|
||||||
|
!Server/*.jar
|
||||||
|
!Server/plugins/*.jar
|
37
Server/bukkit.yml
Executable file
37
Server/bukkit.yml
Executable file
@ -0,0 +1,37 @@
|
|||||||
|
# This is the main configuration file for Bukkit.
|
||||||
|
# As you can see, there's actually not that much to configure without any plugins.
|
||||||
|
# For a reference for any variable inside this file, check out the Bukkit Wiki at
|
||||||
|
# http://wiki.bukkit.org/Bukkit.yml
|
||||||
|
#
|
||||||
|
# If you need help on this file, feel free to join us on irc or leave a message
|
||||||
|
# on the forums asking for advice.
|
||||||
|
#
|
||||||
|
# IRC: #spigot @ irc.spi.gt
|
||||||
|
# (If this means nothing to you, just go to http://www.spigotmc.org/pages/irc/ )
|
||||||
|
# Forums: http://www.spigotmc.org/
|
||||||
|
# Bug tracker: http://www.spigotmc.org/go/bugs
|
||||||
|
|
||||||
|
|
||||||
|
settings:
|
||||||
|
allow-end: true
|
||||||
|
warn-on-overload: true
|
||||||
|
permissions-file: permissions.yml
|
||||||
|
update-folder: update
|
||||||
|
plugin-profiling: false
|
||||||
|
connection-throttle: 4000
|
||||||
|
query-plugins: true
|
||||||
|
deprecated-verbose: default
|
||||||
|
shutdown-message: Server closed
|
||||||
|
spawn-limits:
|
||||||
|
monsters: 70
|
||||||
|
animals: 15
|
||||||
|
water-animals: 5
|
||||||
|
ambient: 15
|
||||||
|
chunk-gc:
|
||||||
|
period-in-ticks: 600
|
||||||
|
load-threshold: 0
|
||||||
|
ticks-per:
|
||||||
|
animal-spawns: 400
|
||||||
|
monster-spawns: 1
|
||||||
|
autosave: 6000
|
||||||
|
aliases: now-in-commands.yml
|
4
Server/eula.txt
Executable file
4
Server/eula.txt
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
#By changing the setting below to TRUE you are indicating your agreement to our EULA (https://account.mojang.com/documents/minecraft_eula).
|
||||||
|
#and also agreeing that tacos are tasty.
|
||||||
|
#Mon Dec 21 15:24:20 MSK 2020
|
||||||
|
eula=true
|
BIN
Server/paper-1.12.2-1618.jar
Executable file
BIN
Server/paper-1.12.2-1618.jar
Executable file
Binary file not shown.
183
Server/paper.yml
Executable file
183
Server/paper.yml
Executable file
@ -0,0 +1,183 @@
|
|||||||
|
# This is the main configuration file for Paper.
|
||||||
|
# As you can see, there's tons to configure. Some options may impact gameplay, so use
|
||||||
|
# with caution, and make sure you know what each option does before configuring.
|
||||||
|
#
|
||||||
|
# If you need help with the configuration or have any questions related to Paper,
|
||||||
|
# join us in our IRC channel.
|
||||||
|
#
|
||||||
|
# IRC: #paper @ irc.spi.gt ( http://irc.spi.gt/iris/?channels=paper )
|
||||||
|
# Wiki: https://paper.readthedocs.org/
|
||||||
|
# Paper Forums: https://aquifermc.org/
|
||||||
|
|
||||||
|
verbose: false
|
||||||
|
config-version: 13
|
||||||
|
settings:
|
||||||
|
enable-player-collisions: true
|
||||||
|
player-auto-save-rate: -1
|
||||||
|
max-player-auto-save-per-tick: -1
|
||||||
|
load-permissions-yml-before-plugins: true
|
||||||
|
bungee-online-mode: true
|
||||||
|
save-player-data: true
|
||||||
|
min-chunk-load-threads: 2
|
||||||
|
book-size:
|
||||||
|
page-max: 2560
|
||||||
|
total-multiplier: 0.98
|
||||||
|
spam-limiter:
|
||||||
|
tab-spam-increment: 10
|
||||||
|
tab-spam-limit: 500
|
||||||
|
use-alternative-luck-formula: false
|
||||||
|
remove-invalid-statistics: false
|
||||||
|
region-file-cache-size: 256
|
||||||
|
incoming-packet-spam-threshold: 300
|
||||||
|
sleep-between-chunk-saves: false
|
||||||
|
save-empty-scoreboard-teams: false
|
||||||
|
suggest-player-names-when-null-tab-completions: true
|
||||||
|
watchdog:
|
||||||
|
early-warning-every: 5000
|
||||||
|
early-warning-delay: 10000
|
||||||
|
timings:
|
||||||
|
enabled: true
|
||||||
|
verbose: true
|
||||||
|
server-name-privacy: false
|
||||||
|
hidden-config-entries:
|
||||||
|
- database
|
||||||
|
- settings.bungeecord-addresses
|
||||||
|
history-interval: 300
|
||||||
|
history-length: 3600
|
||||||
|
messages:
|
||||||
|
kick:
|
||||||
|
authentication-servers-down: ''
|
||||||
|
flying-player: Flying is not enabled on this server
|
||||||
|
flying-vehicle: Flying is not enabled on this server
|
||||||
|
world-settings:
|
||||||
|
default:
|
||||||
|
keep-spawn-loaded-range: 8
|
||||||
|
auto-save-interval: -1
|
||||||
|
frosted-ice:
|
||||||
|
enabled: true
|
||||||
|
delay:
|
||||||
|
min: 20
|
||||||
|
max: 40
|
||||||
|
grass-spread-tick-rate: 1
|
||||||
|
game-mechanics:
|
||||||
|
disable-sprint-interruption-on-attack: false
|
||||||
|
disable-chest-cat-detection: false
|
||||||
|
disable-end-credits: false
|
||||||
|
shield-blocking-delay: 5
|
||||||
|
disable-player-crits: false
|
||||||
|
disable-unloaded-chunk-enderpearl-exploit: true
|
||||||
|
village-sieges-enabled: true
|
||||||
|
allow-permanent-chunk-loaders: false
|
||||||
|
scan-for-legacy-ender-dragon: true
|
||||||
|
elytra-hit-wall-damage: true
|
||||||
|
nether-ceiling-void-damage: false
|
||||||
|
allow-non-player-entities-on-scoreboards: false
|
||||||
|
container-update-tick-rate: 1
|
||||||
|
hopper:
|
||||||
|
push-based: false
|
||||||
|
cooldown-when-full: true
|
||||||
|
disable-move-event: false
|
||||||
|
parrots-are-unaffected-by-player-movement: false
|
||||||
|
disable-explosion-knockback: false
|
||||||
|
use-alternate-fallingblock-onGround-detection: false
|
||||||
|
non-player-arrow-despawn-rate: -1
|
||||||
|
prevent-tnt-from-moving-in-water: false
|
||||||
|
keep-spawn-loaded: true
|
||||||
|
fire-physics-event-for-redstone: false
|
||||||
|
disable-ice-and-snow: false
|
||||||
|
armor-stands-do-collision-entity-lookups: true
|
||||||
|
skeleton-horse-thunder-spawn-chance: 0.01
|
||||||
|
spawner-nerfed-mobs-should-jump: false
|
||||||
|
baby-zombie-movement-speed: 0.5
|
||||||
|
allow-leashing-undead-horse: false
|
||||||
|
all-chunks-are-slime-chunks: false
|
||||||
|
squid-spawn-height:
|
||||||
|
maximum: 0.0
|
||||||
|
mob-spawner-tick-rate: 1
|
||||||
|
bed-search-radius: 1
|
||||||
|
armor-stands-tick: true
|
||||||
|
experience-merge-max-value: -1
|
||||||
|
anti-xray:
|
||||||
|
enabled: false
|
||||||
|
engine-mode: 1
|
||||||
|
chunk-edge-mode: 1
|
||||||
|
max-chunk-section-index: 3
|
||||||
|
update-radius: 2
|
||||||
|
hidden-blocks:
|
||||||
|
- gold_ore
|
||||||
|
- iron_ore
|
||||||
|
- coal_ore
|
||||||
|
- lapis_ore
|
||||||
|
- mossy_cobblestone
|
||||||
|
- obsidian
|
||||||
|
- chest
|
||||||
|
- diamond_ore
|
||||||
|
- redstone_ore
|
||||||
|
- lit_redstone_ore
|
||||||
|
- clay
|
||||||
|
- emerald_ore
|
||||||
|
- ender_chest
|
||||||
|
replacement-blocks:
|
||||||
|
- stone
|
||||||
|
- planks
|
||||||
|
disable-thunder: false
|
||||||
|
enable-treasure-maps: true
|
||||||
|
treasure-maps-return-already-discovered: false
|
||||||
|
disable-teleportation-suffocation-check: false
|
||||||
|
generator-settings:
|
||||||
|
canyon: true
|
||||||
|
caves: true
|
||||||
|
dungeon: true
|
||||||
|
fortress: true
|
||||||
|
mineshaft: true
|
||||||
|
monument: true
|
||||||
|
stronghold: true
|
||||||
|
temple: true
|
||||||
|
village: true
|
||||||
|
flat-bedrock: false
|
||||||
|
disable-extreme-hills-emeralds: false
|
||||||
|
disable-extreme-hills-monster-eggs: false
|
||||||
|
disable-mesa-additional-gold: false
|
||||||
|
skip-entity-ticking-in-chunks-scheduled-for-unload: true
|
||||||
|
use-vanilla-world-scoreboard-name-coloring: false
|
||||||
|
falling-block-height-nerf: 0
|
||||||
|
tnt-entity-height-nerf: 0
|
||||||
|
use-chunk-inhabited-timer: true
|
||||||
|
fast-drain:
|
||||||
|
lava: false
|
||||||
|
water: false
|
||||||
|
despawn-ranges:
|
||||||
|
soft: 32
|
||||||
|
hard: 128
|
||||||
|
lava-flow-speed:
|
||||||
|
normal: 30
|
||||||
|
nether: 10
|
||||||
|
fishing-time-range:
|
||||||
|
MinimumTicks: 100
|
||||||
|
MaximumTicks: 600
|
||||||
|
remove-corrupt-tile-entities: false
|
||||||
|
prevent-moving-into-unloaded-chunks: false
|
||||||
|
max-entity-collisions: 8
|
||||||
|
duplicate-uuid-resolver: saferegen
|
||||||
|
duplicate-uuid-saferegen-delete-range: 32
|
||||||
|
disable-creeper-lingering-effect: false
|
||||||
|
filter-nbt-data-from-spawn-eggs-and-related: true
|
||||||
|
queue-light-updates: false
|
||||||
|
optimize-explosions: false
|
||||||
|
save-queue-limit-for-auto-save: 50
|
||||||
|
delay-chunk-unloads-by: 10s
|
||||||
|
max-auto-save-chunks-per-tick: 24
|
||||||
|
max-chunk-sends-per-tick: 81
|
||||||
|
max-growth-height:
|
||||||
|
cactus: 3
|
||||||
|
reeds: 3
|
||||||
|
max-chunk-gens-per-tick: 10
|
||||||
|
water-over-lava-flow-speed: 5
|
||||||
|
lootables:
|
||||||
|
auto-replenish: false
|
||||||
|
restrict-player-reloot: true
|
||||||
|
reset-seed-on-fill: true
|
||||||
|
max-refills: -1
|
||||||
|
refresh-min: 12h
|
||||||
|
refresh-max: 2d
|
||||||
|
portal-search-radius: 128
|
BIN
Server/plugins/Citizens-2.0.29-b2488.jar
Executable file
BIN
Server/plugins/Citizens-2.0.29-b2488.jar
Executable file
Binary file not shown.
BIN
Server/plugins/Economy.jar
Executable file
BIN
Server/plugins/Economy.jar
Executable file
Binary file not shown.
BIN
Server/plugins/LuckPerms-Bukkit-5.3.107.jar
Executable file
BIN
Server/plugins/LuckPerms-Bukkit-5.3.107.jar
Executable file
Binary file not shown.
BIN
Server/plugins/PlaceholderAPI-2.11.1.jar
Executable file
BIN
Server/plugins/PlaceholderAPI-2.11.1.jar
Executable file
Binary file not shown.
BIN
Server/plugins/PowerNBT.jar
Executable file
BIN
Server/plugins/PowerNBT.jar
Executable file
Binary file not shown.
BIN
Server/plugins/QSeller-1.0.0.jar
Executable file
BIN
Server/plugins/QSeller-1.0.0.jar
Executable file
Binary file not shown.
BIN
Server/plugins/Vault (1).jar
Executable file
BIN
Server/plugins/Vault (1).jar
Executable file
Binary file not shown.
BIN
Server/plugins/worldedit-bukkit-6.1.9.jar
Executable file
BIN
Server/plugins/worldedit-bukkit-6.1.9.jar
Executable file
Binary file not shown.
BIN
Server/plugins/worldguard-bukkit-6.2.2.jar
Executable file
BIN
Server/plugins/worldguard-bukkit-6.2.2.jar
Executable file
Binary file not shown.
39
Server/server.properties
Executable file
39
Server/server.properties
Executable file
@ -0,0 +1,39 @@
|
|||||||
|
#Minecraft server properties
|
||||||
|
#Sun Feb 27 14:13:20 MSK 2022
|
||||||
|
spawn-protection=16
|
||||||
|
generator-settings=
|
||||||
|
force-gamemode=false
|
||||||
|
allow-nether=true
|
||||||
|
gamemode=0
|
||||||
|
broadcast-console-to-ops=true
|
||||||
|
enable-query=false
|
||||||
|
player-idle-timeout=0
|
||||||
|
difficulty=1
|
||||||
|
spawn-monsters=true
|
||||||
|
op-permission-level=4
|
||||||
|
pvp=true
|
||||||
|
snooper-enabled=true
|
||||||
|
level-type=DEFAULT
|
||||||
|
hardcore=false
|
||||||
|
enable-command-block=true
|
||||||
|
max-players=20
|
||||||
|
network-compression-threshold=256
|
||||||
|
resource-pack-sha1=
|
||||||
|
max-world-size=29999984
|
||||||
|
server-port=25565
|
||||||
|
debug=false
|
||||||
|
server-ip=
|
||||||
|
spawn-npcs=true
|
||||||
|
allow-flight=false
|
||||||
|
level-name=world
|
||||||
|
view-distance=10
|
||||||
|
resource-pack=
|
||||||
|
spawn-animals=true
|
||||||
|
white-list=false
|
||||||
|
generate-structures=true
|
||||||
|
online-mode=false
|
||||||
|
max-build-height=256
|
||||||
|
level-seed=
|
||||||
|
prevent-proxy-connections=false
|
||||||
|
enable-rcon=false
|
||||||
|
motd=A Minecraft Server
|
126
Server/spigot.yml
Executable file
126
Server/spigot.yml
Executable file
@ -0,0 +1,126 @@
|
|||||||
|
# This is the main configuration file for Spigot.
|
||||||
|
# As you can see, there's tons to configure. Some options may impact gameplay, so use
|
||||||
|
# with caution, and make sure you know what each option does before configuring.
|
||||||
|
# For a reference for any variable inside this file, check out the Spigot wiki at
|
||||||
|
# http://www.spigotmc.org/wiki/spigot-configuration/
|
||||||
|
#
|
||||||
|
# If you need help with the configuration or have any questions related to Spigot,
|
||||||
|
# join us at the IRC or drop by our forums and leave a post.
|
||||||
|
#
|
||||||
|
# IRC: #spigot @ irc.spi.gt ( http://www.spigotmc.org/pages/irc/ )
|
||||||
|
# Forums: http://www.spigotmc.org/
|
||||||
|
|
||||||
|
config-version: 11
|
||||||
|
settings:
|
||||||
|
sample-count: 12
|
||||||
|
save-user-cache-on-stop-only: false
|
||||||
|
moved-wrongly-threshold: 0.0625
|
||||||
|
moved-too-quickly-multiplier: 10.0
|
||||||
|
filter-creative-items: true
|
||||||
|
player-shuffle: 0
|
||||||
|
attribute:
|
||||||
|
maxHealth:
|
||||||
|
max: 2048.0
|
||||||
|
movementSpeed:
|
||||||
|
max: 2048.0
|
||||||
|
attackDamage:
|
||||||
|
max: 2048.0
|
||||||
|
user-cache-size: 1000
|
||||||
|
late-bind: false
|
||||||
|
int-cache-limit: 1024
|
||||||
|
item-dirty-ticks: 20
|
||||||
|
netty-threads: 4
|
||||||
|
bungeecord: false
|
||||||
|
timeout-time: 60
|
||||||
|
restart-on-crash: true
|
||||||
|
restart-script: ./start.sh
|
||||||
|
debug: false
|
||||||
|
commands:
|
||||||
|
tab-complete: 0
|
||||||
|
silent-commandblock-console: false
|
||||||
|
log: true
|
||||||
|
replace-commands:
|
||||||
|
- setblock
|
||||||
|
- summon
|
||||||
|
- testforblock
|
||||||
|
- tellraw
|
||||||
|
spam-exclusions:
|
||||||
|
- /skill
|
||||||
|
messages:
|
||||||
|
whitelist: You are not whitelisted on this server!
|
||||||
|
unknown-command: Unknown command. Type "/help" for help.
|
||||||
|
server-full: The server is full!
|
||||||
|
outdated-client: Outdated client! Please use {0}
|
||||||
|
outdated-server: Outdated server! I'm still on {0}
|
||||||
|
restart: Server is restarting
|
||||||
|
advancements:
|
||||||
|
disable-saving: false
|
||||||
|
disabled:
|
||||||
|
- minecraft:story/disabled
|
||||||
|
stats:
|
||||||
|
disable-saving: false
|
||||||
|
forced-stats: {}
|
||||||
|
world-settings:
|
||||||
|
default:
|
||||||
|
verbose: true
|
||||||
|
item-despawn-rate: 6000
|
||||||
|
merge-radius:
|
||||||
|
item: 2.5
|
||||||
|
exp: 3.0
|
||||||
|
view-distance: 10
|
||||||
|
enable-zombie-pigmen-portal-spawns: true
|
||||||
|
wither-spawn-sound-radius: 0
|
||||||
|
hanging-tick-frequency: 100
|
||||||
|
zombie-aggressive-towards-villager: true
|
||||||
|
arrow-despawn-rate: 1200
|
||||||
|
nerf-spawner-mobs: false
|
||||||
|
entity-tracking-range:
|
||||||
|
players: 48
|
||||||
|
animals: 48
|
||||||
|
monsters: 48
|
||||||
|
misc: 32
|
||||||
|
other: 64
|
||||||
|
entity-activation-range:
|
||||||
|
animals: 32
|
||||||
|
monsters: 32
|
||||||
|
misc: 16
|
||||||
|
water: 16
|
||||||
|
tick-inactive-villagers: true
|
||||||
|
max-tick-time:
|
||||||
|
tile: 50
|
||||||
|
entity: 50
|
||||||
|
ticks-per:
|
||||||
|
hopper-transfer: 8
|
||||||
|
hopper-check: 1
|
||||||
|
hopper-amount: 1
|
||||||
|
random-light-updates: false
|
||||||
|
mob-spawn-range: 4
|
||||||
|
hunger:
|
||||||
|
jump-walk-exhaustion: 0.05
|
||||||
|
jump-sprint-exhaustion: 0.2
|
||||||
|
combat-exhaustion: 0.1
|
||||||
|
regen-exhaustion: 6.0
|
||||||
|
swim-multiplier: 0.01
|
||||||
|
sprint-multiplier: 0.1
|
||||||
|
other-multiplier: 0.0
|
||||||
|
save-structure-info: true
|
||||||
|
growth:
|
||||||
|
cactus-modifier: 100
|
||||||
|
cane-modifier: 100
|
||||||
|
melon-modifier: 100
|
||||||
|
mushroom-modifier: 100
|
||||||
|
pumpkin-modifier: 100
|
||||||
|
sapling-modifier: 100
|
||||||
|
wheat-modifier: 100
|
||||||
|
netherwart-modifier: 100
|
||||||
|
vine-modifier: 100
|
||||||
|
cocoa-modifier: 100
|
||||||
|
max-tnt-per-tick: 100
|
||||||
|
squid-spawn-range:
|
||||||
|
min: 45.0
|
||||||
|
seed-village: 10387312
|
||||||
|
seed-feature: 14357617
|
||||||
|
seed-monument: 10387313
|
||||||
|
seed-slime: 987234911
|
||||||
|
dragon-death-sound-radius: 0
|
||||||
|
max-entity-collisions: 8
|
75
build.gradle
Executable file
75
build.gradle
Executable file
@ -0,0 +1,75 @@
|
|||||||
|
plugins {
|
||||||
|
id 'java'
|
||||||
|
}
|
||||||
|
|
||||||
|
group = 'ru.redguy'
|
||||||
|
version = '1.0.0'
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
maven {
|
||||||
|
name = 'papermc-repo'
|
||||||
|
url = 'https://papermc.io/repo/repository/maven-public/'
|
||||||
|
}
|
||||||
|
maven {
|
||||||
|
name = 'sonatype'
|
||||||
|
url = 'https://oss.sonatype.org/content/groups/public/'
|
||||||
|
}
|
||||||
|
maven {
|
||||||
|
name = 'redguy-repo'
|
||||||
|
url = 'https://repo.redguy.ru/repository/maven-public/'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnly 'com.destroystokyo.paper:paper-api:1.12.2-R0.1-SNAPSHOT'
|
||||||
|
compileOnly 'me.clip:placeholderapi:2.11.1'
|
||||||
|
compileOnly "com.github.MilkBowl:VaultAPI:1.7"
|
||||||
|
compileOnly "net.citizensnpcs:citizensapi:2.0.29-SNAPSHOT"
|
||||||
|
|
||||||
|
implementation 'com.github.IPVP-MC:canvas:1fa1956b89'
|
||||||
|
implementation 'mysql:mysql-connector-java:8.0.16'
|
||||||
|
implementation 'com.zaxxer:HikariCP:4.0.3'
|
||||||
|
implementation 'org.jetbrains:annotations:20.1.0'
|
||||||
|
implementation 'com.h2database:h2:1.4.200'
|
||||||
|
}
|
||||||
|
|
||||||
|
def targetJavaVersion = 8
|
||||||
|
java {
|
||||||
|
def javaVersion = JavaVersion.toVersion(targetJavaVersion)
|
||||||
|
sourceCompatibility = javaVersion
|
||||||
|
targetCompatibility = javaVersion
|
||||||
|
if (JavaVersion.current() < javaVersion) {
|
||||||
|
toolchain.languageVersion = JavaLanguageVersion.of(targetJavaVersion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
compileJava.options.encoding = 'UTF-8'
|
||||||
|
tasks.withType(JavaCompile).configureEach {
|
||||||
|
if (targetJavaVersion >= 10 || JavaVersion.current().isJava10Compatible()) {
|
||||||
|
options.release = targetJavaVersion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jar {
|
||||||
|
configurations.implementation.canBeResolved = true
|
||||||
|
from {
|
||||||
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||||
|
configurations.implementation.collect { it.isDirectory() ? it : zipTree(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
processResources {
|
||||||
|
def props = [version: version]
|
||||||
|
inputs.properties props
|
||||||
|
filteringCharset 'UTF-8'
|
||||||
|
filesMatching('plugin.yml') {
|
||||||
|
expand props
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task copytorun(type: Copy) {
|
||||||
|
delete file("$projectDir/Server/plugins/QSeller*")
|
||||||
|
from file("$projectDir/build/libs/QSeller-${version}.jar")
|
||||||
|
into file("$projectDir/Server/plugins/")
|
||||||
|
}
|
0
gradle.properties
Executable file
0
gradle.properties
Executable file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Executable file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Executable file
Binary file not shown.
5
gradle/wrapper/gradle-wrapper.properties
vendored
Executable file
5
gradle/wrapper/gradle-wrapper.properties
vendored
Executable file
@ -0,0 +1,5 @@
|
|||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
185
gradlew
vendored
Executable file
185
gradlew
vendored
Executable file
@ -0,0 +1,185 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright 2015 the original author or 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 UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$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 "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die () {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# 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" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
|
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
|
||||||
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=`expr $i + 1`
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
0) set -- ;;
|
||||||
|
1) set -- "$args0" ;;
|
||||||
|
2) set -- "$args0" "$args1" ;;
|
||||||
|
3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Escape application args
|
||||||
|
save () {
|
||||||
|
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||||
|
echo " "
|
||||||
|
}
|
||||||
|
APP_ARGS=`save "$@"`
|
||||||
|
|
||||||
|
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||||
|
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||||
|
|
||||||
|
exec "$JAVACMD" "$@"
|
89
gradlew.bat
vendored
Executable file
89
gradlew.bat
vendored
Executable file
@ -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
|
1
settings.gradle
Executable file
1
settings.gradle
Executable file
@ -0,0 +1 @@
|
|||||||
|
rootProject.name = 'QSeller'
|
126
src/main/java/ru/redguy/qseller/Database.java
Executable file
126
src/main/java/ru/redguy/qseller/Database.java
Executable file
@ -0,0 +1,126 @@
|
|||||||
|
package ru.redguy.qseller;
|
||||||
|
|
||||||
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public abstract class Database {
|
||||||
|
protected static Database instance;
|
||||||
|
|
||||||
|
public static Database getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private HikariDataSource ds;
|
||||||
|
private final String prefix;
|
||||||
|
|
||||||
|
protected Database(HikariDataSource ds, String tablePrefix) {
|
||||||
|
this.ds = ds;
|
||||||
|
prefix = tablePrefix;
|
||||||
|
dataBaseCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract boolean isTableExists(String name, Connection con) throws SQLException;
|
||||||
|
|
||||||
|
private void dataBaseCheck() {
|
||||||
|
try (Connection con = ds.getConnection()) {
|
||||||
|
if (!isTableExists("OPTIONS", con)) {
|
||||||
|
PreparedStatement ps = con.prepareStatement("CREATE TABLE " + prefix + "options (option_name text not null,option_value text null);");
|
||||||
|
ps.execute();
|
||||||
|
ps = con.prepareStatement("INSERT INTO " + prefix + "options (option_name, option_value) VALUES ('schema_version', '1');");
|
||||||
|
ps.execute();
|
||||||
|
}
|
||||||
|
PreparedStatement ps = con.prepareStatement("SELECT * FROM " + prefix + "options WHERE option_name = 'schema_version';");
|
||||||
|
ResultSet rs = ps.executeQuery();
|
||||||
|
rs.next();
|
||||||
|
String schema_version = rs.getString("option_value");
|
||||||
|
switch (schema_version) {
|
||||||
|
case "1": {
|
||||||
|
if (!isTableExists("players", con)) {
|
||||||
|
ps = con.prepareStatement("create table " + prefix + "players (uuid text not null,villager_level int default 1 null);");
|
||||||
|
ps.execute();
|
||||||
|
}
|
||||||
|
if (!isTableExists("items", con)) {
|
||||||
|
ps = con.prepareStatement("create table " + prefix + "items (player text not null,item text not null,sold int default 0 not null);");
|
||||||
|
ps.execute();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException throwables) {
|
||||||
|
throwables.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPrefix() {
|
||||||
|
return prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disconnect() {
|
||||||
|
this.ds.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVillagerLevel(UUID uuid) {
|
||||||
|
try (Connection con = ds.getConnection()) {
|
||||||
|
PreparedStatement ps = con.prepareStatement("SELECT * FROM " + prefix + "players WHERE uuid = ?");
|
||||||
|
ps.setString(1, uuid.toString());
|
||||||
|
ResultSet rs = ps.executeQuery();
|
||||||
|
if (rs.next()) {
|
||||||
|
return rs.getInt("villager_level");
|
||||||
|
}
|
||||||
|
ps = con.prepareStatement("INSERT INTO " + prefix + "players (uuid) VALUES (?)");
|
||||||
|
ps.setString(1, uuid.toString());
|
||||||
|
ps.execute();
|
||||||
|
return getVillagerLevel(uuid);
|
||||||
|
} catch (SQLException throwables) {
|
||||||
|
throwables.printStackTrace();
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getItemProgress(UUID uuid, Material material) {
|
||||||
|
try (Connection con = ds.getConnection()) {
|
||||||
|
PreparedStatement ps = con.prepareStatement("SELECT * FROM " + prefix + "items WHERE player = ? AND item = ?");
|
||||||
|
ps.setString(1, uuid.toString());
|
||||||
|
ps.setString(2, material.name());
|
||||||
|
ResultSet rs = ps.executeQuery();
|
||||||
|
if (rs.next()) {
|
||||||
|
return rs.getInt("sold");
|
||||||
|
}
|
||||||
|
ps = con.prepareStatement("INSERT INTO " + prefix + "items (player, item) VALUES (?, ?)");
|
||||||
|
ps.setString(1, uuid.toString());
|
||||||
|
ps.setString(2, material.name());
|
||||||
|
ps.execute();
|
||||||
|
return getItemProgress(uuid, material);
|
||||||
|
} catch (SQLException throwables) {
|
||||||
|
throwables.printStackTrace();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void progressItem(UUID uuid, Material material) {
|
||||||
|
try (Connection con = ds.getConnection()) {
|
||||||
|
PreparedStatement ps = con.prepareStatement("UPDATE " + prefix + "items SET sold = sold+1 WHERE player = ? AND item = ?");
|
||||||
|
ps.setString(1, uuid.toString());
|
||||||
|
ps.setString(2, material.name());
|
||||||
|
ps.execute();
|
||||||
|
} catch (SQLException throwables) {
|
||||||
|
throwables.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void progressVillager(UUID uuid) {
|
||||||
|
try (Connection con = ds.getConnection()) {
|
||||||
|
PreparedStatement ps = con.prepareStatement("UPDATE " + prefix + "players SET villager_level = villager_level+1 WHERE uuid = ?");
|
||||||
|
ps.setString(1, uuid.toString());
|
||||||
|
ps.execute();
|
||||||
|
} catch (SQLException throwables) {
|
||||||
|
throwables.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
23
src/main/java/ru/redguy/qseller/H2Database.java
Executable file
23
src/main/java/ru/redguy/qseller/H2Database.java
Executable file
@ -0,0 +1,23 @@
|
|||||||
|
package ru.redguy.qseller;
|
||||||
|
|
||||||
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
public class H2Database extends Database{
|
||||||
|
protected H2Database(HikariDataSource ds) {
|
||||||
|
super(ds, "");
|
||||||
|
Database.instance = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean isTableExists(String name, Connection con) throws SQLException {
|
||||||
|
PreparedStatement st = con.prepareStatement("SELECT * FROM information_schema.tables WHERE table_name = ?");
|
||||||
|
st.setString(1, name.toUpperCase());
|
||||||
|
ResultSet rs = st.executeQuery();
|
||||||
|
return rs.next();
|
||||||
|
}
|
||||||
|
}
|
23
src/main/java/ru/redguy/qseller/MySQLDatabase.java
Executable file
23
src/main/java/ru/redguy/qseller/MySQLDatabase.java
Executable file
@ -0,0 +1,23 @@
|
|||||||
|
package ru.redguy.qseller;
|
||||||
|
|
||||||
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
public class MySQLDatabase extends Database{
|
||||||
|
protected MySQLDatabase(HikariDataSource ds, String tablePrefix) {
|
||||||
|
super(ds, tablePrefix);
|
||||||
|
Database.instance = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean isTableExists(String name, Connection con) throws SQLException {
|
||||||
|
PreparedStatement st = con.prepareStatement("SHOW TABLES LIKE ?");
|
||||||
|
st.setString(1, this.getPrefix() + name);
|
||||||
|
ResultSet rs = st.executeQuery();
|
||||||
|
return rs.next();
|
||||||
|
}
|
||||||
|
}
|
199
src/main/java/ru/redguy/qseller/QSeller.java
Executable file
199
src/main/java/ru/redguy/qseller/QSeller.java
Executable file
@ -0,0 +1,199 @@
|
|||||||
|
package ru.redguy.qseller;
|
||||||
|
|
||||||
|
import com.zaxxer.hikari.HikariConfig;
|
||||||
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
|
import me.clip.placeholderapi.PlaceholderAPI;
|
||||||
|
import net.citizensnpcs.api.event.NPCRightClickEvent;
|
||||||
|
import net.milkbowl.vault.economy.Economy;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
|
import org.bukkit.configuration.serialization.ConfigurationSerialization;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
import org.ipvp.canvas.MenuFunctionListener;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public final class QSeller extends JavaPlugin implements Listener {
|
||||||
|
|
||||||
|
static {
|
||||||
|
ConfigurationSerialization.registerClass(SellItem.class, "SellItem");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static QSeller instance;
|
||||||
|
|
||||||
|
public static QSeller getInstance() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Economy econ = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable() {
|
||||||
|
instance = this;
|
||||||
|
|
||||||
|
defConf("db.type","h2");
|
||||||
|
defConf("db._typeComment","h2 or mysql");
|
||||||
|
|
||||||
|
defConf("db.h2.file","base.db");
|
||||||
|
|
||||||
|
defConf("db.mysql.host","localhost");
|
||||||
|
defConf("db.mysql.port",3306);
|
||||||
|
defConf("db.mysql.base","reputation");
|
||||||
|
defConf("db.mysql.tablePrefix","seller_");
|
||||||
|
defConf("db.mysql.user","admin");
|
||||||
|
defConf("db.mysql.pass","StarWarsMonster123");
|
||||||
|
defConf("db.mysql.useSSL",false);
|
||||||
|
defConf("db.mysql.maximumPoolSize",1);
|
||||||
|
defConf("db.mysql.minimumIdle",1);
|
||||||
|
defConf("db.mysql.serverTimezone","UTC");
|
||||||
|
defConf("db.mysql.maxLifetimeSeconds",30);
|
||||||
|
|
||||||
|
defConf("game.menu.structure",new ArrayList<String>() {{
|
||||||
|
add("#########");add("#iiiiiii#");add("#iiiiiii#");add("#iiiiiii#");add("#########");add("####b####");
|
||||||
|
}});
|
||||||
|
defConf("game.menu.title","Торговец {{level}} ур.");
|
||||||
|
defConf("game.menu.npcs",new ArrayList<Integer>() {{
|
||||||
|
add(-1);
|
||||||
|
}});
|
||||||
|
defConf("game.menu.items",new ArrayList<SellItem>() {{
|
||||||
|
add(new SellItem(Material.SUGAR_CANE));add(new SellItem(Material.CARROT_ITEM));
|
||||||
|
add(new SellItem(Material.POTATO_ITEM));add(new SellItem(Material.MELON_BLOCK));
|
||||||
|
add(new SellItem(Material.PUMPKIN));add(new SellItem(Material.NETHER_STALK));
|
||||||
|
add(new SellItem(Material.CACTUS));add(new SellItem(Material.STRING));
|
||||||
|
}});
|
||||||
|
defConf("game.menu.startStacks",10);
|
||||||
|
defConf("game.menu.step",15);
|
||||||
|
defConf("game.menu.backgroundColor",15);
|
||||||
|
defConf("game.menu.maxVillagerLevel",100);
|
||||||
|
defConf("game.menu.item.lore",new ArrayList<String>() {{
|
||||||
|
add("Нажмите, чтобы продать");
|
||||||
|
add("Стак за {{price}}");
|
||||||
|
add("Мин. цена {{min_price}}");
|
||||||
|
add("Прогресс {{progress_cur}}/{{progress_max}} стаков");
|
||||||
|
}});
|
||||||
|
defConf("game.menu.info.tittle","Информация");
|
||||||
|
defConf("game.menu.info.lore",new ArrayList<String>() {{
|
||||||
|
add("Торгуй с умом");
|
||||||
|
}});
|
||||||
|
|
||||||
|
defConf("messages.mustBePlayer","Ты должен быть игроком");
|
||||||
|
defConf("messages.notAnyWhere","Вы не можете открывать торговлю дистанционно");
|
||||||
|
defConf("messages.noPerm","У вас прав нет на это");
|
||||||
|
defConf("messages.sold","Вы продали стак и получили {{price}}");
|
||||||
|
defConf("messages.notEnoughItems","Для продажи нужем минимум стак!");
|
||||||
|
|
||||||
|
saveConfig();
|
||||||
|
|
||||||
|
if (getServer().getPluginManager().getPlugin("Vault") == null) {
|
||||||
|
getLogger().warning("Oh shit, vault not found!");
|
||||||
|
}
|
||||||
|
RegisteredServiceProvider<Economy> rsp = getServer().getServicesManager().getRegistration(Economy.class);
|
||||||
|
if (rsp == null) {
|
||||||
|
getLogger().warning("Oh shit, vault economy not found!");
|
||||||
|
}
|
||||||
|
econ = rsp.getProvider();
|
||||||
|
|
||||||
|
if(this.getString("db.type").equals("mysql")) {
|
||||||
|
HikariConfig config = new HikariConfig();
|
||||||
|
config.setJdbcUrl("jdbc:mysql://" + getString("db.mysql.host") + ":" + getInt("db.mysql.port") + "/" + getString("db.mysql.base") + "?serverTimezone=" + getString("db.mysql.serverTimezone") + "&allowPublicKeyRetrieval=true&useSSL=" + getBoolean("db.mysql.useSSL"));
|
||||||
|
config.setUsername(getString("db.mysql.user"));
|
||||||
|
config.setPassword(getString("db.mysql.pass"));
|
||||||
|
config.setDriverClassName("com.mysql.cj.jdbc.Driver");
|
||||||
|
config.addDataSourceProperty("cachePrepStmts", "true");
|
||||||
|
config.addDataSourceProperty("prepStmtCacheSize", "250");
|
||||||
|
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
|
||||||
|
config.addDataSourceProperty("maximumPoolSize", getInt("db.mysql.maximumPoolSize"));
|
||||||
|
config.addDataSourceProperty("minimumIdle", getInt("db.mysql.minimumIdle"));
|
||||||
|
config.setMaxLifetime(getInt("db.mysql.maxLifetimeSeconds")*1000L);
|
||||||
|
|
||||||
|
new MySQLDatabase(new HikariDataSource(config),this.getString("db.mysql.tablePrefix"));
|
||||||
|
} else {
|
||||||
|
HikariConfig config = new HikariConfig();
|
||||||
|
config.setJdbcUrl("jdbc:h2:"+new File(getDataFolder(),getString("db.h2.file")).getAbsolutePath());
|
||||||
|
config.setDriverClassName("org.h2.Driver");
|
||||||
|
|
||||||
|
new H2Database(new HikariDataSource(config));
|
||||||
|
}
|
||||||
|
|
||||||
|
Bukkit.getPluginManager().registerEvents(new MenuFunctionListener(), this);
|
||||||
|
Bukkit.getPluginManager().registerEvents(this,this);
|
||||||
|
|
||||||
|
Bukkit.getServer().getPluginCommand("qseller").setExecutor(new QSellerCommand());
|
||||||
|
Bukkit.getServer().getPluginCommand("qseller").setTabCompleter(new QSellerCommand.TabComplete());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onNPCClick(NPCRightClickEvent event) {
|
||||||
|
if(getConfig().getIntegerList("game.menu.npcs").contains(event.getNPC().getId())) {
|
||||||
|
new QSellerMenu().open(event.getClicker());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisable() {
|
||||||
|
Database.getInstance().disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getString(String name) {
|
||||||
|
return getConfig().getString(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getStringList(String name) {
|
||||||
|
return getConfig().getStringList(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<SellItem> getSellItemList(String name) {
|
||||||
|
List<?> somethingList = getConfig().getList(name);
|
||||||
|
if (somethingList == null) {
|
||||||
|
return new ArrayList<>(0);
|
||||||
|
}
|
||||||
|
List<SellItem> result = new ArrayList<>();
|
||||||
|
for (Object object : somethingList) {
|
||||||
|
if (object instanceof SellItem) {
|
||||||
|
result.add((SellItem) object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<String> getParsedStringList(String name, OfflinePlayer player) {
|
||||||
|
return getConfig().getStringList(name).stream().map(str -> PlaceholderAPI.setPlaceholders(player, parseInternalPlaceholders(ChatColor.translateAlternateColorCodes('&',str),player))).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public String getParsedString(String name) {
|
||||||
|
return ChatColor.translateAlternateColorCodes('&',getConfig().getString(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public String getParsedString(String name, OfflinePlayer player) {
|
||||||
|
return PlaceholderAPI.setPlaceholders(player, parseInternalPlaceholders(ChatColor.translateAlternateColorCodes('&',getConfig().getString(name)),player));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String parseInternalPlaceholders(String text, OfflinePlayer player) {
|
||||||
|
return text.replaceAll("\\{\\{level}}",String.valueOf(Database.getInstance().getVillagerLevel(player.getUniqueId())));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getInt(String name) {
|
||||||
|
return getConfig().getInt(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getBoolean(String name) {
|
||||||
|
return getConfig().getBoolean(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void defConf(String name, Object value) {
|
||||||
|
if(!getConfig().isSet(name))
|
||||||
|
getConfig().set(name, value);
|
||||||
|
}
|
||||||
|
}
|
55
src/main/java/ru/redguy/qseller/QSellerCommand.java
Executable file
55
src/main/java/ru/redguy/qseller/QSellerCommand.java
Executable file
@ -0,0 +1,55 @@
|
|||||||
|
package ru.redguy.qseller;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandExecutor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.command.TabCompleter;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class QSellerCommand implements CommandExecutor {
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||||
|
switch (args.length) {
|
||||||
|
case 0: {
|
||||||
|
if(sender instanceof Player) {
|
||||||
|
if(sender.hasPermission("qseller.open")) {
|
||||||
|
new QSellerMenu().open((Player) sender);
|
||||||
|
} else {
|
||||||
|
sender.sendMessage(QSeller.getInstance().getParsedString("messages.notAnyWhere"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sender.sendMessage(QSeller.getInstance().getParsedString("messages.mustBePlayer"));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1: {
|
||||||
|
if(args[0].equals("reload")) {
|
||||||
|
if(sender.hasPermission("qseller.reload")) {
|
||||||
|
QSeller.getInstance().reloadConfig();
|
||||||
|
} else {
|
||||||
|
sender.sendMessage(QSeller.getInstance().getParsedString("messages.noPerm"));
|
||||||
|
}
|
||||||
|
} else if(Bukkit.getPlayer(args[0])!=null) {
|
||||||
|
if(sender.hasPermission("qseller.open.others")) {
|
||||||
|
new QSellerMenu().open(Bukkit.getPlayer(args[0]));
|
||||||
|
} else {
|
||||||
|
sender.sendMessage(QSeller.getInstance().getParsedString("messages.noPerm"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TabComplete implements TabCompleter {
|
||||||
|
@Override
|
||||||
|
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
171
src/main/java/ru/redguy/qseller/QSellerMenu.java
Executable file
171
src/main/java/ru/redguy/qseller/QSellerMenu.java
Executable file
@ -0,0 +1,171 @@
|
|||||||
|
package ru.redguy.qseller;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.Inventory;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
import org.bukkit.material.MaterialData;
|
||||||
|
import org.ipvp.canvas.ClickInformation;
|
||||||
|
import org.ipvp.canvas.Menu;
|
||||||
|
import org.ipvp.canvas.slot.Slot;
|
||||||
|
import org.ipvp.canvas.type.ChestMenu;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class QSellerMenu {
|
||||||
|
|
||||||
|
Menu menu;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the items of type from an inventory.
|
||||||
|
* @param inventory Inventory to modify
|
||||||
|
* @param type The type of Material to remove
|
||||||
|
* @param amount The amount to remove, or Integer.MAX_VALUE to remove all
|
||||||
|
* @return The amount of items that could not be removed, 0 for success, or -1 for failures
|
||||||
|
*/
|
||||||
|
public static int removeItems(Inventory inventory, Material type, short meta, int amount) {
|
||||||
|
|
||||||
|
if(type == null || inventory == null)
|
||||||
|
return -1;
|
||||||
|
if (amount <= 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (amount == Integer.MAX_VALUE) {
|
||||||
|
inventory.remove(type);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
HashMap<Integer,ItemStack> retVal = inventory.removeItem(new ItemStack(type,amount,meta));
|
||||||
|
|
||||||
|
int notRemoved = 0;
|
||||||
|
for(ItemStack item: retVal.values()) {
|
||||||
|
notRemoved+=item.getAmount();
|
||||||
|
}
|
||||||
|
return notRemoved;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sell(Player player, ClickInformation info) {
|
||||||
|
ItemStack item = info.getClickedSlot().getItem(player);
|
||||||
|
if(player.getInventory().contains(new ItemStack(item.getType(),item.getType().getMaxStackSize(),item.getData().getData()))) {
|
||||||
|
Optional<SellItem> items = QSeller.getInstance().getSellItemList("game.menu.items").stream().filter(i -> item.getType().equals(i.getItem())&&i.getMeta()==item.getData().getData()).findFirst();
|
||||||
|
if(items.isPresent()) {
|
||||||
|
int startStacks = QSeller.getInstance().getInt("game.menu.startStacks");
|
||||||
|
int step = QSeller.getInstance().getInt("game.menu.step");
|
||||||
|
int villagerLevel = Database.getInstance().getVillagerLevel(player.getUniqueId());
|
||||||
|
SellItem sellItem = items.get();
|
||||||
|
Database.getInstance().progressItem(player.getUniqueId(), item.getType());
|
||||||
|
removeItems(player.getInventory(), item.getType(), (short) sellItem.getMeta(), item.getType().getMaxStackSize());
|
||||||
|
double price = countPrice(player,sellItem,villagerLevel,startStacks, step);
|
||||||
|
QSeller.getInstance().econ.depositPlayer(player, price);
|
||||||
|
player.sendMessage(QSeller.getInstance().getParsedString("messages.sold", player).replaceAll("\\{\\{price}}",String.valueOf(price)));
|
||||||
|
|
||||||
|
checkForNewLevel(player,villagerLevel,startStacks, step);
|
||||||
|
|
||||||
|
render(player);
|
||||||
|
menu.update(player);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
player.sendMessage(QSeller.getInstance().getParsedString("messages.notEnoughItems", player));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private double countPrice(Player player, SellItem sellItem, int villagerLevel, int startStacks, int step) {
|
||||||
|
int progress = Database.getInstance().getItemProgress(player.getUniqueId(),sellItem.getItem());
|
||||||
|
return Math.max(sellItem.getHighPrice()+villagerLevel-1-progress, sellItem.getBasePrice());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkForNewLevel(Player player,int villagerLevel, int startStacks, int step) {
|
||||||
|
if(QSeller.getInstance().getInt("game.menu.maxVillagerLevel")<=villagerLevel) return;
|
||||||
|
for (SellItem sellItem : QSeller.getInstance().getSellItemList("game.menu.items")) {
|
||||||
|
int progress = Database.getInstance().getItemProgress(player.getUniqueId(),sellItem.getItem());
|
||||||
|
int maxProgress = startStacks+(villagerLevel-1)*step;
|
||||||
|
if(progress<maxProgress) return;
|
||||||
|
}
|
||||||
|
Database.getInstance().progressVillager(player.getUniqueId());
|
||||||
|
Menu oldMenu = menu;
|
||||||
|
menu = ChestMenu.builder(6)
|
||||||
|
.title(QSeller.getInstance().getParsedString("game.menu.title", player))
|
||||||
|
.build();
|
||||||
|
render(player);
|
||||||
|
oldMenu.close();
|
||||||
|
menu.open(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void render(Player player) {
|
||||||
|
int i = 0;
|
||||||
|
int item = 0;
|
||||||
|
int villagerLevel = Database.getInstance().getVillagerLevel(player.getUniqueId());
|
||||||
|
int startStacks = QSeller.getInstance().getInt("game.menu.startStacks");
|
||||||
|
int step = QSeller.getInstance().getInt("game.menu.step");
|
||||||
|
List<SellItem> items = QSeller.getInstance().getSellItemList("game.menu.items");
|
||||||
|
for (char ch : String.join("", QSeller.getInstance().getStringList("game.menu.structure")).toCharArray()) {
|
||||||
|
Slot slot = menu.getSlot(i);
|
||||||
|
ItemStack stack;
|
||||||
|
ItemMeta meta;
|
||||||
|
|
||||||
|
switch (ch) {
|
||||||
|
case '#':
|
||||||
|
stack = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) QSeller.getInstance().getInt("game.menu.backgroundColor"));
|
||||||
|
meta = stack.getItemMeta();
|
||||||
|
meta.setLocalizedName(" ");
|
||||||
|
stack.setItemMeta(meta);
|
||||||
|
|
||||||
|
slot.setItem(stack);
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
stack = new ItemStack(Material.SIGN);
|
||||||
|
meta = stack.getItemMeta();
|
||||||
|
meta.setLocalizedName(QSeller.getInstance().getParsedString("game.menu.info.tittle", player));
|
||||||
|
meta.setLore(QSeller.getInstance().getParsedStringList("game.menu.info.lore", player));
|
||||||
|
stack.setItemMeta(meta);
|
||||||
|
|
||||||
|
slot.setItem(stack);
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
if (item < items.size()) {
|
||||||
|
SellItem sellItem = items.get(item);
|
||||||
|
stack = new ItemStack(sellItem.getItem(),1, (byte) sellItem.getMeta());
|
||||||
|
if(stack.getType().equals(Material.AIR)) {
|
||||||
|
item++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
meta = stack.getItemMeta();
|
||||||
|
meta.setLore(
|
||||||
|
QSeller.getInstance().getParsedStringList("game.menu.item.lore", player).stream()
|
||||||
|
.map(str -> str.replaceAll("\\{\\{price}}", String.valueOf(countPrice(player,sellItem,villagerLevel,startStacks, step))))
|
||||||
|
.map(str -> str.replaceAll("\\{\\{min_price}}", String.valueOf(sellItem.getBasePrice()+villagerLevel-1)))
|
||||||
|
.map(str -> str.replaceAll("\\{\\{progress_cur}}", String.valueOf(Database.getInstance().getItemProgress(player.getUniqueId(),stack.getType()))))
|
||||||
|
.map(str -> str.replaceAll("\\{\\{progress_max}}", String.valueOf(startStacks+(villagerLevel-1)*step)))
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
);
|
||||||
|
stack.setItemMeta(meta);
|
||||||
|
|
||||||
|
slot.setItem(stack);
|
||||||
|
slot.setClickHandler(this::sell);
|
||||||
|
} else {
|
||||||
|
stack = new ItemStack(Material.STAINED_GLASS_PANE, 1, (short) 8);
|
||||||
|
meta = stack.getItemMeta();
|
||||||
|
meta.setLocalizedName(" ");
|
||||||
|
stack.setItemMeta(meta);
|
||||||
|
|
||||||
|
slot.setItem(stack);
|
||||||
|
}
|
||||||
|
item++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void open(Player player) {
|
||||||
|
menu = ChestMenu.builder(6)
|
||||||
|
.title(QSeller.getInstance().getParsedString("game.menu.title", player))
|
||||||
|
.build();
|
||||||
|
render(player);
|
||||||
|
menu.open(player);
|
||||||
|
}
|
||||||
|
}
|
98
src/main/java/ru/redguy/qseller/SellItem.java
Executable file
98
src/main/java/ru/redguy/qseller/SellItem.java
Executable file
@ -0,0 +1,98 @@
|
|||||||
|
package ru.redguy.qseller;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||||
|
import org.bukkit.configuration.serialization.SerializableAs;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@SerializableAs("SellItem")
|
||||||
|
public class SellItem implements Cloneable, ConfigurationSerializable {
|
||||||
|
|
||||||
|
Material item = Material.AIR;
|
||||||
|
short meta = 0;
|
||||||
|
double basePrice = 0.0;
|
||||||
|
double highPrice = 0.0;
|
||||||
|
|
||||||
|
public SellItem(String item, short meta, double basePrice, double highPrice) {
|
||||||
|
this.item = Material.valueOf(item);
|
||||||
|
this.meta = meta;
|
||||||
|
this.basePrice = basePrice;
|
||||||
|
this.highPrice = highPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SellItem(Material material, short meta, double basePrice, double highPrice) {
|
||||||
|
this.item = material;
|
||||||
|
this.meta = meta;
|
||||||
|
this.basePrice = basePrice;
|
||||||
|
this.highPrice = highPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SellItem(Material material) {
|
||||||
|
this.item = material;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Material getItem() {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setItem(Material item) {
|
||||||
|
this.item = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getMeta() {
|
||||||
|
return meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMeta(short meta) {
|
||||||
|
this.meta = meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getBasePrice() {
|
||||||
|
return basePrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBasePrice(double basePrice) {
|
||||||
|
this.basePrice = basePrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getHighPrice() {
|
||||||
|
return highPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHighPrice(double highPrice) {
|
||||||
|
this.highPrice = highPrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Object> serialize() {
|
||||||
|
LinkedHashMap<String,Object> result = new LinkedHashMap<>();
|
||||||
|
result.put("item", this.getItem().name());
|
||||||
|
result.put("meta", this.getMeta());
|
||||||
|
result.put("basePrice", this.getBasePrice());
|
||||||
|
result.put("highPrice", this.getHighPrice());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SellItem deserialize(Map<String, Object> args) {
|
||||||
|
Material item = Material.AIR;
|
||||||
|
short meta = 0;
|
||||||
|
double basePrice = 0.0D;
|
||||||
|
double highPrice = 0.0D;
|
||||||
|
|
||||||
|
if(args.containsKey("item")) {
|
||||||
|
item = Material.valueOf(String.valueOf(args.get("item")));
|
||||||
|
}
|
||||||
|
if(args.containsKey("meta")) {
|
||||||
|
meta = Short.parseShort(String.valueOf(args.get("meta")));
|
||||||
|
}
|
||||||
|
if(args.containsKey("basePrice")) {
|
||||||
|
basePrice = Double.parseDouble(String.valueOf(args.get("basePrice")));
|
||||||
|
}
|
||||||
|
if(args.containsKey("highPrice")) {
|
||||||
|
highPrice = Double.parseDouble(String.valueOf(args.get("highPrice")));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SellItem(item,meta,basePrice,highPrice);
|
||||||
|
}
|
||||||
|
}
|
22
src/main/resources/plugin.yml
Executable file
22
src/main/resources/plugin.yml
Executable file
@ -0,0 +1,22 @@
|
|||||||
|
name: QSeller
|
||||||
|
version: '${version}'
|
||||||
|
main: ru.redguy.qseller.QSeller
|
||||||
|
prefix: QSell
|
||||||
|
authors: [ RedGuy ]
|
||||||
|
description: Seller plugin
|
||||||
|
website: https://redguy.ru
|
||||||
|
commands:
|
||||||
|
qseller:
|
||||||
|
description: Открытие меню продавца
|
||||||
|
depend:
|
||||||
|
- Vault
|
||||||
|
permissions:
|
||||||
|
qseller.open:
|
||||||
|
default: not op
|
||||||
|
description: Позволяет открыть меню в любой точке мира
|
||||||
|
qseller.open.others:
|
||||||
|
default: not op
|
||||||
|
description: Позволяет открыть меню в любой точке мира для другого игрока
|
||||||
|
qseller.reload:
|
||||||
|
default: not op
|
||||||
|
description: Позволяет перезагрузить конфиг
|
Reference in New Issue
Block a user