├── .gitignore ├── README.md ├── messages ├── cesky.yml └── english.yml ├── pictures ├── block_logo.svg ├── command.gif ├── energy.gif ├── logo.png └── logo.svg ├── pom.xml └── src ├── main ├── java │ └── eu │ │ └── ncodes │ │ └── appwritedatabase │ │ ├── AppwriteDatabase.java │ │ ├── AppwriteDatabaseAPI.java │ │ ├── Enums │ │ ├── TypeOfListEnum.java │ │ └── TypeOfValueEnum.java │ │ ├── Instances │ │ ├── AppwriteCallback.java │ │ ├── AppwriteCallbackError.java │ │ ├── CacheInstance.java │ │ └── CacheValueInstance.java │ │ ├── Listeners │ │ ├── OnCommandListener.java │ │ ├── OnPlayerJoin.java │ │ └── OnPlayerLeave.java │ │ ├── Managers │ │ ├── CacheManager.java │ │ └── FileManager.java │ │ ├── Services │ │ ├── CreateCollectionService.java │ │ ├── DocumentService.java │ │ └── GetCollectionListService.java │ │ └── Utils │ │ ├── CommandUtils.java │ │ ├── PlaceholderAPI.java │ │ ├── PluginUtils.java │ │ └── PluginVariables.java └── resources │ ├── config.yml │ ├── defaults.yml │ ├── messages.yml │ └── plugin.yml └── test └── resources └── .gitkeep /.gitignore: -------------------------------------------------------------------------------- 1 | # User-specific stuff 2 | .idea/ 3 | 4 | *.iml 5 | *.ipr 6 | *.iws 7 | 8 | # IntelliJ 9 | out/ 10 | 11 | # Compiled class file 12 | *.class 13 | 14 | # Log file 15 | *.log 16 | 17 | # BlueJ files 18 | *.ctxt 19 | 20 | # Package Files # 21 | *.jar 22 | *.war 23 | *.nar 24 | *.ear 25 | *.zip 26 | *.tar.gz 27 | *.rar 28 | 29 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 30 | hs_err_pid* 31 | 32 | *~ 33 | 34 | # temporary files which can be created if a process still has a handle open of a deleted file 35 | .fuse_hidden* 36 | 37 | # KDE directory preferences 38 | .directory 39 | 40 | # Linux trash folder which might appear on any partition or disk 41 | .Trash-* 42 | 43 | # .nfs files are created when an open file is removed but is still being accessed 44 | .nfs* 45 | 46 | # General 47 | .DS_Store 48 | .AppleDouble 49 | .LSOverride 50 | 51 | # Icon must end with two \r 52 | Icon 53 | 54 | # Thumbnails 55 | ._* 56 | 57 | # Files that might appear in the root of a volume 58 | .DocumentRevisions-V100 59 | .fseventsd 60 | .Spotlight-V100 61 | .TemporaryItems 62 | .Trashes 63 | .VolumeIcon.icns 64 | .com.apple.timemachine.donotpresent 65 | 66 | # Directories potentially created on remote AFP share 67 | .AppleDB 68 | .AppleDesktop 69 | Network Trash Folder 70 | Temporary Items 71 | .apdisk 72 | 73 | # Windows thumbnail cache files 74 | Thumbs.db 75 | Thumbs.db:encryptable 76 | ehthumbs.db 77 | ehthumbs_vista.db 78 | 79 | # Dump file 80 | *.stackdump 81 | 82 | # Folder config file 83 | [Dd]esktop.ini 84 | 85 | # Recycle Bin used on file shares 86 | $RECYCLE.BIN/ 87 | 88 | # Windows Installer files 89 | *.cab 90 | *.msi 91 | *.msix 92 | *.msm 93 | *.msp 94 | 95 | # Windows shortcuts 96 | *.lnk 97 | 98 | target/ 99 | 100 | pom.xml.tag 101 | pom.xml.releaseBackup 102 | pom.xml.versionsBackup 103 | pom.xml.next 104 | 105 | release.properties 106 | dependency-reduced-pom.xml 107 | buildNumber.properties 108 | .mvn/timing.properties 109 | .mvn/wrapper/maven-wrapper.jar 110 | .flattened-pom.xml 111 | 112 | # Common working directory 113 | run/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![](https://jitpack.io/v/nCodesDotEU/Appwrite-Minecraft-Database.svg)](https://jitpack.io/#nCodesDotEU/Appwrite-Minecraft-Database) 2 | 3 | 4 | 5 | 6 | # Appwrite Minecraft SDK 7 | 8 | Utility Minecraft plugin that creates persistent data storage while using Appwrite as a database. This plugin was a missing piece on the scene for years! Finally, with Appwrite Minecraft SDK, storing data is as simple as `/appwrite database NiX3r set money 50`. A server makes no longer needs to pay over-priced developers just because there is no simple way to store data without writing Java code. 9 | 10 | ## 📜 Showcase 11 | 12 | I am a server administrator, I have no coding experience, and I want to customize my server... 13 | 14 | I have a dungeon minigame already created, but I don't want to let players play it infinitely; instead, I want to make this minigame a special reward. First, I start by running a command to define the variable `availableDungeonKeys` when a player first joins my server and set it to 0: 15 | 16 | ``` 17 | /appwrite database player set-remote %playername% availableDungeonKeys 3 18 | ``` 19 | 20 | Great, now when a new player joins, he will automatically have 3 keys. 21 | 22 | When starting a minigame, I can use the placeholder `%aw_p_availableDungeonKeys%` to get the value and check if the amount is higher than 0. If that is the case, I can run a command to take 1 key from the player: 23 | 24 | ``` 25 | /appwrite database player take-remote %playername% availableDungeonKeys 1 26 | ``` 27 | 28 | Now that I have taken one key from the player, I can let him into a minigame. Tada 🎉 I have just created a system where players can join my minigame, but they can only do it 3 times. 29 | 30 | Finally, I add an option to purchase more keys to my web-store and run the command once they purchase the keys: 31 | 32 | ``` 33 | /appwrite database player add-remote %playername% availableDungeonKeys 10 34 | ``` 35 | 36 | --- 37 | 38 | Let's take a look at another scenario... Let's say I need an energy system so the player can only join the minigame when he has at least 1 energy. Instead of buying it, he needs to collect 25 fragments in order to convert it to 1 energy. Fragments can be obtained by breaking a special block on the spawn. How do I achieve that? It's extremely simple! 39 | 40 | Let's start.. First, define variables when a player joins for the first time: 41 | 42 | ``` 43 | /appwrite database player set-remote %playername% energy 5 44 | /appwrite database player set-local %playername% fragments 0 45 | ``` 46 | 47 | Notice how I marked fragments local because I want to lose the value when a player leaves the server - I don't want to store that. 48 | 49 | Now, when a player breaks the specific block, I can run a command to increase his fragments count: 50 | 51 | ``` 52 | /appwrite database player add-local %playername% fragments 1 53 | ``` 54 | 55 | In this event, I also use placeholder `%aw_p_fragments%` to check if he has at least 25, and if that is the case, I reset it to 0 while increasing the energy count: 56 | 57 | ``` 58 | /appwrite database player add-remote %playername% energy 1 59 | /appwrite database player set-local %playername% fragments 0 60 | ``` 61 | 62 | Wohoo, energy system finished 🥳 Here is a working example of such a logic: 63 | 64 | 65 | 66 | ## 💿 How to install 67 | 68 | 1. Download the latest plugin from [Spigot](insert) (TODO) 69 | 2. Copy the jar file into the server plugins folder 70 | 3. Start / Restart the server to trigger the first load of the plugin 71 | 4. Insert Appwrite endpoint, project ID and API key into the generated config.yml file 72 | 5. Restart the server 73 | 6. **Enjoy Appwrite Database plugin!** 74 | 75 | ## ⌨️ Commands 76 | 77 | Aliases: `appwrite` | `aw`
78 | Example of commands usage:
79 | 80 | 81 | - **Help** 82 | - Command to show help menu in the game 83 | - Usage: `/appwrite help` 84 | - **Version** 85 | - Command to show the currently installed version 86 | - Usage: `/appwrite version` 87 | - Aliases: `version` | `ver` | `v` 88 | - Permisson: `appwrite.version` 89 | - **Database** 90 | - Command for work with the data storage 91 | - Aliases: `database` | `db` 92 | - Sub commands: 93 | - **Player** 94 | - Command to work with data of a specific player 95 | - Aliases `player` | `p` 96 | - Sub commands: 97 | - **Save** 98 | - Command for save cache into the database. This is triggered automatically when player leaves the server, but you can use this command to store it at a specific point. 99 | - Usage: `appwrite database player save ` 100 | - Aliases: `save` | `s` 101 | - Permission: `appwrite.player.save` 102 | - **Set Local** 103 | - Command to set a value of local variable 104 | - Usage: `appwrite database player set-local ` 105 | - Aliases: `set-local` | `sl` 106 | - Permission: `appwrite.player.set.local` 107 | - **Set Remote** 108 | - Command to set a value of remote variable 109 | - Usage: `appwrite database player set-remote ` 110 | - Aliases: `set-remote` | `sr` 111 | - Permission: `appwrite.player.set.remote` 112 | - **Add Local** 113 | - Command to increase a value of local variable 114 | - Usage: `appwrite database player add-remote ` 115 | - Aliases: `add-local` | `al` 116 | - Permission: `appwrite.player.add.local` 117 | - **Add Remote** 118 | - Command to increase a value of remote variable 119 | - Usage: `appwrite database player add-remote ` 120 | - Aliases: `add-remote` | `ar` 121 | - Permission: `appwrite.player.add.remote` 122 | - **Take Local** 123 | - Command to decrease a value of local variable 124 | - Usage: `appwrite database player take-local ` 125 | - Aliases: `takel-local` | `tl` 126 | - Permission: `appwrite.player.take.local` 127 | - **Take Remote** 128 | - Command to decrease a value of remote variable 129 | - Usage: `appwrite database player take-remote ` 130 | - Aliases: `take-remote` | `tr` 131 | - Permission: `appwrite.player.take.remote` 132 | - **Get** 133 | - Command to get a value of remote variable 134 | - Usage: `appwrite database player get ` 135 | - Aliases: `get` | `g` 136 | - Permission: `appwrite.player.get` 137 | - **Global** 138 | - Command to work with global database. Here you can store variables that are shared for everyone one the server. 139 | - Aliases `global` | `g` 140 | - Sub commands: 141 | - **Save** 142 | - Command to save the global cache into database 143 | - Usage: `appwrite database global save` 144 | - Aliases: `save` | `s` 145 | - Permission: `appwrite.global.save` 146 | - **Set Local** 147 | - Command to set a value of local variable 148 | - Usage: `appwrite database global set-local ` 149 | - Aliases: `set-local` | `sl` 150 | - Permission: `appwrite.global.set.local` 151 | - **Set Remote** 152 | - Command to set a value of remote variable 153 | - Usage: `appwrite database global set-remote ` 154 | - Aliases: `set-remote` | `sr` 155 | - Permission: `appwrite.global.set.remote` 156 | - **Add Local** 157 | - Command to increase a value of local variable 158 | - Usage: `appwrite database global add-remote ` 159 | - Aliases: `add-local` | `al` 160 | - Permission: `appwrite.global.add.local` 161 | - **Add Remote** 162 | - Command to increase a value of remote variable 163 | - Usage: `appwrite database global add-remote ` 164 | - Aliases: `add-remote` | `ar` 165 | - Permission: `appwrite.global.add.remote` 166 | - **Take Local** 167 | - Command to decrease a value of local variable 168 | - Usage: `appwrite database global take-local ` 169 | - Aliases: `takel-local` | `tl` 170 | - Permission: `appwrite.global.take.local` 171 | - **Take Remote** 172 | - Command to decrease a value of remote variable 173 | - Usage: `appwrite database global take-remote ` 174 | - Aliases: `take-remote` | `tr` 175 | - Permission: `appwrite.global.take.remote` 176 | - **Get** 177 | - Command to get a value of global variable 178 | - Usage: `appwrite database global get ` 179 | - Aliases: `get` | `g` 180 | - Permission: `appwrite.global.get` 181 | - **Reload** 182 | - Command to reload configs 183 | - Aliases `reload` | `r` 184 | - Sub commands: 185 | - **All** 186 | - Command to reload all configs 187 | - Usage: `appwrite reload all` 188 | - Aliases: `all` | `a` 189 | - Permission: `appwrite.reload.all` 190 | - **Messages** 191 | - Command to reload messages config 192 | - Usage: `appwrite reload messages` 193 | - Aliases: `messages` | `msg` | `m` 194 | - Permission: `appwrite.reload.messages` 195 | - **Config** 196 | - Command to reload config 197 | - Usage: `appwrite reload config` 198 | - Aliases: `config` | `c` 199 | - Permission: `appwrite.reload.config` 200 | 201 | ## 📐 Configs 202 | 203 | ### ⚙️ config.yml 204 | 205 | In the `config.yml` file, you can configure the connection to the Appwrite server. 206 | 207 | * **appwrite.api_endpoint:** Your Appwrite endpoint 208 | * **appwrite.project_id:** Your Appwrite project ID 209 | * **appwrite.api_key**: Your Appwrite API key 210 | 211 | ### 🈴 languages.yml 212 | 213 | * 🇺🇸 [English](https://github.com/nCodesDotEU/Appwrite-Minecraft-Database/blob/master/messages/english.yml) 214 | * 🇨🇿 [Česky](https://github.com/nCodesDotEU/Appwrite-Minecraft-Database/blob/master/messages/cesky.yml) 215 | * 🇸🇰 [Slovensky](insert) (TODO) 216 | 217 | ## 🧲 API 218 | 219 | Before using the API, make sure your plugin is set up a valid Maven project. 220 | 221 | First things first, you have to import the project from [JitPack](https://jitpack.io/#nCodesDotEU/Appwrite-Minecraft-Database). To do that, you enter `pom.xml` of your project and add `repository` and `dependency`. 222 | 223 | ``` 224 | ... 225 | 226 | jitpack.io 227 | https://jitpack.io 228 | 229 | ... 230 | 231 | com.github.nCodesDotEU 232 | Appwrite-Minecraft-Database 233 | Tag 234 | 235 | ... 236 | ``` 237 | 238 | Then, you can start using the API from class `AppwriteDatabaseAPI`, for example: 239 | 240 | ``` 241 | String playerName = "NiX3r"; 242 | Player player = Bukkit.getPlayer(playerName); 243 | String playerUUID = player.getUniqueId().toString(); 244 | 245 | AppwriteDatabaseAPI.addValueSync(playerUUID, "money", 12, true); 246 | ``` 247 | 248 | ## 🔮 PlaceholdersAPI 249 | 250 | - **Global** 251 | - Placeholder: `%aw_g_%` 252 | - Stands for global variables 253 | - **Player** 254 | - Placeholder: `%aw_p_%` 255 | - Stands for source player variable 256 | - **Other Player** 257 | - Placeholder: `%aw_po__%` 258 | - Stands for different players variable 259 | 260 | ## 📋 TO-DO List 261 | 262 | 1. Don't remove local variables 263 | 2. Aliasses - mathematical formulas to count 264 | 3. Events - create database events (such as OnDataChange, OnDataLoad, OnDataSave, ...) 265 | 4. Defaults - default values of variables 266 | 5. Inspects - inspect players keys, global keys and their values 267 | 6. TOP 10 - shows top 10 268 | 7. Merge data with external changes 269 | 270 | ## 📆 Versions 271 | 272 | | Plugin version | Description | 1.17 | 1.16 | 1.14 | 1.12 | 1.8 | 1.7 | 1.5 | 273 | | ------------------------------------------------------------ | ----------------------- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | 274 | | 0.0.1 | First release of plugin | ✔️ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | 275 | | [0.0.2](https://github.com/nCodesDotEU/Appwrite-Minecraft-Database/releases/tag/v0.0.2) | Huge refactor | ✔️ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | 276 | | [0.0.3](https://github.com/nCodesDotEU/Appwrite-Minecraft-Database/releases/tag/v0.0.3) | Fixed JitPack build | ✔️ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | 277 | 278 | 279 | 280 | ## ❓ FAQ 281 | 282 | ### 📣 Where to use local and where remote variables? 283 | 284 | Local variables are those that don't save in the database. On the other hand, remote variables are those that are saved in the database. That means you can use local variables as much as you want, and they'll never be stored in the database. Fun fact: You can create a local variable and then just set it as remote and vice versa. 285 | 286 | ### 📣 Types of variables 287 | 288 | You can use several variables types. Once you choose the type, you cannot change it - you must delete and then create in again to override the type. 289 | 290 | Types: 291 | 292 | - **INT** - number without a decimal point 293 | - **FLOAT** - number with a decimal point 294 | - **STRING** - everything else (typically text) 295 | 296 | Why do I need different types? 🤔 For example, if you have to store money, you have to store it as INT or FLOAT, because later you will need to increase or decrease the value by a relative amount. 297 | 298 | 299 | 300 | 301 | Built with Appwrite 302 | 303 | 304 | **My big pleasure for plugin logo to** [Neon](https://github.com/NeonSpork) 305 | -------------------------------------------------------------------------------- /messages/cesky.yml: -------------------------------------------------------------------------------- 1 | prefix: '&d&lAppwrite &8• &7' 2 | commands: 3 | help: '&7Pomocne menu' 4 | version: '&aVerze pluginu: {{version}}' 5 | set: 6 | player: 7 | success: '&a█ &7Klic &f{{key}} &7uspesne nastaven na &f{{value}} &7pro hrace 8 | &f{{player}}' 9 | not_found: '&6█ &7Kolekce nenalezena. Prosim zkuste to pozdeji' 10 | unexpected_error: '&c█ &7Neocekavana chyba. Prosim zkontrolujte Appwrite zaznamy' 11 | global: 12 | success: '&a█ &7Klic &f{{key}} &7uspesne nastaven na &f{{value}} &7pro obecna data' 13 | not_found: '&6█ &7Kolekce nenalezena. Prosim zkuste to pozdeji' 14 | unexpected_error: '&c█ &7Neocekavana chyba. Prosim zkontrolujte Appwrite zaznamy' 15 | add: 16 | player: 17 | success: '&a█ &7Klic &f{{key}} &7uspesne aktualizovan &8(+) &7na &f{{value}} 18 | &7pro hrace &f{{player}}' 19 | not_found: '&6█ &7Kolekce nenalezena. Prosim zkuste to pozdeji' 20 | unexpected_error: '&c█ &7Neocekavana chyba. Prosim zkontrolujte Appwrite zaznamy' 21 | global: 22 | success: '&a█ &7Klic &f{{key}} &7uspesne aktualizovan &8(+) &7na &f{{value}} 23 | &7pro obecna data' 24 | not_found: '&6█ &7Kolekce nenalezena. Prosim zkuste to pozdeji' 25 | unexpected_error: '&c█ &7Neocekavana chyba. Prosim zkontrolujte Appwrite zaznamy' 26 | take: 27 | player: 28 | success: '&a█ &7Klic &f{{key}} &7uspesne aktualizovan &8(-) &7na &f{{value}} 29 | &7pro hrace &f{{player}}' 30 | not_found: '&6█ &7Kolekce nenalezena. Prosim zkuste to pozdeji' 31 | unexpected_error: '&c█ &7Neocekavana chyba. Prosim zkontrolujte Appwrite zaznamy' 32 | global: 33 | success: '&a█ &7Klic &f{{key}} &7uspesne aktualizovan &8(-) &7na &f{{value}} 34 | &7pro obecna data' 35 | not_found: '&6█ &7Kolekce nenalezena. Prosim zkuste to pozdeji' 36 | unexpected_error: '&c█ &7Neocekavana chyba. Prosim zkontrolujte Appwrite zaznamy' 37 | get: 38 | player: 39 | success: '&a█ &f{{key}}&7: &f{{value}} &8({{player}})' 40 | not_found: '&6█ &7Klic &f{{key}} &7nenalezen. Prosim prvni nastavte nebo definujte vychozi hodnotu' 41 | unexpected_error: '&c█ &7Neocekavana chyba. Prosim zkontrolujte Appwrite zaznamy' 42 | global: 43 | success: '&a█ &f{{key}}&7: &f{{value}} &8(global)' 44 | not_found: '&6█ &7Klic &f{{key}} &7nenalezen. Prosim prvni nastavte nebo definujte vychozi hodnotu' 45 | unexpected_error: '&c█ &7Neocekavana chyba. Prosim zkontrolujte Appwrite zaznamy' 46 | config: 47 | all: '&a█ &7Uspesne nacteny &fvsechny &7soubory' 48 | messages: '&a█ &7Uspesne nacten &7soubor &fzprav' 49 | config: '&a█ &7Uspesne nacten &fmain &7soubor' 50 | -------------------------------------------------------------------------------- /messages/english.yml: -------------------------------------------------------------------------------- 1 | prefix: '&d&lAppwrite &8• &7' 2 | commands: 3 | help: '&7Help command' 4 | version: '&aPlugin version: {{version}}' 5 | set: 6 | player: 7 | success: '&a█ &7Key &f{{key}} &7successfully set to &f{{value}} &7for player 8 | &f{{player}}' 9 | not_found: '&6█ &7Cannot find collection. Please try again later' 10 | unexpected_error: '&c█ &7Unexpected server error. Please check Appwrite logs' 11 | global: 12 | success: '&a█ &7Key &f{{key}} &7successfully set to &f{{value}} &7on &fglobal 13 | &7storage' 14 | not_found: '&6█ &7Cannot find collection. Please try again later' 15 | unexpected_error: '&c█ &7Unexpected server error. Please check Appwrite logs' 16 | add: 17 | player: 18 | success: '&a█ &7Key &f{{key}} &7successfully updated &8(add) &7to &f{{value}} 19 | &7for player &f{{player}}' 20 | not_found: '&6█ &7Cannot find collection. Please try again later' 21 | unexpected_error: '&c█ &7Unexpected server error. Please check Appwrite logs' 22 | global: 23 | success: '&a█ &7Key &f{{key}} &7successfully updated &8(add) &7to &f{{value}} 24 | &7on &fglobal &7storage' 25 | not_found: '&6█ &7Cannot find collection. Please try again later' 26 | unexpected_error: '&c█ &7Unexpected server error. Please check Appwrite logs' 27 | take: 28 | player: 29 | success: '&a█ &7Key &f{{key}} &7successfully updated &8(take) &7to &f{{value}} 30 | &7for player &f{{player}}' 31 | not_found: '&6█ &7Cannot find collection. Please try again later' 32 | unexpected_error: '&c█ &7Unexpected server error. Please check Appwrite logs' 33 | global: 34 | success: '&a█ &7Key &f{{key}} &7successfully updated &8(take) &7to &f{{value}} 35 | &7on &fglobal &7storage' 36 | not_found: '&6█ &7Cannot find collection. Please try again later' 37 | unexpected_error: '&c█ &7Unexpected server error. Please check Appwrite logs' 38 | get: 39 | player: 40 | success: '&a█ &f{{key}}&7: &f{{value}} &8({{player}})' 41 | not_found: '&6█ &7Key &f{{key}} &7not found. Please set it first or define default 42 | value.' 43 | unexpected_error: '&c█ &7Unexpected server error. Please check Appwrite logs' 44 | global: 45 | success: '&a█ &f{{key}}&7: &f{{value}} &8(global)' 46 | not_found: '&6█ &7Key &f{{key}} &7not found. Please set it first or define default 47 | value.' 48 | unexpected_error: '&c█ &7Unexpected server error. Please check Appwrite logs' 49 | config: 50 | all: '&a█ &7Successfully reloaded &fall &7configs' 51 | messages: '&a█ &7Successfully reloaded &fmessages &7configs' 52 | config: '&a█ &7Successfully reloaded &fmain &7config' 53 | -------------------------------------------------------------------------------- /pictures/block_logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /pictures/command.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NiX3r/Appwrite-Minecraft-Database/b808e81f7a3d71aefd72afdab4d5ea94d9cb9a58/pictures/command.gif -------------------------------------------------------------------------------- /pictures/energy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NiX3r/Appwrite-Minecraft-Database/b808e81f7a3d71aefd72afdab4d5ea94d9cb9a58/pictures/energy.gif -------------------------------------------------------------------------------- /pictures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NiX3r/Appwrite-Minecraft-Database/b808e81f7a3d71aefd72afdab4d5ea94d9cb9a58/pictures/logo.png -------------------------------------------------------------------------------- /pictures/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | eu.ncodes 8 | appwrite-database 9 | 0.0.3 10 | jar 11 | 12 | Appwrite Database 13 | 14 | Utility Minecraft plugin that creates persistent data storage while using Appwrite 15 | 16 | 1.8 17 | UTF-8 18 | 19 | https://ncodes.eu 20 | 21 | 22 | 23 | 24 | org.apache.maven.plugins 25 | maven-compiler-plugin 26 | 3.8.1 27 | 28 | ${java.version} 29 | ${java.version} 30 | 31 | 32 | 33 | org.apache.maven.plugins 34 | maven-shade-plugin 35 | 3.2.4 36 | 37 | 38 | package 39 | 40 | shade 41 | 42 | 43 | false 44 | 45 | 46 | 47 | 48 | 49 | org.apache.maven.plugins 50 | maven-shade-plugin 51 | 3.1.0 52 | 53 | 54 | 55 | org.bstats 56 | eu.ncodes.appwritedatabase 57 | 58 | 59 | 60 | 61 | 62 | package 63 | 64 | shade 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | src/main/resources 73 | true 74 | 75 | 76 | 77 | 78 | 79 | 80 | spigotmc-repo 81 | https://hub.spigotmc.org/nexus/content/repositories/snapshots/ 82 | 83 | 84 | sonatype 85 | https://oss.sonatype.org/content/groups/public/ 86 | 87 | 88 | aikar 89 | https://repo.aikar.co/content/groups/aikar/ 90 | 91 | 92 | placeholderapi 93 | https://repo.extendedclip.com/content/repositories/placeholderapi/ 94 | 95 | 96 | 97 | 98 | 99 | org.bstats 100 | bstats-bukkit 101 | 2.2.1 102 | compile 103 | 104 | 105 | me.clip 106 | placeholderapi 107 | 2.10.10 108 | provided 109 | 110 | 111 | io.appwrite 112 | sdk-for-kotlin 113 | 0.1.0 114 | 115 | 116 | com.google.code.gson 117 | gson 118 | 2.8.6 119 | 120 | 121 | co.aikar 122 | acf-bukkit 123 | 0.5.0-SNAPSHOT 124 | 125 | 126 | org.spigotmc 127 | spigot-api 128 | 1.13.2-R0.1-SNAPSHOT 129 | provided 130 | 131 | 132 | org.junit.jupiter 133 | junit-jupiter-engine 134 | 5.3.1 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /src/main/java/eu/ncodes/appwritedatabase/AppwriteDatabase.java: -------------------------------------------------------------------------------- 1 | package eu.ncodes.appwritedatabase; 2 | 3 | import co.aikar.commands.BukkitCommandManager; 4 | import com.google.common.collect.ImmutableList; 5 | import eu.ncodes.appwritedatabase.Instances.CacheValueInstance; 6 | import eu.ncodes.appwritedatabase.Listeners.OnCommandListener; 7 | import eu.ncodes.appwritedatabase.Listeners.OnPlayerJoin; 8 | import eu.ncodes.appwritedatabase.Listeners.OnPlayerLeave; 9 | import eu.ncodes.appwritedatabase.Managers.CacheManager; 10 | import eu.ncodes.appwritedatabase.Managers.FileManager; 11 | import eu.ncodes.appwritedatabase.Services.CreateCollectionService; 12 | import eu.ncodes.appwritedatabase.Services.DocumentService; 13 | import eu.ncodes.appwritedatabase.Services.GetCollectionListService; 14 | import eu.ncodes.appwritedatabase.Utils.PlaceholderAPI; 15 | import eu.ncodes.appwritedatabase.Utils.PluginVariables; 16 | import io.appwrite.Client; 17 | import io.appwrite.services.Database; 18 | import org.bstats.bukkit.Metrics; 19 | import org.bukkit.Bukkit; 20 | import org.bukkit.ChatColor; 21 | import org.bukkit.entity.Player; 22 | import org.bukkit.plugin.java.JavaPlugin; 23 | 24 | import java.util.LinkedHashMap; 25 | 26 | public final class AppwriteDatabase extends JavaPlugin { 27 | 28 | public void onEnable() { 29 | 30 | // Initialize minecraft plugin variable 31 | PluginVariables.Plugin = this; 32 | PluginVariables.FileManager = new FileManager(this); 33 | 34 | // Create config if needed and load it 35 | PluginVariables.config = PluginVariables.FileManager.getConfig("config.yml"); 36 | PluginVariables.config.copyDefaults(true).save(); 37 | 38 | PluginVariables.lang = PluginVariables.FileManager.getConfig("messages.yml"); 39 | PluginVariables.lang.copyDefaults(true).save(); 40 | 41 | PluginVariables.defaults = PluginVariables.FileManager.getConfig("defaults.yml"); 42 | PluginVariables.defaults.copyDefaults(true).save(); 43 | 44 | if(PluginVariables.config.get("appwrite.api_endpoint").equals("https://[HOSTNAME_OR_IP]/v1") || 45 | PluginVariables.config.get("appwrite.project_id").equals("5df5acd0d48c2") || 46 | PluginVariables.config.get("appwrite.api_key").equals("919c2d18fb5d4...a2ae413da83346ad2")){ 47 | getServer().getConsoleSender().sendMessage(ChatColor.DARK_RED + "!! Config is a default template. Turning off plugin..."); 48 | Bukkit.getPluginManager().disablePlugin(this); 49 | } 50 | else{ // Countinue loading plugin 51 | 52 | // Connect to Appwrite 53 | PluginVariables.AppwriteClient = new Client() 54 | .setEndpoint(PluginVariables.config.get("appwrite.api_endpoint")) 55 | .setProject(PluginVariables.config.get("appwrite.project_id")) 56 | .setKey(PluginVariables.config.get("appwrite.api_key")); 57 | 58 | PluginVariables.AppwriteDatabase = new Database(PluginVariables.AppwriteClient); 59 | 60 | // Register events 61 | System.out.println("Registering events .... 1"); 62 | getServer().getPluginManager().registerEvents(new OnPlayerJoin(), this); 63 | System.out.println("Registering events .... 2"); 64 | getServer().getPluginManager().registerEvents(new OnPlayerLeave(), this); 65 | System.out.println("Registering events .... 3"); 66 | 67 | // Initialize and register commands 68 | // TODO - db global inspect auto complete write only '@page' 69 | PluginVariables.CommandManager = new BukkitCommandManager(this); 70 | 71 | PluginVariables.CommandManager.enableUnstableAPI("help"); 72 | PluginVariables.CommandManager.getCommandCompletions().registerCompletion("key", c -> { 73 | return ImmutableList.of(""); 74 | }); 75 | 76 | PluginVariables.CommandManager.getCommandCompletions().registerCompletion("value", c -> { 77 | return ImmutableList.of(""); 78 | }); 79 | 80 | PluginVariables.CommandManager.getCommandCompletions().registerCompletion("playerkey", c -> { 81 | try{ 82 | Player p = c.getPlayer(); 83 | if(p != null) { 84 | String group = p.getUniqueId().toString(); 85 | 86 | LinkedHashMap values = CacheManager.getInstance().getValues(group); 87 | 88 | 89 | String[] arr = new String[values.size() + 1]; 90 | values.keySet().toArray(arr); 91 | 92 | arr[arr.length - 1] = ""; 93 | 94 | return ImmutableList.copyOf(arr); 95 | } 96 | } 97 | catch (Exception ex){ 98 | return ImmutableList.of(""); 99 | } 100 | return ImmutableList.of(""); 101 | 102 | }); 103 | 104 | PluginVariables.CommandManager.getCommandCompletions().registerCompletion("globalkey", c -> { 105 | String group = AppwriteDatabaseAPI.GLOBAL_GROUP_NAME; 106 | 107 | LinkedHashMap values = CacheManager.getInstance().getValues(group); 108 | 109 | String[] arr = new String[values.size() + 1]; 110 | 111 | values.keySet().toArray(arr); 112 | 113 | arr[arr.length - 1] = ""; 114 | 115 | return ImmutableList.copyOf(arr); 116 | }); 117 | 118 | PluginVariables.CommandManager.registerCommand(new OnCommandListener()); 119 | 120 | // Surround it with try-catch 121 | try{ 122 | // Checks if collection data exists 123 | GetCollectionListService.GetListCollection((id) -> { 124 | if(id.equals("none")) { 125 | getLogger().info("Collection not found. Creating ..."); 126 | CreateCollectionService.CreateCollection((newId) -> { 127 | getLogger().info("Collection created!"); 128 | PluginVariables.DataCollectionID = newId; 129 | afterEnable(); 130 | }); 131 | } 132 | else { 133 | PluginVariables.DataCollectionID = id; 134 | afterEnable(); 135 | } 136 | }); 137 | } 138 | catch (Exception ex){ 139 | ex.printStackTrace(); 140 | getServer().getConsoleSender().sendMessage(ChatColor.DARK_RED + "!! Config connect to Appwrite database. Turning off plugin..."); 141 | Bukkit.getPluginManager().disablePlugin(this); 142 | } 143 | 144 | // Create instance of PlaceholderAPI 145 | if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { 146 | new PlaceholderAPI().register(); 147 | } 148 | 149 | // Create instance of bStats 150 | Metrics metrics = new Metrics(this, 13089); 151 | 152 | } 153 | 154 | } 155 | 156 | public void onDisable(){ 157 | 158 | // Save global data 159 | DocumentService.savePlayer(AppwriteDatabaseAPI.GLOBAL_GROUP_NAME, response -> { 160 | System.out.println("----> SAVED! <----"); 161 | }); 162 | 163 | } 164 | 165 | private void afterEnable() { 166 | 167 | OnPlayerJoin.OnJoin(AppwriteDatabaseAPI.GLOBAL_GROUP_NAME, isSuccess -> { 168 | if(!isSuccess){ 169 | Bukkit.getScheduler().runTask(PluginVariables.Plugin, x -> { 170 | Bukkit.getPluginManager().disablePlugin(PluginVariables.Plugin); 171 | }); 172 | } 173 | }); 174 | 175 | for(Player p : Bukkit.getOnlinePlayers()) { 176 | OnPlayerJoin.OnJoin(p.getUniqueId().toString(), isSuccess ->{ 177 | if(!isSuccess){ 178 | Bukkit.getScheduler().runTask(PluginVariables.Plugin, x -> { 179 | p.kickPlayer("Could not load data. Please try again."); 180 | }); 181 | } 182 | }); 183 | } 184 | } 185 | 186 | } 187 | -------------------------------------------------------------------------------- /src/main/java/eu/ncodes/appwritedatabase/AppwriteDatabaseAPI.java: -------------------------------------------------------------------------------- 1 | package eu.ncodes.appwritedatabase; 2 | 3 | import eu.ncodes.appwritedatabase.Instances.AppwriteCallback; 4 | import eu.ncodes.appwritedatabase.Instances.CacheValueInstance; 5 | import eu.ncodes.appwritedatabase.Managers.CacheManager; 6 | import eu.ncodes.appwritedatabase.Services.DocumentService; 7 | import eu.ncodes.appwritedatabase.Utils.PluginUtils; 8 | 9 | import java.util.function.Consumer; 10 | 11 | public class AppwriteDatabaseAPI { 12 | public static String GLOBAL_GROUP_NAME = "$global"; 13 | 14 | public static Object getGlobalValueSync(String key){ 15 | return getValueSync(GLOBAL_GROUP_NAME, key); 16 | } 17 | 18 | public static Object getValueSync(String group, String key) { 19 | CacheValueInstance cachedValue = CacheManager.getInstance().getValue(group, key); 20 | if(cachedValue == null) { 21 | return "0"; 22 | } 23 | return cachedValue.value; 24 | } 25 | 26 | public static Object setValueSync(String group, String key, Object value, Boolean isRemote) { 27 | CacheManager.getInstance().setValue(group, key, value.toString(), isRemote); 28 | return CacheManager.getInstance().getValue(group, key).value; 29 | } 30 | 31 | public static Object setGlobalValueSync(String key, Object value, Boolean isRemote){ 32 | return setValueSync(GLOBAL_GROUP_NAME, key, value, isRemote); 33 | } 34 | 35 | public static Object takeValueSync(String group, String key, Object value, Boolean isRemote) { 36 | try { 37 | String oldValue = CacheManager.getInstance().getValue(group, key).value.toString(); 38 | if(oldValue != null) { 39 | String newValue = PluginUtils.takeValue(oldValue, value.toString()); 40 | CacheManager.getInstance().setValue(group, key, newValue, isRemote); 41 | return CacheManager.getInstance().getValue(group, key).value; 42 | } else { 43 | throw new Exception("Old value not set"); 44 | } 45 | } catch(Exception exp) { 46 | return setValueSync(group, key, value, isRemote); 47 | } 48 | } 49 | 50 | public static Object takeGlobalValueSync(String key, Object value, Boolean isRemote){ 51 | return takeValueSync(GLOBAL_GROUP_NAME, key, value, isRemote); 52 | } 53 | 54 | public static Object addValueSync(String group, String key, Object value, Boolean isRemote) { 55 | try { 56 | String oldValue = CacheManager.getInstance().getValue(group, key).value.toString(); 57 | if(oldValue != null) { 58 | String newValue = PluginUtils.addValue(oldValue, value.toString()); 59 | CacheManager.getInstance().setValue(group, key, newValue, isRemote); 60 | return CacheManager.getInstance().getValue(group, key).value; 61 | } else { 62 | throw new Exception("Old value not set"); 63 | } 64 | } catch(Exception exp) { 65 | return setValueSync(group, key, value, isRemote); 66 | } 67 | } 68 | 69 | public static Object addGlobalValueSync(String key, Object value, Boolean isRemote){ 70 | return addValueSync(GLOBAL_GROUP_NAME, key, value, isRemote); 71 | } 72 | 73 | public static void saveGroupAsync(String group, Consumer callback){ 74 | 75 | DocumentService.savePlayer(group, response ->{ 76 | callback.accept(response); 77 | }); 78 | 79 | } 80 | 81 | // TODO - Add save all method 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/eu/ncodes/appwritedatabase/Enums/TypeOfListEnum.java: -------------------------------------------------------------------------------- 1 | package eu.ncodes.appwritedatabase.Enums; 2 | 3 | public enum TypeOfListEnum { 4 | PLAYER, 5 | GLOBAL, 6 | DEFAULTS 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/eu/ncodes/appwritedatabase/Enums/TypeOfValueEnum.java: -------------------------------------------------------------------------------- 1 | package eu.ncodes.appwritedatabase.Enums; 2 | 3 | public enum TypeOfValueEnum { 4 | INT, 5 | DOUBLE, 6 | STRING 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/eu/ncodes/appwritedatabase/Instances/AppwriteCallback.java: -------------------------------------------------------------------------------- 1 | package eu.ncodes.appwritedatabase.Instances; 2 | 3 | import com.google.gson.JsonObject; 4 | 5 | public class AppwriteCallback { 6 | public AppwriteCallbackError error; 7 | public Object value; 8 | public JsonObject document; 9 | 10 | public AppwriteCallback(AppwriteCallbackError error, Object value, JsonObject document) { 11 | this.error = error; 12 | this.value = value; 13 | this.document = document; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/eu/ncodes/appwritedatabase/Instances/AppwriteCallbackError.java: -------------------------------------------------------------------------------- 1 | package eu.ncodes.appwritedatabase.Instances; 2 | 3 | public enum AppwriteCallbackError { 4 | DOCUMENT_NOT_FOUND, 5 | UNEXPECTED_ERROR 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/eu/ncodes/appwritedatabase/Instances/CacheInstance.java: -------------------------------------------------------------------------------- 1 | package eu.ncodes.appwritedatabase.Instances; 2 | 3 | import java.util.LinkedHashMap; 4 | 5 | public class CacheInstance { 6 | 7 | public String PlayerUUID; 8 | public String DocumentID; 9 | public LinkedHashMap Values; 10 | 11 | public CacheInstance(String PlayerUUID, String DocumentID, LinkedHashMap Values){ 12 | this.PlayerUUID = PlayerUUID; 13 | this.DocumentID = DocumentID; 14 | this.Values = Values; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/eu/ncodes/appwritedatabase/Instances/CacheValueInstance.java: -------------------------------------------------------------------------------- 1 | package eu.ncodes.appwritedatabase.Instances; 2 | 3 | public class CacheValueInstance { 4 | public Object value; 5 | public Boolean isRemote; 6 | 7 | public CacheValueInstance(Object value, Boolean isRemote) { 8 | this.value = value; 9 | this.isRemote = isRemote; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/eu/ncodes/appwritedatabase/Listeners/OnCommandListener.java: -------------------------------------------------------------------------------- 1 | package eu.ncodes.appwritedatabase.Listeners; 2 | 3 | import co.aikar.commands.BaseCommand; 4 | import co.aikar.commands.CommandHelp; 5 | import co.aikar.commands.annotation.*; 6 | import com.google.gson.JsonArray; 7 | import com.google.gson.JsonElement; 8 | import com.google.gson.JsonObject; 9 | import eu.ncodes.appwritedatabase.AppwriteDatabaseAPI; 10 | import eu.ncodes.appwritedatabase.Enums.TypeOfListEnum; 11 | import eu.ncodes.appwritedatabase.Instances.AppwriteCallback; 12 | import eu.ncodes.appwritedatabase.Instances.AppwriteCallbackError; 13 | import eu.ncodes.appwritedatabase.Managers.CacheManager; 14 | import eu.ncodes.appwritedatabase.Services.DocumentService; 15 | import eu.ncodes.appwritedatabase.Utils.CommandUtils; 16 | import eu.ncodes.appwritedatabase.Utils.PluginUtils; 17 | import eu.ncodes.appwritedatabase.Utils.PluginVariables; 18 | import org.bukkit.Bukkit; 19 | import org.bukkit.ChatColor; 20 | import org.bukkit.command.CommandSender; 21 | import org.bukkit.entity.Player; 22 | 23 | import java.util.HashMap; 24 | import java.util.LinkedHashMap; 25 | import java.util.Map; 26 | import java.util.Set; 27 | import java.util.function.Consumer; 28 | 29 | import static co.aikar.commands.ACFBukkitUtil.sendMsg; 30 | 31 | @CommandAlias("appwrite|aw") 32 | public class OnCommandListener extends BaseCommand { 33 | 34 | @HelpCommand 35 | public void doHelp(CommandSender sender, CommandHelp help) { 36 | sendMsg(sender, PluginUtils.GetMessage("commands.help")); 37 | help.showHelp(); 38 | } 39 | 40 | @Subcommand("version|ver|v") 41 | @Description("Command for get plugin version") 42 | @CommandPermission("appwrite.version") 43 | public void GetVersion(CommandSender sender){ 44 | PluginUtils.SendMessage(sender, "commands.version", new LinkedHashMap(){{ 45 | put("version", PluginVariables.Plugin.getDescription().getVersion() + " - powered by Appwrite " + ChatColor.DARK_RED + "❤"); 46 | }}); 47 | } 48 | 49 | @Subcommand("database|db") // TODO - Add save commands 50 | @Description("Commands related to Appwrite database") 51 | public class DatabaseClass extends BaseCommand { 52 | 53 | /* TODO - Repair 54 | @Subcommand("defaults|def") 55 | @Description("Database defaults") 56 | public class DefaultsClass extends BaseCommand { 57 | 58 | @Subcommand("inspect") 59 | @Syntax("") 60 | @Description("Get 10 defaults per ") 61 | @CommandPermission("appwrite.defaults.inspect") 62 | @CommandCompletion("@page") 63 | public void InspectCommand(CommandSender sender, @Default("1") int page) { 64 | sharedListCommand(sender, page, TypeOfListEnum.DEFAULTS, null); 65 | } 66 | 67 | } 68 | */ 69 | @Subcommand("player|p") 70 | @Description("Per-player data storage") 71 | public class PersonalClass extends BaseCommand { 72 | 73 | /* TODO - Repair 74 | @Subcommand("inspect") 75 | @Syntax("") 76 | @Description("Get 10 player variables per ") 77 | @CommandPermission("appwrite.player.inspect") 78 | @CommandCompletion("@players @page") 79 | public void InspectCommand(CommandSender sender, String player, @Default("1") int page) { 80 | String uuid = Bukkit.getOfflinePlayer(player).getUniqueId().toString(); 81 | sharedListCommand(sender, page, TypeOfListEnum.GLOBAL, uuid); 82 | }*/ 83 | 84 | @Subcommand("save|s") 85 | @Syntax("") 86 | @Description("Manual player save") 87 | @CommandPermission("appwrite.player.save") 88 | @CommandCompletion("@players") 89 | public void SavePlayer(CommandSender sender, String player){ 90 | String uuid = Bukkit.getOfflinePlayer(player).getUniqueId().toString(); 91 | sharedSaveCommand(sender, uuid, false); 92 | } 93 | 94 | @Subcommand("set-local|sl") 95 | @Syntax(" ") 96 | @Description("Update current value of local to a new one on player storage") 97 | @CommandPermission("appwrite.player.set.local") 98 | @CommandCompletion("@players @playerkey @value") 99 | public void SetCommandLocal(CommandSender sender, String player, String key, String value) { 100 | String uuid = Bukkit.getOfflinePlayer(player).getUniqueId().toString(); 101 | sharedSetCommand(sender, key, value, uuid, player, false); 102 | } 103 | @Subcommand("set-remote|sr") 104 | @Syntax(" ") 105 | @Description("Update current value of remote to a new one on player storage") 106 | @CommandPermission("appwrite.player.set.remote") 107 | @CommandCompletion("@players @playerkey @value") 108 | public void SetCommandRemote(CommandSender sender, String player, String key, String value) { 109 | String uuid = Bukkit.getOfflinePlayer(player).getUniqueId().toString(); 110 | sharedSetCommand(sender, key, value, uuid, player, true); 111 | } 112 | 113 | @Subcommand("add-local|al") 114 | @Syntax(" ") 115 | @Description("Increase the current value of local on player storage") 116 | @CommandPermission("appwrite.player.add.local") 117 | @CommandCompletion("@players @playerkey @value") 118 | public void AddCommandLocal(CommandSender sender, String player, String key, String value) { 119 | String uuid = Bukkit.getOfflinePlayer(player).getUniqueId().toString(); 120 | sharedAddCommand(sender, key, value, uuid, player, false); 121 | } 122 | 123 | @Subcommand("add-remote|ar") 124 | @Syntax(" ") 125 | @Description("Increase the current value of remote on player storage") 126 | @CommandPermission("appwrite.player.add.remote") 127 | @CommandCompletion("@players @playerkey @value") 128 | public void AddCommandRemote(CommandSender sender, String player, String key, String value) { 129 | String uuid = Bukkit.getOfflinePlayer(player).getUniqueId().toString(); 130 | sharedAddCommand(sender, key, value, uuid, player, true); 131 | } 132 | 133 | @Subcommand("take-local|tl") 134 | @Syntax(" ") 135 | @Description("Decrease the current value of local on player storage") 136 | @CommandPermission("appwrite.player.take.local") 137 | @CommandCompletion("@players @playerkey @value") 138 | public void TakeCommandLocal(CommandSender sender, String player, String key, String value) { 139 | String uuid = Bukkit.getOfflinePlayer(player).getUniqueId().toString(); 140 | sharedTakeCommand(sender, key, value, uuid, player, false); 141 | } 142 | 143 | @Subcommand("take-remote|tr") 144 | @Syntax(" ") 145 | @Description("Decrease the current value of remote on player storage") 146 | @CommandPermission("appwrite.player.take.remote") 147 | @CommandCompletion("@players @playerkey @value") 148 | public void TakeCommandRemote(CommandSender sender, String player, String key, String value) { 149 | String uuid = Bukkit.getOfflinePlayer(player).getUniqueId().toString(); 150 | sharedTakeCommand(sender, key, value, uuid, player, true); 151 | } 152 | 153 | @Subcommand("get|g") 154 | @Syntax(" ") 155 | @Description("Get the current value of on player storage") 156 | @CommandPermission("appwrite.player.get") 157 | @CommandCompletion("@players @playerkey") 158 | public void GetCommand(CommandSender sender, String player, String key) { 159 | String uuid = Bukkit.getOfflinePlayer(player).getUniqueId().toString(); 160 | sharedGetCommand(sender, key, uuid, player); 161 | } 162 | } 163 | 164 | @Subcommand("global|g") 165 | @Description("Globally shared data storage") 166 | public class GlobalClass extends BaseCommand { 167 | /* TODO - Repair 168 | @Subcommand("inspect") 169 | @Syntax("") 170 | @Description("Get 10 global variables per ") 171 | @CommandPermission("appwrite.global.inspect") 172 | @CommandCompletion("@page") 173 | public void InspectCommand(CommandSender sender, @Default("1") int page){ 174 | sharedListCommand(sender, page, TypeOfListEnum.GLOBAL, null); 175 | }*/ 176 | 177 | @Subcommand("save|s") 178 | @Description("Manual global save") 179 | @CommandPermission("appwrite.global.save") 180 | public void SavePlayer(CommandSender sender){ 181 | sharedSaveCommand(sender, AppwriteDatabaseAPI.GLOBAL_GROUP_NAME, false); 182 | } 183 | 184 | @Subcommand("set-local|sl") 185 | @Syntax(" ") 186 | @Description("Update current value of local to a new one on global storage") 187 | @CommandPermission("appwrite.global.set.local") 188 | @CommandCompletion("@globalkey @value") 189 | public void SetCommandLocal(CommandSender sender, String key, String value) { 190 | String uuid = AppwriteDatabaseAPI.GLOBAL_GROUP_NAME; 191 | sharedSetCommand(sender, key, value, uuid, null, false); 192 | } 193 | 194 | @Subcommand("set-remote|sr") 195 | @Syntax(" ") 196 | @Description("Update current value of remote to a new one on global storage") 197 | @CommandPermission("appwrite.global.set.remote") 198 | @CommandCompletion("@globalkey @value") 199 | public void SetCommandRemote(CommandSender sender, String key, String value) { 200 | String uuid = AppwriteDatabaseAPI.GLOBAL_GROUP_NAME; 201 | sharedSetCommand(sender, key, value, uuid, null, true); 202 | } 203 | 204 | @Subcommand("add-local|al") 205 | @Syntax(" ") 206 | @Description("Increase the current value of local on global storage") 207 | @CommandPermission("appwrite.global.add.local") 208 | @CommandCompletion("@globalkey @value") 209 | public void AddCommandLocal(CommandSender sender, String key, String value) { 210 | String uuid = AppwriteDatabaseAPI.GLOBAL_GROUP_NAME; 211 | sharedAddCommand(sender, key, value, uuid, null, false); 212 | } 213 | 214 | @Subcommand("add-remote|ar") 215 | @Syntax(" ") 216 | @Description("Increase the current value of remote on global storage") 217 | @CommandPermission("appwrite.global.add.remote") 218 | @CommandCompletion("@globalkey @value") 219 | public void AddCommandRemote(CommandSender sender, String key, String value) { 220 | String uuid = AppwriteDatabaseAPI.GLOBAL_GROUP_NAME; 221 | sharedAddCommand(sender, key, value, uuid, null, true); 222 | } 223 | 224 | @Subcommand("take-local|tl") 225 | @Syntax(" ") 226 | @Description("Decrease the current value of local on global storage") 227 | @CommandPermission("appwrite.global.take.local") 228 | @CommandCompletion("@globalkey @value") 229 | public void TakeCommandLocal(CommandSender sender, String key, String value) { 230 | String uuid = AppwriteDatabaseAPI.GLOBAL_GROUP_NAME; 231 | sharedTakeCommand(sender, key, value, uuid, null, false); 232 | } 233 | 234 | @Subcommand("take-remote|tr") 235 | @Syntax(" ") 236 | @Description("Decrease the current value of remote on global storage") 237 | @CommandPermission("appwrite.global.take.remote") 238 | @CommandCompletion("@globalkey @value") 239 | public void TakeCommandRemote(CommandSender sender, String key, String value) { 240 | String uuid = AppwriteDatabaseAPI.GLOBAL_GROUP_NAME; 241 | sharedTakeCommand(sender, key, value, uuid, null, true); 242 | } 243 | 244 | @Subcommand("get|g") 245 | @Syntax("") 246 | @Description("Get the current value of on global storage") 247 | @CommandPermission("appwrite.global.get") 248 | @CommandCompletion("@globalkey") 249 | public void GetCommand(CommandSender sender, String key) { 250 | String uuid = AppwriteDatabaseAPI.GLOBAL_GROUP_NAME; 251 | sharedGetCommand(sender, key, uuid, null); 252 | } 253 | } 254 | } 255 | 256 | // TODO - reloads dont work (NullPointerException) 257 | @Subcommand("reload|r") 258 | public class ReloadClass extends BaseCommand{ 259 | 260 | @Subcommand("all|a") 261 | @CommandPermission("appwrite.reload.all") 262 | public void AllCommand(CommandSender sender) { 263 | PluginVariables.FileManager.reloadConfig("config.yml"); 264 | PluginVariables.FileManager.reloadConfig("messages.yml"); 265 | PluginUtils.SendMessage(sender, "commands.reload.all"); 266 | } 267 | 268 | @Subcommand("messages|msg|m") 269 | @CommandPermission("appwrite.reload.messages") 270 | public void MessagesCommand(CommandSender sender) { 271 | PluginVariables.FileManager.reloadConfig("messages.yml"); 272 | PluginUtils.SendMessage(sender, "commands.reload.messages"); 273 | } 274 | 275 | @Subcommand("config|c") 276 | @CommandPermission("appwrite.reload.config") 277 | public void ConfigCommand(CommandSender sender) { 278 | PluginVariables.FileManager.reloadConfig("config.yml"); 279 | PluginUtils.SendMessage(sender, "commands.reload.config"); 280 | } 281 | } 282 | 283 | private void sharedSaveCommand(CommandSender sender, String group, Boolean isAll){ 284 | 285 | String messageKeyPrefix = "commands.save." + (group.equals(AppwriteDatabaseAPI.GLOBAL_GROUP_NAME) ?"global." : "player."); 286 | if(isAll){} // TODO - Add save all 287 | else{ 288 | 289 | AppwriteDatabaseAPI.saveGroupAsync(group, response -> { 290 | 291 | 292 | if(response.error != null){ 293 | PluginUtils.SendMessage(sender, messageKeyPrefix + "unexpected_error", new LinkedHashMap()); 294 | } 295 | else { 296 | PluginUtils.SendMessage(sender, messageKeyPrefix + "success", new LinkedHashMap()); 297 | } 298 | 299 | }); 300 | 301 | 302 | 303 | } 304 | 305 | } 306 | 307 | /* TODO - Repair 308 | private void sharedListCommand(CommandSender sender, int page, TypeOfListEnum type, String group) { 309 | Consumer onFinish = (data) -> { 310 | 311 | String msg = ""; 312 | 313 | String cmd = data.get("cmd").getAsString(); 314 | int size = data.get("size").getAsInt(); 315 | JsonObject list = data.get("list").getAsJsonObject(); 316 | 317 | Set> entries = list.entrySet(); 318 | for (Map.Entry entry: entries) { 319 | msg += "\n&b" + entry.getKey() + ": &7" + entry.getValue().getAsString(); 320 | } 321 | 322 | msg = ChatColor.translateAlternateColorCodes('&', msg); 323 | sender.sendMessage(msg); 324 | CommandUtils.sendFooter(sender, cmd, page, ((size / 10) + 1)); 325 | }; 326 | 327 | if(type == TypeOfListEnum.DEFAULTS) { 328 | JsonObject dataObject = new JsonObject(); 329 | 330 | dataObject.addProperty("size", CommandUtils.getDefaultsSize()); 331 | dataObject.addProperty("cmd", "aw db def inspect"); 332 | dataObject.add("list", CommandUtils.getDefaultsHashMap((page - 1) * 10)); 333 | 334 | onFinish.accept(dataObject); 335 | } else if(type == TypeOfListEnum.GLOBAL) { 336 | String uuid = AppwriteDatabaseAPI.GLOBAL_GROUP_NAME; 337 | 338 | DocumentService.listDocuments(uuid, page, (response) -> { 339 | if(response.error != null) { 340 | // TODO: Napis error message 341 | return; 342 | } 343 | 344 | JsonObject documentListObject = (JsonObject) response.value; 345 | Integer sum = documentListObject.get("sum").getAsInt(); 346 | 347 | JsonObject dataJson = new JsonObject(); 348 | 349 | for(JsonElement documentEl : documentListObject.get("documents").getAsJsonArray()) { 350 | JsonObject document = documentEl.getAsJsonObject(); 351 | 352 | dataJson.add(document.get("key").getAsString(), document.get("value")); 353 | } 354 | 355 | JsonObject dataObject = new JsonObject(); 356 | 357 | dataObject.addProperty("size", sum); 358 | dataObject.addProperty("cmd", "aw db g inspect"); 359 | dataObject.add("list", dataJson); 360 | 361 | onFinish.accept(dataObject); 362 | }); 363 | } else if(type == TypeOfListEnum.PLAYER) { 364 | 365 | DocumentService.listDocuments(group, page, (response) -> { 366 | if(response.error != null) { 367 | // TODO: Napis error message 368 | return; 369 | } 370 | 371 | JsonObject documentListObject = (JsonObject) response.value; 372 | Integer sum = documentListObject.get("sum").getAsInt(); 373 | JsonObject dataJson = new JsonObject(); 374 | 375 | for(JsonElement documentEl : documentListObject.get("documents").getAsJsonArray()) { 376 | JsonObject document = documentEl.getAsJsonObject(); 377 | 378 | dataJson.add(document.get("key").getAsString(), document.get("value")); 379 | } 380 | 381 | JsonObject dataObject = new JsonObject(); 382 | 383 | dataObject.addProperty("size", sum); 384 | dataObject.addProperty("cmd", "aw db g inspect"); 385 | dataObject.add("list", dataJson); 386 | 387 | onFinish.accept(dataObject); 388 | }); 389 | } 390 | 391 | } 392 | */ 393 | private void sharedGetCommand(CommandSender sender, String key, String uuid, String playerName) { 394 | 395 | String messageKeyPrefix = "commands.get." + (playerName != null ? "player." : "global."); 396 | 397 | if(CacheManager.getInstance().getValues(uuid).containsKey(key)) { 398 | PluginUtils.SendMessage(sender, messageKeyPrefix + "success", new LinkedHashMap(){{ 399 | put("player", playerName); 400 | put("key", key); 401 | put("value", CacheManager.getInstance().getValues(uuid).get(key).value.toString()); 402 | }}); 403 | }else { 404 | PluginUtils.SendMessage(sender, messageKeyPrefix + "not_found", new LinkedHashMap(){{ 405 | put("player", playerName); 406 | put("key", key); 407 | }}); 408 | } 409 | 410 | } 411 | 412 | private void sharedSetCommand(CommandSender sender, String key, String value, String uuid, String playerName, Boolean isRemote) { 413 | String messageKeyPrefix = "commands.set." + (playerName != null ? "player." : "global."); 414 | 415 | AppwriteDatabaseAPI.setValueSync(uuid, key, value, isRemote); 416 | PluginUtils.SendMessage(sender, messageKeyPrefix + "success", new LinkedHashMap(){{ 417 | put("player", playerName); 418 | put("key", key); 419 | put("value", value); 420 | }}); 421 | 422 | } 423 | 424 | private void sharedAddCommand(CommandSender sender, String key, String value, String uuid, String playerName, Boolean isRemote) { 425 | String messageKeyPrefix = "commands.add." + (playerName != null ? "player." : "global."); 426 | String newValue = AppwriteDatabaseAPI.addValueSync(uuid, key, value, isRemote).toString(); 427 | 428 | PluginUtils.SendMessage(sender, messageKeyPrefix + "success", new LinkedHashMap(){{ 429 | put("player", playerName); 430 | put("key", key); 431 | put("value", newValue); 432 | }}); 433 | } 434 | 435 | private void sharedTakeCommand(CommandSender sender, String key, String value, String uuid, String playerName, Boolean isRemote) { 436 | String messageKeyPrefix = "commands.take." + (playerName != null ? "player." : "global."); 437 | String newValue = AppwriteDatabaseAPI.takeValueSync(uuid, key, value, isRemote).toString(); 438 | 439 | PluginUtils.SendMessage(sender, messageKeyPrefix + "success", new LinkedHashMap(){{ 440 | put("player", playerName); 441 | put("key", key); 442 | put("value", newValue); 443 | }}); 444 | } 445 | } 446 | -------------------------------------------------------------------------------- /src/main/java/eu/ncodes/appwritedatabase/Listeners/OnPlayerJoin.java: -------------------------------------------------------------------------------- 1 | package eu.ncodes.appwritedatabase.Listeners; 2 | 3 | import com.google.gson.JsonObject; 4 | import com.google.gson.JsonParser; 5 | import eu.ncodes.appwritedatabase.Instances.CacheValueInstance; 6 | import eu.ncodes.appwritedatabase.Managers.CacheManager; 7 | import eu.ncodes.appwritedatabase.Services.DocumentService; 8 | import eu.ncodes.appwritedatabase.Utils.PluginVariables; 9 | import org.bukkit.Bukkit; 10 | import org.bukkit.event.EventHandler; 11 | import org.bukkit.event.Listener; 12 | import org.bukkit.event.player.AsyncPlayerPreLoginEvent; 13 | import org.bukkit.event.player.PlayerJoinEvent; 14 | import org.jetbrains.annotations.NotNull; 15 | 16 | import java.util.LinkedHashMap; 17 | import java.util.concurrent.TimeUnit; 18 | import java.util.concurrent.atomic.AtomicReference; 19 | import java.util.function.Consumer; 20 | 21 | public class OnPlayerJoin implements Listener { 22 | 23 | // I know that this function 24 | 25 | @EventHandler 26 | public void On(@NotNull AsyncPlayerPreLoginEvent e) 27 | { 28 | 29 | System.out.println("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); 30 | 31 | AtomicReference isFinished = new AtomicReference<>(false); 32 | AtomicReference shouldKick = new AtomicReference<>(false); 33 | 34 | OnJoin(e.getUniqueId().toString(), isSuccess -> { 35 | isFinished.set(true); 36 | shouldKick.set(!isSuccess); 37 | }); 38 | 39 | while (!isFinished.get()){ 40 | 41 | try { 42 | TimeUnit.MILLISECONDS.sleep(300); 43 | } catch (InterruptedException ex) { 44 | ex.printStackTrace(); 45 | } 46 | 47 | } 48 | 49 | if(shouldKick.get()){ 50 | e.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, "Could not load data. Please try again."); 51 | } 52 | 53 | } 54 | 55 | @EventHandler 56 | public void OnJoin(PlayerJoinEvent e){ 57 | System.out.println(">>>>>>>>>>>>> JOINED <<<<<<<<<<<"); 58 | } 59 | 60 | public static void OnJoin(String uuid, Consumer callback) { 61 | /* 62 | Set defaultKeys = PluginVariables.defaults.getConfig().getConfigurationSection("defaults").getKeys(false); 63 | 64 | for(Object key : defaultKeys.toArray()) { 65 | Object value = PluginVariables.defaults.getConfig().get("defaults." + key.toString()); 66 | CacheManager.getInstance().setValue(uuid, key.toString(), value, null); 67 | } 68 | */ 69 | 70 | 71 | DocumentService.getPlayer(uuid, (response) -> { 72 | if(response.error != null) { 73 | callback.accept(false); 74 | return; 75 | } 76 | 77 | JsonObject data = (JsonObject) response.value; 78 | CacheManager.getInstance().ensureCache(uuid, data.get("$id").getAsString(), new LinkedHashMap()); 79 | 80 | JsonObject jsonData = JsonParser.parseString(data.get("value").getAsString()).getAsJsonObject(); 81 | 82 | for(String key : jsonData.keySet()) { 83 | Object value = jsonData.get(key); 84 | CacheManager.getInstance().setValue(uuid, key, value, true); 85 | } 86 | callback.accept(true); 87 | 88 | }); 89 | } 90 | } -------------------------------------------------------------------------------- /src/main/java/eu/ncodes/appwritedatabase/Listeners/OnPlayerLeave.java: -------------------------------------------------------------------------------- 1 | package eu.ncodes.appwritedatabase.Listeners; 2 | 3 | import eu.ncodes.appwritedatabase.AppwriteDatabaseAPI; 4 | import eu.ncodes.appwritedatabase.Managers.CacheManager; 5 | import eu.ncodes.appwritedatabase.Services.DocumentService; 6 | import org.bukkit.event.EventHandler; 7 | import org.bukkit.event.Listener; 8 | import org.bukkit.event.player.PlayerQuitEvent; 9 | 10 | public class OnPlayerLeave implements Listener { 11 | @EventHandler 12 | public void On(PlayerQuitEvent e) 13 | { 14 | 15 | AppwriteDatabaseAPI.saveGroupAsync(e.getPlayer().getUniqueId().toString(), response -> { 16 | 17 | CacheManager.getInstance().removeAll(e.getPlayer().getUniqueId().toString()); 18 | 19 | }); 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/eu/ncodes/appwritedatabase/Managers/CacheManager.java: -------------------------------------------------------------------------------- 1 | package eu.ncodes.appwritedatabase.Managers; 2 | 3 | import eu.ncodes.appwritedatabase.Instances.CacheInstance; 4 | import eu.ncodes.appwritedatabase.Instances.CacheValueInstance; 5 | 6 | import java.util.ArrayList; 7 | import java.util.LinkedHashMap; 8 | 9 | public class CacheManager { 10 | private static CacheManager _instance = null; 11 | public static CacheManager getInstance() 12 | { 13 | if (_instance == null) 14 | _instance = new CacheManager(); 15 | 16 | return _instance; 17 | } 18 | 19 | private LinkedHashMap cache = new LinkedHashMap(); 20 | 21 | public void ensureCache(String group, String docId, LinkedHashMap values){ 22 | if(!cache.containsKey(group)){ 23 | cache.put(group, new CacheInstance(group, docId, values)); 24 | } 25 | } 26 | 27 | public CacheValueInstance getValue(String group, String key) { 28 | if(cache.containsKey(group)) { 29 | CacheInstance playerCache = cache.get((group)); 30 | if(playerCache.Values.containsKey(key)) { 31 | return playerCache.Values.get(key); 32 | } 33 | } 34 | 35 | return null; 36 | } 37 | 38 | public LinkedHashMap getValues(String group) { 39 | if(cache.containsKey(group)) { 40 | LinkedHashMap playerCache = cache.get(group).Values; 41 | return playerCache; 42 | } 43 | 44 | return null; 45 | } 46 | 47 | public void setValue(String group, String key, Object value, Boolean isRemote) { 48 | LinkedHashMap playerCache = cache.get(group).Values; 49 | playerCache.remove(key); 50 | playerCache.put(key, new CacheValueInstance(value, isRemote)); 51 | } 52 | 53 | public void removeValue(String group, String key) { 54 | if(!cache.containsKey(group)) { 55 | return; 56 | } 57 | 58 | LinkedHashMap playerCache = cache.get(group).Values; 59 | playerCache.remove(key); 60 | } 61 | 62 | public void removeAll(String group) { 63 | cache.remove(group); 64 | } 65 | 66 | public String getDocumentID(String group){ 67 | return cache.get(group).DocumentID; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/eu/ncodes/appwritedatabase/Managers/FileManager.java: -------------------------------------------------------------------------------- 1 | package eu.ncodes.appwritedatabase.Managers; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.io.InputStreamReader; 6 | import java.io.Reader; 7 | import java.io.UnsupportedEncodingException; 8 | import java.util.HashMap; 9 | import java.util.LinkedHashMap; 10 | 11 | import org.bukkit.configuration.file.YamlConfiguration; 12 | import org.bukkit.plugin.java.JavaPlugin; 13 | 14 | 15 | public class FileManager { 16 | 17 | private final JavaPlugin plugin; 18 | private LinkedHashMap configs = new LinkedHashMap(); 19 | 20 | public FileManager(JavaPlugin plugin) 21 | { 22 | this.plugin = plugin; 23 | } 24 | 25 | /** 26 | * Get the config by the name(Don't forget the .yml) 27 | * 28 | * @param name 29 | * @return 30 | */ 31 | public Config getConfig(String name) { 32 | if (!configs.containsKey(name)) 33 | configs.put(name, new Config(name)); 34 | 35 | return configs.get(name); 36 | } 37 | 38 | /** 39 | * Save the config by the name(Don't forget the .yml) 40 | * 41 | * @param name 42 | * @return 43 | */ 44 | public Config saveConfig(String name) { 45 | return getConfig(name).save(); 46 | } 47 | 48 | /** 49 | * Reload the config by the name(Don't forget the .yml) 50 | * 51 | * @param name 52 | * @return 53 | */ 54 | public Config reloadConfig(String name) { 55 | return getConfig(name).reload(); 56 | } 57 | 58 | public class Config { 59 | 60 | private String name; 61 | private File file; 62 | private YamlConfiguration config; 63 | 64 | public Config(String name) 65 | { 66 | this.name = name; 67 | } 68 | 69 | /** 70 | * Saves the config as long as the config isn't empty 71 | * 72 | * @return 73 | */ 74 | public Config save() { 75 | if ((this.config == null) || (this.file == null)) 76 | return this; 77 | try 78 | { 79 | if (config.getConfigurationSection("").getKeys(true).size() != 0) 80 | config.save(this.file); 81 | } 82 | catch (IOException ex) 83 | { 84 | ex.printStackTrace(); 85 | } 86 | return this; 87 | } 88 | 89 | /** 90 | * Gets the config as a YamlConfiguration 91 | * 92 | * @return 93 | */ 94 | public YamlConfiguration get() { 95 | if (this.config == null) 96 | reload(); 97 | 98 | return this.config; 99 | } 100 | 101 | /** 102 | * Saves the default config(Will overwrite anything in the current config's file) 103 | *

