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