104 | * Don't forget to reload after! 105 | * 106 | * @return 107 | */ 108 | public Config saveDefaultConfig() { 109 | file = new File(plugin.getDataFolder(), this.name); 110 | 111 | plugin.saveResource(this.name, false); 112 | 113 | return this; 114 | } 115 | 116 | /** 117 | * Reloads the config 118 | * 119 | * @return 120 | */ 121 | public Config reload() { 122 | if (file == null) 123 | this.file = new File(plugin.getDataFolder(), this.name); 124 | 125 | this.config = YamlConfiguration.loadConfiguration(file); 126 | 127 | Reader defConfigStream; 128 | try 129 | { 130 | defConfigStream = new InputStreamReader(plugin.getResource(this.name), "UTF8"); 131 | 132 | if (defConfigStream != null) 133 | { 134 | YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(defConfigStream); 135 | this.config.setDefaults(defConfig); 136 | } 137 | } 138 | catch (UnsupportedEncodingException | NullPointerException e) 139 | { 140 | 141 | } 142 | return this; 143 | } 144 | 145 | /** 146 | * Copies the config from the resources to the config's default settings. 147 | *

148 | * Force = true ----> Will add any new values from the default file 149 | *

150 | * Force = false ---> Will NOT add new values from the default file 151 | * 152 | * @param force 153 | * @return 154 | */ 155 | public Config copyDefaults(boolean force) { 156 | get().options().copyDefaults(force); 157 | return this; 158 | } 159 | 160 | /** 161 | * An easy way to set a value into the config 162 | * 163 | * @param key 164 | * @param value 165 | * @return 166 | */ 167 | public Config set(String key, Object value) { 168 | get().set(key, value); 169 | return this; 170 | } 171 | 172 | /** 173 | * An easy way to get a value from the config 174 | * 175 | * @param key 176 | * @return 177 | */ 178 | public String get(String key) { 179 | return get().get(key).toString(); 180 | } 181 | 182 | public Object getObject(String key) { 183 | return get().get(key); 184 | } 185 | 186 | public YamlConfiguration getConfig() { 187 | return this.config; 188 | } 189 | } 190 | 191 | } -------------------------------------------------------------------------------- /src/main/java/eu/ncodes/appwritedatabase/Services/CreateCollectionService.java: -------------------------------------------------------------------------------- 1 | package eu.ncodes.appwritedatabase.Services; 2 | 3 | import com.google.gson.JsonElement; 4 | import com.google.gson.JsonParser; 5 | import eu.ncodes.appwritedatabase.Utils.PluginVariables; 6 | import io.appwrite.exceptions.AppwriteException; 7 | import kotlin.Result; 8 | import kotlin.coroutines.Continuation; 9 | import kotlin.coroutines.CoroutineContext; 10 | import kotlin.coroutines.EmptyCoroutineContext; 11 | import okhttp3.Response; 12 | import org.jetbrains.annotations.NotNull; 13 | 14 | import java.util.ArrayList; 15 | import java.util.HashMap; 16 | import java.util.LinkedHashMap; 17 | import java.util.Map; 18 | import java.util.function.Consumer; 19 | 20 | public class CreateCollectionService { 21 | // TODO: Refactor 22 | public static void CreateCollection(Consumer callback) { 23 | 24 | // Create default rules 25 | ArrayList> rules = new ArrayList>(); 26 | 27 | Map uuid = new LinkedHashMap<>(); 28 | uuid.put("label", "Minecraft UUID"); 29 | uuid.put("key", "minecraftUUID"); 30 | uuid.put("type", "text"); 31 | uuid.put("default", ""); 32 | uuid.put("required", true); 33 | uuid.put("array", false); 34 | 35 | Map value = new LinkedHashMap<>(); 36 | value.put("label", "Value"); 37 | value.put("key", "value"); 38 | value.put("type", "text"); 39 | value.put("default", ""); 40 | value.put("required", true); 41 | value.put("array", false); 42 | 43 | rules.add(uuid); 44 | rules.add(value); 45 | 46 | try { 47 | PluginVariables.AppwriteDatabase.createCollection( 48 | "data", 49 | null, 50 | null, 51 | rules, 52 | new Continuation() { 53 | @NotNull 54 | @Override 55 | public CoroutineContext getContext() { 56 | return EmptyCoroutineContext.INSTANCE; 57 | } 58 | 59 | @Override 60 | public void resumeWith(@NotNull Object o) { 61 | String json = ""; 62 | try { 63 | if (o instanceof Result.Failure) { 64 | Result.Failure failure = (Result.Failure) o; 65 | throw failure.exception; 66 | } else { 67 | Response response = (Response) o; 68 | json = response.body().string(); 69 | JsonElement root = new JsonParser().parse(json); 70 | callback.accept(root.getAsJsonObject().get("$id").getAsString()); 71 | response.close(); 72 | return; 73 | } 74 | } catch (Throwable th) { 75 | th.printStackTrace(); 76 | } 77 | } 78 | } 79 | ); 80 | } catch (AppwriteException e) { 81 | e.printStackTrace(); 82 | } 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/eu/ncodes/appwritedatabase/Services/DocumentService.java: -------------------------------------------------------------------------------- 1 | package eu.ncodes.appwritedatabase.Services; 2 | 3 | import com.google.gson.JsonElement; 4 | import com.google.gson.JsonObject; 5 | import com.google.gson.JsonParser; 6 | import eu.ncodes.appwritedatabase.Instances.AppwriteCallback; 7 | import eu.ncodes.appwritedatabase.Instances.AppwriteCallbackError; 8 | import eu.ncodes.appwritedatabase.Instances.CacheValueInstance; 9 | import eu.ncodes.appwritedatabase.Managers.CacheManager; 10 | import eu.ncodes.appwritedatabase.Utils.PluginVariables; 11 | import kotlin.Result; 12 | import kotlin.coroutines.Continuation; 13 | import kotlin.coroutines.CoroutineContext; 14 | import kotlin.coroutines.EmptyCoroutineContext; 15 | import okhttp3.Response; 16 | import org.apache.commons.lang.math.NumberUtils; 17 | import org.jetbrains.annotations.NotNull; 18 | 19 | import java.util.ArrayList; 20 | import java.util.LinkedHashMap; 21 | import java.util.Map; 22 | import java.util.function.Consumer; 23 | 24 | public class DocumentService { 25 | 26 | public static void getPlayer(String group, Consumer callback) { 27 | try { 28 | ArrayList filters = new ArrayList<>(); 29 | filters.add("minecraftUUID=" + group); 30 | 31 | PluginVariables.AppwriteDatabase.listDocuments( 32 | PluginVariables.DataCollectionID, 33 | filters, 34 | new Continuation() { 35 | @NotNull 36 | @Override 37 | public CoroutineContext getContext() { 38 | return EmptyCoroutineContext.INSTANCE; 39 | } 40 | 41 | @Override 42 | public void resumeWith(@NotNull Object o) { 43 | try { 44 | if (o instanceof Result.Failure) { 45 | Result.Failure failure = (Result.Failure) o; 46 | throw failure.exception; 47 | } else { 48 | Response response = (Response) o; 49 | String json = response.body().string(); 50 | 51 | JsonElement root = new JsonParser().parse(json); 52 | 53 | try { 54 | JsonObject responseJson = root.getAsJsonObject(); 55 | JsonObject playerData = responseJson.getAsJsonArray("documents").get(0).getAsJsonObject(); 56 | callback.accept(new AppwriteCallback(null, playerData, null)); 57 | } catch(Exception err) { 58 | createPlayer(group, callback); 59 | } 60 | 61 | response.close(); 62 | } 63 | } catch (Throwable th) { 64 | th.printStackTrace(); 65 | callback.accept(new AppwriteCallback(AppwriteCallbackError.UNEXPECTED_ERROR, null, null)); 66 | } 67 | } 68 | } 69 | ); 70 | } 71 | catch(Exception ex) { 72 | ex.printStackTrace(); 73 | callback.accept(new AppwriteCallback(AppwriteCallbackError.UNEXPECTED_ERROR, null, null)); 74 | } 75 | } 76 | 77 | private static void createPlayer(String group, Consumer callback){ 78 | 79 | JsonObject value = new JsonObject(); 80 | 81 | Map document = new LinkedHashMap<>(); 82 | document.put("minecraftUUID", group); 83 | document.put("value", value.toString()); 84 | 85 | try { 86 | PluginVariables.AppwriteDatabase.createDocument( 87 | PluginVariables.DataCollectionID, 88 | document, 89 | new Continuation() { 90 | @NotNull 91 | @Override 92 | public CoroutineContext getContext() { 93 | return EmptyCoroutineContext.INSTANCE; 94 | } 95 | 96 | @Override 97 | public void resumeWith(@NotNull Object o) { 98 | try { 99 | if (o instanceof Result.Failure) { 100 | Result.Failure failure = (Result.Failure) o; 101 | throw failure.exception; 102 | } else { 103 | Response response = (Response) o; 104 | if(response.code() == 200 || response.code() == 201) { 105 | String json = response.body().string(); 106 | JsonElement root = new JsonParser().parse(json); 107 | callback.accept(new AppwriteCallback(null, root.getAsJsonObject(), null)); 108 | } else { 109 | System.out.println("GET Error22: " + response.code()); 110 | callback.accept(new AppwriteCallback(AppwriteCallbackError.UNEXPECTED_ERROR, null, null)); 111 | } 112 | response.close(); 113 | } 114 | } catch (Throwable th) { 115 | th.printStackTrace(); 116 | callback.accept(new AppwriteCallback(AppwriteCallbackError.UNEXPECTED_ERROR, null, null)); 117 | } 118 | } 119 | } 120 | ); 121 | 122 | } 123 | catch(Exception ex) { 124 | ex.printStackTrace(); 125 | callback.accept(new AppwriteCallback(AppwriteCallbackError.UNEXPECTED_ERROR, null, null)); 126 | } 127 | 128 | } 129 | 130 | public static void savePlayer(String group, Consumer callback) { 131 | 132 | String documentId = CacheManager.getInstance().getDocumentID(group); 133 | JsonObject value = new JsonObject(); 134 | LinkedHashMap cache = CacheManager.getInstance().getValues(group); 135 | for (String item : cache.keySet()) { 136 | if(cache.get(item).isRemote) { 137 | if (NumberUtils.isNumber(cache.get(item).value.toString())) { 138 | value.addProperty(item, Long.valueOf(cache.get(item).value.toString())); 139 | } else { 140 | value.addProperty(item, cache.get(item).value.toString()); 141 | } 142 | } 143 | } 144 | 145 | Map document = new LinkedHashMap<>(); 146 | //document.put("minecraftUUID", group); 147 | document.put("value", value.toString()); 148 | 149 | try { 150 | PluginVariables.AppwriteDatabase.updateDocument( 151 | PluginVariables.DataCollectionID, 152 | documentId, 153 | document, 154 | new Continuation() { 155 | @NotNull 156 | @Override 157 | public CoroutineContext getContext() { 158 | return EmptyCoroutineContext.INSTANCE; 159 | } 160 | 161 | @Override 162 | public void resumeWith(@NotNull Object o) { 163 | try { 164 | if (o instanceof Result.Failure) { 165 | Result.Failure failure = (Result.Failure) o; 166 | throw failure.exception; 167 | } else { 168 | Response response = (Response) o; 169 | if(response.code() == 200 || response.code() == 201) { 170 | String json = response.body().string(); 171 | JsonElement root = new JsonParser().parse(json); 172 | callback.accept(new AppwriteCallback(null, value, root.getAsJsonObject())); 173 | } else { 174 | System.out.println("GET Error2: " + response.code()); 175 | callback.accept(new AppwriteCallback(AppwriteCallbackError.DOCUMENT_NOT_FOUND, null, null)); 176 | } 177 | response.close(); 178 | } 179 | } catch (Throwable th) { 180 | th.printStackTrace(); 181 | callback.accept(new AppwriteCallback(AppwriteCallbackError.UNEXPECTED_ERROR, null, null)); 182 | } 183 | } 184 | } 185 | ); 186 | 187 | } 188 | catch(Exception ex) { 189 | ex.printStackTrace(); 190 | callback.accept(new AppwriteCallback(AppwriteCallbackError.UNEXPECTED_ERROR, null, null)); 191 | } 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /src/main/java/eu/ncodes/appwritedatabase/Services/GetCollectionListService.java: -------------------------------------------------------------------------------- 1 | package eu.ncodes.appwritedatabase.Services; 2 | 3 | import com.google.gson.JsonElement; 4 | import com.google.gson.JsonParser; 5 | import eu.ncodes.appwritedatabase.Utils.PluginVariables; 6 | import io.appwrite.exceptions.AppwriteException; 7 | import kotlin.Result; 8 | import kotlin.coroutines.Continuation; 9 | import kotlin.coroutines.CoroutineContext; 10 | import kotlin.coroutines.EmptyCoroutineContext; 11 | import okhttp3.Response; 12 | import org.jetbrains.annotations.NotNull; 13 | 14 | import java.util.function.Consumer; 15 | 16 | public class GetCollectionListService { 17 | // TODO: Refactor 18 | 19 | public static void GetListCollection(Consumer callback) { 20 | 21 | try { 22 | PluginVariables.AppwriteDatabase.listCollections(new Continuation() 23 | { 24 | @NotNull 25 | @Override 26 | public CoroutineContext getContext() { 27 | return EmptyCoroutineContext.INSTANCE; 28 | } 29 | 30 | @Override 31 | public void resumeWith(@NotNull Object o) { 32 | String json = ""; 33 | try { 34 | if (o instanceof Result.Failure) { 35 | Result.Failure failure = (Result.Failure) o; 36 | throw failure.exception; 37 | } else { 38 | Response response = (Response) o; 39 | boolean exists = false; 40 | json = response.body().string(); 41 | JsonElement root = new JsonParser().parse(json); 42 | for(JsonElement e : root.getAsJsonObject().get("collections").getAsJsonArray()) { 43 | if(e.getAsJsonObject().get("name").getAsString().equals("data")) { 44 | String output = e.getAsJsonObject().get("$id").getAsString(); 45 | exists = true; 46 | callback.accept(output); 47 | return; 48 | } 49 | } 50 | if(!exists) 51 | callback.accept("none"); 52 | response.close(); 53 | return; 54 | } 55 | } catch (Throwable th) { 56 | th.printStackTrace(); 57 | callback.accept("none"); 58 | return; 59 | } 60 | } 61 | } 62 | ); 63 | } catch (AppwriteException e) { 64 | e.printStackTrace(); 65 | callback.accept("none"); 66 | return; 67 | } 68 | 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/eu/ncodes/appwritedatabase/Utils/CommandUtils.java: -------------------------------------------------------------------------------- 1 | package eu.ncodes.appwritedatabase.Utils; 2 | 3 | import com.google.gson.JsonArray; 4 | import com.google.gson.JsonObject; 5 | import net.md_5.bungee.api.chat.ClickEvent; 6 | import net.md_5.bungee.api.chat.ComponentBuilder; 7 | import net.md_5.bungee.api.chat.HoverEvent; 8 | import net.md_5.bungee.api.chat.TextComponent; 9 | import org.bukkit.command.CommandSender; 10 | import org.bukkit.entity.Player; 11 | 12 | import java.util.*; 13 | 14 | public class CommandUtils { 15 | 16 | public static JsonObject getDefaultsHashMap(int startIndex) { 17 | JsonObject output = new JsonObject(); 18 | 19 | int outputIndex = 0, arrayIndex = 0; 20 | Set keysSet = PluginVariables.defaults.get().getConfigurationSection("defaults").getKeys(false); 21 | String[] keys = new String[keysSet.size()]; 22 | keysSet.toArray(keys); 23 | 24 | Arrays.sort(keys); 25 | 26 | for(String key : keys) { 27 | if(arrayIndex >= startIndex) { 28 | output.addProperty(key, PluginVariables.defaults.get().getConfigurationSection("defaults").getString(key)); 29 | outputIndex++; 30 | } 31 | 32 | if(outputIndex == 9) { 33 | break; 34 | } 35 | 36 | arrayIndex++; 37 | } 38 | 39 | return output; 40 | } 41 | 42 | public static int getDefaultsSize(){ 43 | return PluginVariables.defaults.get().getKeys(true).size() - 1; 44 | } 45 | 46 | public static void sendFooter(CommandSender target, String command, int currentPage, int maxPage){ 47 | // Footer visualtiazion 48 | String previous = "←--"; 49 | String current = "&a" + currentPage + "/" + maxPage; 50 | String next = "--→"; 51 | 52 | final ComponentBuilder message = new ComponentBuilder(""); 53 | 54 | command = "/" + command; 55 | 56 | if(currentPage == 1){ 57 | previous = "&7" + previous; 58 | message.append(previous.replace("&", "§")); 59 | } 60 | else{ 61 | previous = "&a" + previous; 62 | message.append(previous.replace("&", "§")); 63 | message.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, command + " " + (currentPage - 1))); 64 | message.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, 65 | TextComponent.fromLegacyText("§7Click to show previous page"))); 66 | } 67 | 68 | message.append(" " + current.replace("&", "§") + " "); 69 | message.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, command + " " + currentPage)); 70 | message.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, 71 | TextComponent.fromLegacyText("§7Click to refresh current page"))); 72 | 73 | if(currentPage == maxPage){ 74 | next = "&7" + next; 75 | message.append(next.replace("&", "§")); 76 | } 77 | else{ 78 | message.append(next.replace("&", "§")); 79 | next = "&a" + next; 80 | message.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, command + " " + (currentPage + 1))); 81 | message.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, 82 | TextComponent.fromLegacyText("§7Click to show next page"))); 83 | } 84 | 85 | target.spigot().sendMessage(message.create()); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/eu/ncodes/appwritedatabase/Utils/PlaceholderAPI.java: -------------------------------------------------------------------------------- 1 | package eu.ncodes.appwritedatabase.Utils; 2 | 3 | import eu.ncodes.appwritedatabase.AppwriteDatabase; 4 | import eu.ncodes.appwritedatabase.AppwriteDatabaseAPI; 5 | import me.clip.placeholderapi.expansion.PlaceholderExpansion; 6 | import org.bukkit.Bukkit; 7 | import org.bukkit.OfflinePlayer; 8 | import org.bukkit.event.Listener; 9 | import org.jetbrains.annotations.NotNull; 10 | 11 | public class PlaceholderAPI extends PlaceholderExpansion { 12 | 13 | 14 | @Override 15 | public @NotNull String getIdentifier() { 16 | return "aw"; 17 | } 18 | 19 | @Override 20 | public @NotNull String getAuthor() { 21 | return "nCodes"; 22 | } 23 | 24 | @Override 25 | public @NotNull String getVersion() { 26 | return "0.0.1"; 27 | } 28 | 29 | @Override 30 | public String onRequest(OfflinePlayer player, String params) { 31 | try { 32 | if(player == null) { 33 | return "0"; 34 | } 35 | 36 | String[] splitter = params.split("_"); 37 | 38 | if(splitter.length >= 2) { 39 | 40 | switch (splitter[0]) { 41 | // If placeholder stands for global 42 | case "g": 43 | return AppwriteDatabaseAPI.getGlobalValueSync(splitter[1]).toString(); 44 | // If placeholder stands for player 45 | case "p": 46 | return AppwriteDatabaseAPI.getValueSync(player.getUniqueId().toString(), splitter[1]).toString(); 47 | // If placeholder stands for player other 48 | case "po": 49 | String uuid = Bukkit.getOfflinePlayer(splitter[1]).getUniqueId().toString(); 50 | return AppwriteDatabaseAPI.getValueSync(uuid, splitter[2]).toString(); 51 | } 52 | 53 | } 54 | } catch(Exception exp) { 55 | return "0"; 56 | } 57 | 58 | return "0"; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/eu/ncodes/appwritedatabase/Utils/PluginUtils.java: -------------------------------------------------------------------------------- 1 | package eu.ncodes.appwritedatabase.Utils; 2 | 3 | import com.google.gson.JsonElement; 4 | import com.google.gson.JsonObject; 5 | import eu.ncodes.appwritedatabase.Enums.TypeOfValueEnum; 6 | import eu.ncodes.appwritedatabase.Instances.AppwriteCallback; 7 | import eu.ncodes.appwritedatabase.Services.DocumentService; 8 | import org.apache.commons.lang.math.NumberUtils; 9 | import org.bukkit.ChatColor; 10 | import org.bukkit.command.CommandSender; 11 | 12 | import java.util.ArrayList; 13 | import java.util.HashMap; 14 | import java.util.LinkedHashMap; 15 | import java.util.function.Consumer; 16 | 17 | public class PluginUtils { 18 | 19 | public static String GetMessage(boolean usePrefix, String messageKey, LinkedHashMap values) { 20 | 21 | String message = ""; 22 | 23 | if(usePrefix) { 24 | message = PluginVariables.lang.get("prefix"); 25 | } 26 | 27 | message += PluginVariables.lang.get(messageKey); 28 | 29 | for(String key : values.keySet()) { 30 | if(values.get(key) != null) { 31 | message = message.replace("{{" + key + "}}", values.get(key)); 32 | } 33 | } 34 | 35 | return ChatColor.translateAlternateColorCodes('&', message); 36 | } 37 | 38 | 39 | public static void SendMessage(CommandSender target, boolean usePrefix, String messageKey, LinkedHashMap values) { 40 | target.sendMessage(GetMessage(usePrefix, messageKey, values)); 41 | } 42 | 43 | public static void SendMessage(CommandSender target, String messageKey, LinkedHashMap values) { 44 | SendMessage(target, true, messageKey, values); 45 | } 46 | 47 | public static void SendMessage(CommandSender target, String messageKey) { 48 | SendMessage(target, true, messageKey, new LinkedHashMap<>()); 49 | } 50 | 51 | public static String GetMessage(String messageKey, LinkedHashMap values) { 52 | return GetMessage(true, messageKey, values); 53 | } 54 | 55 | public static String GetMessage(String messageKey) { 56 | return GetMessage(true, messageKey, new LinkedHashMap<>()); 57 | } 58 | 59 | 60 | 61 | public static String addValue(String oldValue, String newValue) { 62 | TypeOfValueEnum newValueType = PluginUtils.GetValueType(newValue); 63 | TypeOfValueEnum oldValueType = PluginUtils.GetValueType(oldValue); 64 | 65 | String value = newValue; 66 | 67 | if(oldValueType.equals(TypeOfValueEnum.STRING)) { 68 | value = oldValue + newValue; 69 | } else if(oldValueType.equals(TypeOfValueEnum.INT)) { 70 | value = "" + (NumberUtils.toInt(oldValue, 0) + NumberUtils.toInt(newValue, 0)); 71 | } else if(oldValueType.equals(TypeOfValueEnum.DOUBLE)) { 72 | value = "" + (NumberUtils.toDouble(oldValue, 0D) + NumberUtils.toDouble(newValue, 0D)); 73 | } 74 | 75 | return value; 76 | } 77 | 78 | public static String takeValue(String oldValue, String newValue) { 79 | TypeOfValueEnum oldValueType = PluginUtils.GetValueType(oldValue); 80 | 81 | String value = newValue; 82 | 83 | if(oldValueType.equals(TypeOfValueEnum.STRING)) { 84 | value = oldValue.replace(newValue, ""); 85 | } else if(oldValueType.equals(TypeOfValueEnum.INT)) { 86 | value = "" + (NumberUtils.toInt(oldValue, 0) - NumberUtils.toInt(newValue, 0)); 87 | } else if(oldValueType.equals(TypeOfValueEnum.DOUBLE)) { 88 | value = "" + (NumberUtils.toDouble(oldValue, 0D) - NumberUtils.toDouble(newValue, 0D)); 89 | } 90 | 91 | return value; 92 | } 93 | 94 | public static TypeOfValueEnum GetValueType(String value) { 95 | try { 96 | Integer.parseInt(value); 97 | return TypeOfValueEnum.INT; 98 | } catch(Exception ex) {} 99 | 100 | try { 101 | Double.parseDouble(value); 102 | return TypeOfValueEnum.DOUBLE; 103 | } catch(Exception ex) {} 104 | 105 | return TypeOfValueEnum.STRING; 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/eu/ncodes/appwritedatabase/Utils/PluginVariables.java: -------------------------------------------------------------------------------- 1 | package eu.ncodes.appwritedatabase.Utils; 2 | 3 | import co.aikar.commands.BukkitCommandManager; 4 | import eu.ncodes.appwritedatabase.Managers.FileManager; 5 | import io.appwrite.Client; 6 | import io.appwrite.services.Database; 7 | import org.bukkit.plugin.java.JavaPlugin; 8 | 9 | public class PluginVariables { 10 | 11 | // Instance for minecraft command manager 12 | public static BukkitCommandManager CommandManager; 13 | 14 | // Instance for minecraft plugin 15 | public static JavaPlugin Plugin; 16 | 17 | // Instance for appwrite client 18 | public static Client AppwriteClient; 19 | 20 | // Instance for appwrite database 21 | public static Database AppwriteDatabase; 22 | 23 | // Instance for data collection ID 24 | public static String DataCollectionID; 25 | 26 | // File manager for configs (yml) 27 | public static FileManager FileManager; 28 | 29 | // Config classes to interact with 30 | public static FileManager.Config config; 31 | public static FileManager.Config lang; 32 | public static FileManager.Config defaults; 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/resources/config.yml: -------------------------------------------------------------------------------- 1 | appwrite: 2 | # GET THESE FROM YOUR APPWRITE CONSOLE 3 | api_endpoint: 'https://[HOSTNAME_OR_IP]/v1' 4 | project_id: '5df5acd0d48c2' 5 | api_key: '919c2d18fb5d4...a2ae413da83346ad2' -------------------------------------------------------------------------------- /src/main/resources/defaults.yml: -------------------------------------------------------------------------------- 1 | # Configure your default values here 2 | defaults: 3 | tokens: 10 4 | rank: "Unranked" -------------------------------------------------------------------------------- /src/main/resources/messages.yml: -------------------------------------------------------------------------------- 1 | prefix: '&d&lAppwrite &8• &7' 2 | commands: 3 | help: "&7Help command" 4 | version: '&aPlugin version: {{version}}' 5 | save: 6 | player: 7 | success: "&a█ &7Player succesfully saved" 8 | unexpected_error: "&c█ &7Unexpected server error. Please check Appwrite logs" 9 | global: 10 | success: "&a█ &7Global succesfully saved" 11 | unexpected_error: "&c█ &7Unexpected server error. Please check Appwrite logs" 12 | all: 13 | success: "&a█ &7Everything succesfully saved" 14 | unexpected_error: "&c█ &7Unexpected server error. Please check Appwrite logs" 15 | set: 16 | player: 17 | success: "&a█ &7Key &f{{key}} &7successfully set to &f{{value}} &7for player &f{{player}}" 18 | not_found: "&6█ &7Cannot find collection. Please try again later" 19 | unexpected_error: "&c█ &7Unexpected server error. Please check Appwrite logs" 20 | global: 21 | success: "&a█ &7Key &f{{key}} &7successfully set to &f{{value}} &7on &fglobal &7storage" 22 | not_found: "&6█ &7Cannot find collection. Please try again later" 23 | unexpected_error: "&c█ &7Unexpected server error. Please check Appwrite logs" 24 | add: 25 | player: 26 | success: "&a█ &7Key &f{{key}} &7successfully updated &8(add) &7to &f{{value}} &7for player &f{{player}}" 27 | not_found: "&6█ &7Cannot find collection. Please try again later" 28 | unexpected_error: "&c█ &7Unexpected server error. Please check Appwrite logs" 29 | global: 30 | success: "&a█ &7Key &f{{key}} &7successfully updated &8(add) &7to &f{{value}} &7on &fglobal &7storage" 31 | not_found: "&6█ &7Cannot find collection. Please try again later" 32 | unexpected_error: "&c█ &7Unexpected server error. Please check Appwrite logs" 33 | take: 34 | player: 35 | success: "&a█ &7Key &f{{key}} &7successfully updated &8(take) &7to &f{{value}} &7for player &f{{player}}" 36 | not_found: "&6█ &7Cannot find collection. Please try again later" 37 | unexpected_error: "&c█ &7Unexpected server error. Please check Appwrite logs" 38 | global: 39 | success: "&a█ &7Key &f{{key}} &7successfully updated &8(take) &7to &f{{value}} &7on &fglobal &7storage" 40 | not_found: "&6█ &7Cannot find collection. Please try again later" 41 | unexpected_error: "&c█ &7Unexpected server error. Please check Appwrite logs" 42 | get: 43 | player: 44 | success: "&a█ &f{{key}}&7: &f{{value}} &8({{player}})" 45 | not_found: "&6█ &7Key &f{{key}} &7not found. Please set it first or define default value." 46 | unexpected_error: "&c█ &7Unexpected server error. Please check Appwrite logs" 47 | global: 48 | success: "&a█ &f{{key}}&7: &f{{value}} &8(global)" 49 | not_found: "&6█ &7Key &f{{key}} &7not found. Please set it first or define default value." 50 | unexpected_error: "&c█ &7Unexpected server error. Please check Appwrite logs" 51 | config: 52 | all: "&a█ &7Successfully reloaded &fall &7configs" 53 | messages: "&a█ &7Successfully reloaded &fmessages &7configs" 54 | config: "&a█ &7Successfully reloaded &fmain &7config" -------------------------------------------------------------------------------- /src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: AppwriteDatabase 2 | version: '${project.version}' 3 | main: eu.ncodes.appwritedatabase.AppwriteDatabase 4 | api-version: 1.13 5 | prefix: AppwriteAPI 6 | authors: [ nCodes, Meldiron ] 7 | description: Utility Minecraft plugin that creates persistent data storage while using Appwrite 8 | website: https://ncodes.eu 9 | softdepend: [PlaceholderAPI] -------------------------------------------------------------------------------- /src/test/resources/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NiX3r/Appwrite-Minecraft-Database/b808e81f7a3d71aefd72afdab4d5ea94d9cb9a58/src/test/resources/.gitkeep --------------------------------------------------------------------------------