├── .circleci └── config.yml ├── .gitignore ├── LICENSE ├── README.md ├── build.gradle.kts ├── datasync-api └── src │ └── main │ └── java │ └── org │ └── anvilpowered │ └── datasync │ └── api │ ├── DataSync.java │ ├── key │ └── DataKeyService.java │ ├── member │ ├── MemberManager.java │ ├── MemberRepository.java │ ├── MongoMemberRepository.java │ └── XodusMemberRepository.java │ ├── misc │ └── SyncUtils.java │ ├── model │ ├── member │ │ └── Member.java │ └── snapshot │ │ └── Snapshot.java │ ├── registry │ └── DataSyncKeys.java │ ├── serializer │ ├── ExperienceSerializer.java │ ├── GameModeSerializer.java │ ├── HealthSerializer.java │ ├── HungerSerializer.java │ ├── InventorySerializer.java │ ├── Serializer.java │ ├── SnapshotSerializer.java │ └── user │ │ ├── UserSerializerComponent.java │ │ ├── UserSerializerManager.java │ │ └── UserTransitCache.java │ ├── snapshot │ ├── SnapshotManager.java │ └── SnapshotRepository.java │ ├── snapshotoptimization │ ├── SnapshotOptimizationManager.java │ └── SnapshotOptimizationService.java │ └── task │ └── SerializationTaskService.java ├── datasync-common ├── build.gradle └── src │ └── main │ └── java │ └── org │ └── anvilpowered │ └── datasync │ ├── api │ └── DataSyncImpl.java │ └── common │ ├── command │ ├── CommonSyncCommandNode.java │ ├── optimize │ │ └── CommonOptimizeCommandNode.java │ └── snapshot │ │ └── CommonSnapshotCommandNode.java │ ├── key │ └── CommonDataKeyService.java │ ├── member │ ├── CommonMemberManager.java │ ├── CommonMemberRepository.java │ ├── CommonMongoMemberRepository.java │ └── CommonXodusMemberRepository.java │ ├── misc │ └── CommonSyncUtils.java │ ├── model │ ├── member │ │ ├── MongoMember.java │ │ └── XodusMember.java │ └── snapshot │ │ ├── MongoSnapshot.java │ │ └── XodusSnapshot.java │ ├── module │ └── CommonModule.java │ ├── plugin │ └── DataSyncPluginInfo.java │ ├── registry │ ├── CommonConfigurationService.java │ └── CommonRegistry.java │ ├── serializer │ ├── CommonExperienceSerializer.java │ ├── CommonGameModeSerializer.java │ ├── CommonHealthSerializer.java │ ├── CommonHungerSerializer.java │ ├── CommonInventorySerializer.java │ ├── CommonSerializer.java │ ├── CommonSnapshotSerializer.java │ └── user │ │ ├── CommonUserSerializerComponent.java │ │ ├── CommonUserSerializerManager.java │ │ └── CommonUserTransitCache.java │ ├── snapshot │ ├── CommonMongoSnapshotRepository.java │ ├── CommonSnapshotManager.java │ ├── CommonSnapshotRepository.java │ └── CommonXodusSnapshotRepository.java │ ├── snapshotoptimization │ ├── CommonSnapshotOptimizationManager.java │ └── CommonSnapshotOptimizationService.java │ └── task │ └── CommonSerializationTaskService.java ├── datasync-sponge ├── build.gradle └── src │ ├── main │ └── java │ │ └── org │ │ └── anvilpowered │ │ └── datasync │ │ └── sponge │ │ ├── DataSyncSponge.java │ │ ├── command │ │ ├── SpongeSyncCommandNode.java │ │ ├── SpongeSyncLockCommand.java │ │ ├── SpongeSyncReloadCommand.java │ │ ├── SpongeSyncTestCommand.java │ │ ├── SpongeSyncUploadCommand.java │ │ ├── optimize │ │ │ ├── SpongeOptimizeCommandNode.java │ │ │ ├── SpongeOptimizeInfoCommand.java │ │ │ ├── SpongeOptimizeStartCommand.java │ │ │ └── SpongeOptimizeStopCommand.java │ │ └── snapshot │ │ │ ├── SpongeSnapshotCommandNode.java │ │ │ ├── SpongeSnapshotCreateCommand.java │ │ │ ├── SpongeSnapshotDeleteCommand.java │ │ │ ├── SpongeSnapshotInfoCommand.java │ │ │ ├── SpongeSnapshotListCommand.java │ │ │ ├── SpongeSnapshotRestoreCommand.java │ │ │ └── SpongeSnapshotViewCommand.java │ │ ├── event │ │ └── SerializerInitializationEvent.java │ │ ├── keys │ │ └── SpongeDataKeyService.java │ │ ├── listener │ │ └── SpongePlayerListener.java │ │ ├── module │ │ └── SpongeModule.java │ │ ├── registry │ │ └── SpongeConfigurationService.java │ │ ├── serializer │ │ ├── SpongeExperienceSerializer.java │ │ ├── SpongeGameModeSerializer.java │ │ ├── SpongeHealthSerializer.java │ │ ├── SpongeHungerSerializer.java │ │ ├── SpongeInventorySerializer.java │ │ ├── SpongeSnapshotSerializer.java │ │ └── user │ │ │ └── SpongeUserSerializerComponent.java │ │ ├── snapshotoptimization │ │ └── SpongeSnapshotOptimizationService.java │ │ ├── task │ │ └── SpongeSerializationTaskService.java │ │ └── util │ │ └── Utils.java │ └── test │ └── java │ └── rocks │ └── milspecsg │ └── msdatasync │ └── tests │ └── ExampleTests.java ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── icon.png └── settings.gradle /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 # use CircleCI 2.0 2 | jobs: # a collection of steps 3 | build: 4 | environment: 5 | # Configure the JVM and Gradle to avoid OOM errors 6 | _JAVA_OPTIONS: "-Xmx3g" 7 | GRADLE_OPTS: "-Dorg.gradle.daemon=false -Dorg.gradle.workers.max=2" 8 | docker: # run the steps with Docker 9 | - image: circleci/openjdk:8u222-jdk-stretch # ...with this image as the primary container; this is where all `steps` will run 10 | steps: # a collection of executable commands 11 | - checkout # check out source code to working directory 12 | - run: 13 | name: "Pull Submodules" 14 | command: | 15 | git submodule init 16 | git submodule update --remote 17 | # Read about caching dependencies: https://circleci.com/docs/2.0/caching/ 18 | - restore_cache: 19 | key: v1-gradle-wrapper-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }} 20 | - restore_cache: 21 | key: v1-gradle-cache-{{ checksum "build.gradle" }} 22 | - run: 23 | name: Run rocks.milspecsg.msdatasync.tests # See: https://circleci.com/docs/2.0/parallelism-faster-jobs/ 24 | # Use "./gradlew test" instead if tests are not run in parallel 25 | command: | 26 | echo "Running gradle tests" 27 | ./gradlew test 28 | - save_cache: 29 | paths: 30 | - ~/.gradle/wrapper 31 | key: v1-gradle-wrapper-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }} 32 | - save_cache: 33 | paths: 34 | - ~/.gradle/caches 35 | key: v1-gradle-cache-{{ checksum "build.gradle" }} 36 | - run: 37 | name: Save test results 38 | command: | 39 | mkdir -p ~/test-results/junit/ 40 | find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ~/test-results/junit/ \; 41 | when: always 42 | - store_test_results: 43 | path: ~/test-results 44 | - store_artifacts: 45 | path: ~/test-results/junit 46 | - run: 47 | name: Assemble JAR 48 | command: | 49 | # Skip this for other nodes 50 | if [ "$CIRCLE_NODE_INDEX" == 0 ]; then 51 | ./gradlew assemble -PbuildNumber=$CIRCLE_BUILD_NUM 52 | fi 53 | # As the JAR was only assembled in the first build container, build/libs will be empty in all the other build containers. 54 | - store_artifacts: 55 | path: sponge/build/libs 56 | # See https://circleci.com/docs/2.0/deployment-integrations/ for deploy examples 57 | workflows: 58 | version: 2 59 | workflow: 60 | jobs: 61 | - build -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Intellij ### 2 | .idea/ 3 | *.iws 4 | out/ 5 | *.iml 6 | .idea_modules/ 7 | atlassian-ide-plugin.xml 8 | 9 | ### Eclipse ### 10 | .metadata 11 | bin/ 12 | tmp/ 13 | *.tmp 14 | *.bak 15 | *.swp 16 | *~.nib 17 | local.properties 18 | .settings/ 19 | .loadpath 20 | .recommenders 21 | .externalToolBuilders/ 22 | *.launch 23 | .factorypath 24 | .recommenders/ 25 | .apt_generated/ 26 | .project 27 | .classpath 28 | 29 | ### Linux ### 30 | *~ 31 | .fuse_hidden* 32 | .directory 33 | .Trash-* 34 | .nfs* 35 | 36 | ### macOS ### 37 | .DS_Store 38 | .AppleDouble 39 | .LSOverride 40 | Icon 41 | ._* 42 | .DocumentRevisions-V100 43 | .fseventsd 44 | .Spotlight-V100 45 | .TemporaryItems 46 | .Trashes 47 | .VolumeIcon.icns 48 | .com.apple.timemachine.donotpresent 49 | .AppleDB 50 | .AppleDesktop 51 | Network Trash Folder 52 | Temporary Items 53 | .apdisk 54 | 55 | ### NetBeans ### 56 | nbproject/private/ 57 | build/ 58 | nbbuild/ 59 | dist/ 60 | nbdist/ 61 | .nb-gradle/ 62 | 63 | ### Windows ### 64 | # Windows thumbnail cache files 65 | Thumbs.db 66 | ehthumbs.db 67 | ehthumbs_vista.db 68 | *.stackdump 69 | [Dd]esktop.ini 70 | $RECYCLE.BIN/ 71 | *.lnk 72 | 73 | ### Gradle ### 74 | .gradle 75 | # build/ already defined under netbeans 76 | out/ 77 | gradle-app.setting 78 | !gradle-wrapper.jar 79 | .gradletasknamecache -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MSDataSync 2 | 3 | 4 | 5 | #### Quick Links 6 | [Join our development discord](https://discord.gg/8RUzuwu) 7 | 8 | [Ore page](https://ore.spongepowered.org/Cableguy20/DataSync) 9 | 10 | [Installation Guide](https://github.com/AnvilPowered/DataSync/wiki/Installation) 11 | 12 | Have you ever had problems with players losing items? 13 | 14 | Do you run a multi server network where every server needs to share inventories and other player data? 15 | 16 | ### Look no further 17 | 18 | _MSDataSync_ is an advanced player data backup plugin that lets you store, manage, edit and rollback player data! 19 | 20 | (Compatible with forge and vanilla) 21 | 22 | # Features 23 | 24 | ## Backup player data 25 | 26 | - _MSDataSync_ creates automated snapshots with an interval specified in your config 27 | 28 | - As of this writing, a snapshot will include (by default) 29 | - Inventory 30 | - Health 31 | - Hunger 32 | - Experience 33 | - Game mode 34 | 35 | - You can manually create a snapshot for a player with `/sync snapshot create ` 36 | 37 | - Or create a snapshot for everyone on the server with `/sync up` 38 | 39 | - By default, _MSDataSync_ will load the latest snapshot when a player leaves and create a snapshot when a player joins. 40 | This can be disabled in the config. 41 | 42 | ## Restore player data 43 | 44 | - The old way 45 | 46 | ``` 47 | Player: HeLp I LOst mY sTuFf!!!!! OWnER!!!!!! 48 | 49 | Owner: screenshots or it didnt happen, sorry bud 50 | 51 | Player: this server is dumb, im never coming back! 52 | 53 | Player has left the game 54 | ``` 55 | 56 | - With _MSDataSync_ 57 | 58 | ``` 59 | Player: HeLp I LOst mY sTuFf!!!!! OWnER!!!!!! 60 | 61 | Owner: when did this happen? 62 | 63 | Player: just now, can you help plz 64 | 65 | [Owner runs /sync snapshot restore Player] 66 | 67 | [Player gets restored to the latest snapshot] 68 | 69 | Player: thanks! 70 | ``` 71 | 72 | - Browse through snapshots by date and restore, edit or delete it (separate permissions for viewing and editing) 73 | 74 | ## Optimize backups 75 | 76 | _MSDataSync_ automatically deletes old snapshots for optimal storage efficiency. The default optimization strategy will: 77 | - Keep all snapshots within the last hour 78 | - Keep up to one snapshot per hour for the last 24 hours (not including the first hour) 79 | - Keep up to one snapshot per day for the last 7 days (not including the first day) 80 | - Delete all snapshots older than 7 days 81 | 82 | ## Comes with child lock 83 | 84 | Don't you hate running dangerous commands by accident! Me too. 85 | We included a child lock so you would be slightly less likely to accidentally break stuff! 86 | - `/sync lock []` 87 | 88 | ## Reload command actually works 89 | 90 | Changed any settings? Just run `/sync reload` and the plugin will reload 91 | - Database connection gets reopened (with updated db settings from config) 92 | - Sync task is restarted (with updated settings from config) 93 | -------------------------------------------------------------------------------- /build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | java 3 | } 4 | 5 | allprojects { 6 | group = "org.anvilpowered" 7 | version = "0.8.1-SNAPSHOT" 8 | } 9 | 10 | subprojects { 11 | apply(plugin = "java") 12 | java { 13 | sourceCompatibility = JavaVersion.VERSION_1_8 14 | targetCompatibility = JavaVersion.VERSION_1_8 15 | } 16 | repositories { 17 | mavenCentral() 18 | maven("https://oss.sonatype.org/content/repositories/snapshots") 19 | maven("https://repo.spongepowered.org/maven") 20 | maven("https://jetbrains.bintray.com/xodus") 21 | } 22 | dependencies { 23 | testImplementation("org.junit.jupiter:junit-jupiter-api:5.4.0") 24 | testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.4.0") 25 | compileOnly("org.anvilpowered:anvil-api:0.3") { 26 | exclude(group = "org.jetbrains.xodus") 27 | } 28 | implementation("org.jetbrains.xodus:xodus-openAPI:1.3.232") 29 | } 30 | // test { 31 | // useJUnitPlatform() 32 | // } 33 | // if (project.hasProperty("buildNumber") && version.toString().contains("-SNAPSHOT")) { 34 | // version = version.toString().replace("-SNAPSHOT", "-RC${buildNumber}") 35 | // } 36 | } 37 | -------------------------------------------------------------------------------- /datasync-api/src/main/java/org/anvilpowered/datasync/api/DataSync.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.api; 20 | 21 | import com.google.common.base.Preconditions; 22 | import com.google.inject.Injector; 23 | import com.google.inject.Module; 24 | import org.anvilpowered.anvil.api.Environment; 25 | import org.anvilpowered.anvil.api.registry.Registry; 26 | import org.anvilpowered.anvil.base.plugin.BasePlugin; 27 | 28 | public class DataSync extends BasePlugin { 29 | 30 | protected static Environment environment; 31 | private static final String NOT_LOADED = "DataSync has not been loaded yet!"; 32 | 33 | DataSync(String name, Injector injector, Module module) { 34 | super(name, injector, module); 35 | } 36 | 37 | public static Environment getEnvironment() { 38 | return Preconditions.checkNotNull(environment, NOT_LOADED); 39 | } 40 | 41 | public static Registry getRegistry() { 42 | return getEnvironment().getInjector().getInstance(Registry.class); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /datasync-api/src/main/java/org/anvilpowered/datasync/api/key/DataKeyService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.api.key; 20 | 21 | import java.util.Optional; 22 | 23 | public interface DataKeyService { 24 | 25 | void addMapping(K key, String name); 26 | 27 | void removeMapping(K key); 28 | 29 | Optional getName(K key); 30 | } 31 | -------------------------------------------------------------------------------- /datasync-api/src/main/java/org/anvilpowered/datasync/api/member/MemberManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.api.member; 20 | 21 | import org.anvilpowered.anvil.api.datastore.Manager; 22 | import org.anvilpowered.datasync.api.model.snapshot.Snapshot; 23 | import org.checkerframework.checker.nullness.qual.Nullable; 24 | 25 | import java.util.UUID; 26 | import java.util.concurrent.CompletableFuture; 27 | 28 | public interface MemberManager 29 | extends Manager> { 30 | 31 | @Override 32 | default String getDefaultIdentifierSingularUpper() { 33 | return "Member"; 34 | } 35 | 36 | @Override 37 | default String getDefaultIdentifierPluralUpper() { 38 | return "Members"; 39 | } 40 | 41 | @Override 42 | default String getDefaultIdentifierSingularLower() { 43 | return "member"; 44 | } 45 | 46 | @Override 47 | default String getDefaultIdentifierPluralLower() { 48 | return "members"; 49 | } 50 | 51 | CompletableFuture deleteSnapshot(UUID userUUID, @Nullable String snapshot); 52 | 53 | TString info(UUID userUUID, Snapshot snapshot); 54 | 55 | CompletableFuture info(UUID userUUID, @Nullable String snapshot); 56 | 57 | CompletableFuture> list(UUID userUUID); 58 | } 59 | -------------------------------------------------------------------------------- /datasync-api/src/main/java/org/anvilpowered/datasync/api/member/MemberRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.api.member; 20 | 21 | import org.anvilpowered.anvil.api.datastore.Repository; 22 | import org.anvilpowered.datasync.api.model.member.Member; 23 | import org.anvilpowered.datasync.api.model.snapshot.Snapshot; 24 | import org.checkerframework.checker.nullness.qual.Nullable; 25 | 26 | import java.time.Instant; 27 | import java.util.List; 28 | import java.util.Optional; 29 | import java.util.UUID; 30 | import java.util.concurrent.CompletableFuture; 31 | 32 | public interface MemberRepository< 33 | TKey, 34 | TDataStore> 35 | extends Repository, TDataStore> { 36 | 37 | /** 38 | * Gets the corresponding {@code Member} from the database. 39 | * If not present, creates a new one and saves it to the database 40 | * 41 | * @param userUUID Mojang issued {@code uuid} of {@code User} to getRequiredRankIndex corresponding {@code Member} 42 | * @return a ready-to-use {@code Member} that corresponds with the given {@code uuid} 43 | */ 44 | CompletableFuture>> getOneOrGenerateForUser(UUID userUUID); 45 | 46 | CompletableFuture>> getOneForUser(UUID userUUID); 47 | 48 | CompletableFuture> getIdForUser(UUID userUUID); 49 | 50 | CompletableFuture> getUUID(TKey id); 51 | 52 | CompletableFuture> getSnapshotIds(TKey id); 53 | 54 | CompletableFuture> getSnapshotIdsForUser(UUID userUUID); 55 | 56 | CompletableFuture> getSnapshotCreationTimes(TKey id); 57 | 58 | CompletableFuture> getSnapshotCreationTimesForUser(UUID userUUID); 59 | 60 | CompletableFuture deleteSnapshot(TKey id, TKey snapshotId); 61 | 62 | CompletableFuture deleteSnapshot(TKey id, Instant createdUtc); 63 | 64 | CompletableFuture deleteSnapshotForUser(UUID userUUID, TKey snapshotId); 65 | 66 | CompletableFuture deleteSnapshotForUser(UUID userUUID, Instant createdUtc); 67 | 68 | CompletableFuture addSnapshot(TKey id, TKey snapshotId); 69 | 70 | CompletableFuture addSnapshotForUser(UUID userUUID, TKey snapshotId); 71 | 72 | CompletableFuture>> getSnapshot(TKey id, Instant createdUtc); 73 | 74 | CompletableFuture>> getSnapshotForUser(UUID userUUID, Instant createdUtc); 75 | 76 | CompletableFuture>> getSnapshot(TKey id, @Nullable String snapshot); 77 | 78 | CompletableFuture>> getSnapshotForUser(UUID userUUID, 79 | @Nullable String snapshot); 80 | 81 | CompletableFuture> getClosestSnapshots(TKey id, Instant createdUtc); 82 | 83 | CompletableFuture> getClosestSnapshotsForUser(UUID userUUID, Instant createdUtc); 84 | 85 | CompletableFuture>> getLatestSnapshot(TKey id); 86 | 87 | CompletableFuture>> getLatestSnapshotForUser(UUID userUUID); 88 | 89 | CompletableFuture>> getPrevious(TKey id, TKey snapshotId); 90 | 91 | CompletableFuture>> getPreviousForUser(UUID userUUID, TKey snapshotId); 92 | 93 | CompletableFuture>> getPreviousForUser(UUID userUUID, Instant createdUtc); 94 | 95 | CompletableFuture>> getNext(TKey id, TKey snapshotId); 96 | 97 | CompletableFuture>> getNextForUser(UUID userUUID, TKey snapshotId); 98 | 99 | CompletableFuture>> getNextForUser(UUID userUUID, Instant createdUtc); 100 | 101 | CompletableFuture setSkipDeserialization(TKey id, boolean skipDeserialization); 102 | } 103 | -------------------------------------------------------------------------------- /datasync-api/src/main/java/org/anvilpowered/datasync/api/member/MongoMemberRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.api.member; 20 | 21 | import dev.morphia.Datastore; 22 | import dev.morphia.query.Query; 23 | import org.anvilpowered.anvil.api.datastore.MongoRepository; 24 | import org.anvilpowered.datasync.api.model.member.Member; 25 | import org.anvilpowered.datasync.api.model.snapshot.Snapshot; 26 | import org.bson.types.ObjectId; 27 | 28 | import java.time.Instant; 29 | import java.util.List; 30 | import java.util.Optional; 31 | import java.util.UUID; 32 | import java.util.concurrent.CompletableFuture; 33 | 34 | public interface MongoMemberRepository 35 | extends MemberRepository, 36 | MongoRepository> { 37 | 38 | CompletableFuture> getSnapshotIds(Query> query); 39 | 40 | CompletableFuture> getSnapshotCreationTimes(Query> query); 41 | 42 | CompletableFuture deleteSnapshot(Query> query, ObjectId snapshotId); 43 | 44 | CompletableFuture deleteSnapshot(Query> query, Instant createdUtc); 45 | 46 | CompletableFuture addSnapshot(Query> query, ObjectId snapshotId); 47 | 48 | CompletableFuture>> getSnapshot(Query> query, Instant createdUtc); 49 | 50 | CompletableFuture> getClosestSnapshots(Query> query, Instant createdUtc); 51 | 52 | Query> asQuery(UUID userUUID); 53 | } 54 | -------------------------------------------------------------------------------- /datasync-api/src/main/java/org/anvilpowered/datasync/api/member/XodusMemberRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.api.member; 20 | 21 | import jetbrains.exodus.entitystore.Entity; 22 | import jetbrains.exodus.entitystore.EntityId; 23 | import jetbrains.exodus.entitystore.PersistentEntityStore; 24 | import jetbrains.exodus.entitystore.StoreTransaction; 25 | import org.anvilpowered.anvil.api.datastore.XodusRepository; 26 | import org.anvilpowered.datasync.api.model.member.Member; 27 | import org.anvilpowered.datasync.api.model.snapshot.Snapshot; 28 | 29 | import java.time.Instant; 30 | import java.util.List; 31 | import java.util.Optional; 32 | import java.util.UUID; 33 | import java.util.concurrent.CompletableFuture; 34 | import java.util.function.Function; 35 | 36 | public interface XodusMemberRepository 37 | extends MemberRepository, 38 | XodusRepository> { 39 | 40 | CompletableFuture> getSnapshotIds(Function> query); 41 | 42 | CompletableFuture> getSnapshotCreationTimes(Function> query); 43 | 44 | CompletableFuture deleteSnapshot(Function> query, EntityId snapshotId); 45 | 46 | CompletableFuture deleteSnapshot(Function> query, Instant createdUtc); 47 | 48 | CompletableFuture addSnapshot(Function> query, EntityId snapshotId); 49 | 50 | CompletableFuture>> getSnapshot(Function> query, Instant createdUtc); 51 | 52 | CompletableFuture> getClosestSnapshots(Function> query, Instant createdUtc); 53 | 54 | Function> asQuery(UUID userUUID); 55 | } 56 | -------------------------------------------------------------------------------- /datasync-api/src/main/java/org/anvilpowered/datasync/api/misc/SyncUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.api.misc; 20 | 21 | import java.util.List; 22 | import java.util.Optional; 23 | 24 | public interface SyncUtils { 25 | 26 | Optional> decodeOptimizationStrategy(List list); 27 | } 28 | -------------------------------------------------------------------------------- /datasync-api/src/main/java/org/anvilpowered/datasync/api/model/member/Member.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.api.model.member; 20 | 21 | import org.anvilpowered.anvil.api.model.ObjectWithId; 22 | 23 | import java.util.List; 24 | import java.util.UUID; 25 | 26 | public interface Member extends ObjectWithId { 27 | 28 | UUID getUserUUID(); 29 | void setUserUUID(UUID userUUID); 30 | 31 | List getSnapshotIds(); 32 | void setSnapshotIds(List snapshotIds); 33 | 34 | boolean isSkipDeserialization(); 35 | void setSkipDeserialization(boolean skipDeserialization); 36 | } 37 | -------------------------------------------------------------------------------- /datasync-api/src/main/java/org/anvilpowered/datasync/api/model/snapshot/Snapshot.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.api.model.snapshot; 20 | 21 | import org.anvilpowered.anvil.api.model.ObjectWithId; 22 | 23 | import java.util.List; 24 | import java.util.Map; 25 | 26 | public interface Snapshot extends ObjectWithId { 27 | 28 | String getName(); 29 | void setName(String name); 30 | 31 | String getServer(); 32 | void setServer(String server); 33 | 34 | List getModulesUsed(); 35 | void setModulesUsed(List modulesUsed); 36 | 37 | List getModulesFailed(); 38 | void setModulesFailed(List modulesFailed); 39 | 40 | Map getKeys(); 41 | void setKeys(Map keys); 42 | 43 | byte[] getInventory(); 44 | void setInventory(byte[] inventory); 45 | } 46 | -------------------------------------------------------------------------------- /datasync-api/src/main/java/org/anvilpowered/datasync/api/serializer/ExperienceSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.api.serializer; 20 | 21 | public interface ExperienceSerializer 22 | extends Serializer { 23 | } 24 | -------------------------------------------------------------------------------- /datasync-api/src/main/java/org/anvilpowered/datasync/api/serializer/GameModeSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.api.serializer; 20 | 21 | public interface GameModeSerializer 22 | extends Serializer { 23 | } 24 | -------------------------------------------------------------------------------- /datasync-api/src/main/java/org/anvilpowered/datasync/api/serializer/HealthSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.api.serializer; 20 | 21 | public interface HealthSerializer 22 | extends Serializer { 23 | } 24 | -------------------------------------------------------------------------------- /datasync-api/src/main/java/org/anvilpowered/datasync/api/serializer/HungerSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.api.serializer; 20 | 21 | public interface HungerSerializer 22 | extends Serializer { 23 | } 24 | -------------------------------------------------------------------------------- /datasync-api/src/main/java/org/anvilpowered/datasync/api/serializer/InventorySerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.api.serializer; 20 | 21 | import org.anvilpowered.datasync.api.model.snapshot.Snapshot; 22 | 23 | public interface InventorySerializer< 24 | TUser, 25 | TInventory, 26 | TItemStackSnapshot> 27 | extends Serializer { 28 | 29 | /** 30 | * Moves data from {@code inventory} into {@code member} 31 | * 32 | * @param snapshot {@link Snapshot} to add data to 33 | * @param inventory Player to get data from 34 | * @param maxSlots Maximum number of slots that will get serialized 35 | * @return Whether serialization was successful 36 | */ 37 | boolean serializeInventory(Snapshot snapshot, TInventory inventory, int maxSlots); 38 | 39 | /** 40 | * Moves data from {@code inventory} into {@code member} 41 | * 42 | * @param snapshot {@link Snapshot} to add data to 43 | * @param inventory Player to get data from 44 | * @return Whether serialization was successful 45 | */ 46 | boolean serializeInventory(Snapshot snapshot, TInventory inventory); 47 | 48 | /** 49 | * Moves data from {@code member} into {@code inventory} 50 | * 51 | * @param snapshot {@link Snapshot} to get data from 52 | * @param inventory Player to add data to 53 | * @param fallbackItemStackSnapshot Item stack to put into unused slots. To be made uneditable 54 | * @return Whether deserialization was successful 55 | */ 56 | boolean deserializeInventory(Snapshot snapshot, TInventory inventory, TItemStackSnapshot fallbackItemStackSnapshot); 57 | 58 | /** 59 | * Moves data from {@code member} into {@code inventory} 60 | * 61 | * @param snapshot {@link Snapshot} to get data from 62 | * @param inventory Player to add data to 63 | * @return Whether deserialization was successful 64 | */ 65 | boolean deserializeInventory(Snapshot snapshot, TInventory inventory); 66 | 67 | TItemStackSnapshot getDefaultFallbackItemStackSnapshot(); 68 | 69 | TItemStackSnapshot getExitWithoutSavingItemStackSnapshot(); 70 | } 71 | -------------------------------------------------------------------------------- /datasync-api/src/main/java/org/anvilpowered/datasync/api/serializer/Serializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.api.serializer; 20 | 21 | import org.anvilpowered.datasync.api.model.snapshot.Snapshot; 22 | 23 | public interface Serializer { 24 | 25 | /** 26 | * @return Name of {@link Serializer}. 27 | * Should follow format "plugin:name" 28 | * For example "datasync:inventory" 29 | */ 30 | String getName(); 31 | 32 | /** 33 | * Moves data from {@code player} into {@code member} 34 | * 35 | * @param snapshot {@link Snapshot} to add data to 36 | * @param user User to get data from 37 | * @return Whether serialization was successful 38 | */ 39 | boolean serialize(Snapshot snapshot, TUser user); 40 | 41 | /** 42 | * Moves data from {@code member} into {@code player} 43 | * 44 | * @param snapshot {@link Snapshot} to get data from 45 | * @param user User to add data to 46 | * @return Whether deserialization was successful 47 | */ 48 | boolean deserialize(Snapshot snapshot, TUser user); 49 | } 50 | -------------------------------------------------------------------------------- /datasync-api/src/main/java/org/anvilpowered/datasync/api/serializer/SnapshotSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.api.serializer; 20 | 21 | public interface SnapshotSerializer 22 | extends Serializer { 23 | 24 | void registerSerializer(Serializer serializer); 25 | 26 | boolean isSerializerEnabled(String name); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /datasync-api/src/main/java/org/anvilpowered/datasync/api/serializer/user/UserSerializerComponent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.api.serializer.user; 20 | 21 | import org.anvilpowered.anvil.api.datastore.Component; 22 | import org.anvilpowered.datasync.api.model.snapshot.Snapshot; 23 | import org.anvilpowered.datasync.api.serializer.Serializer; 24 | 25 | import java.util.Optional; 26 | import java.util.concurrent.CompletableFuture; 27 | 28 | public interface UserSerializerComponent< 29 | TKey, 30 | TUser, 31 | TDataStore> 32 | extends Component, 33 | Serializer { 34 | 35 | CompletableFuture>> serialize(TUser user, String name); 36 | 37 | CompletableFuture>> deserialize(TUser user, CompletableFuture waitFuture); 38 | } 39 | -------------------------------------------------------------------------------- /datasync-api/src/main/java/org/anvilpowered/datasync/api/serializer/user/UserSerializerManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.api.serializer.user; 20 | 21 | import org.anvilpowered.anvil.api.datastore.Manager; 22 | import org.checkerframework.checker.nullness.qual.Nullable; 23 | 24 | import java.util.Collection; 25 | import java.util.UUID; 26 | import java.util.concurrent.CompletableFuture; 27 | 28 | public interface UserSerializerManager< 29 | TUser, 30 | TString> 31 | extends Manager> { 32 | 33 | @Override 34 | default String getDefaultIdentifierSingularUpper() { 35 | return "User serializer"; 36 | } 37 | 38 | @Override 39 | default String getDefaultIdentifierPluralUpper() { 40 | return "User serializers"; 41 | } 42 | 43 | @Override 44 | default String getDefaultIdentifierSingularLower() { 45 | return "user serializer"; 46 | } 47 | 48 | @Override 49 | default String getDefaultIdentifierPluralLower() { 50 | return "user serializers"; 51 | } 52 | 53 | CompletableFuture serialize(Collection users); 54 | 55 | CompletableFuture serialize(TUser user, String name); 56 | 57 | CompletableFuture serialize(TUser user); 58 | 59 | CompletableFuture serializeSafe(TUser user, String name); 60 | 61 | CompletableFuture deserialize(TUser user, String event, CompletableFuture waitFuture); 62 | 63 | CompletableFuture deserialize(TUser user, String event); 64 | 65 | CompletableFuture deserialize(TUser user); 66 | 67 | CompletableFuture deserializeJoin(TUser user); 68 | 69 | CompletableFuture restore(UUID userUUID, @Nullable String snapshot); 70 | } 71 | -------------------------------------------------------------------------------- /datasync-api/src/main/java/org/anvilpowered/datasync/api/serializer/user/UserTransitCache.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.api.serializer.user; 20 | 21 | import java.util.UUID; 22 | import java.util.concurrent.CompletableFuture; 23 | 24 | /** 25 | * All methods are thread-safe 26 | */ 27 | public interface UserTransitCache { 28 | 29 | /** 30 | * Declares that the user with the provided {@link UUID} has started the joining process. 31 | * 32 | * @param userUUID The {@link UUID} of the joining user 33 | * @param waitFuture A future that returns {@code true} when the player is ready to be deserialized, otherwise {@code false} 34 | */ 35 | void joinStart(UUID userUUID, CompletableFuture waitFuture); 36 | 37 | /** 38 | * Declares that the user with the provided {@link UUID} has ended the joining process. 39 | * 40 | * @param userUUID The {@link UUID} of the joining user 41 | */ 42 | void joinEnd(UUID userUUID); 43 | 44 | /** 45 | * Check whether the user with the provided {@link UUID} is in the process of joining. 46 | * 47 | * @param userUUID The {@link UUID} of the user to check 48 | * @return Whether the user with the provided {@link UUID} is in the process of joining 49 | */ 50 | boolean isJoining(UUID userUUID); 51 | } 52 | -------------------------------------------------------------------------------- /datasync-api/src/main/java/org/anvilpowered/datasync/api/snapshot/SnapshotManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.api.snapshot; 20 | 21 | import org.anvilpowered.anvil.api.datastore.Manager; 22 | 23 | public interface SnapshotManager extends Manager> { 24 | 25 | @Override 26 | default String getDefaultIdentifierSingularUpper() { 27 | return "Snapshot"; 28 | } 29 | 30 | @Override 31 | default String getDefaultIdentifierPluralUpper() { 32 | return "Snapshots"; 33 | } 34 | 35 | @Override 36 | default String getDefaultIdentifierSingularLower() { 37 | return "snapshot"; 38 | } 39 | 40 | @Override 41 | default String getDefaultIdentifierPluralLower() { 42 | return "snapshots"; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /datasync-api/src/main/java/org/anvilpowered/datasync/api/snapshot/SnapshotRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.api.snapshot; 20 | 21 | import org.anvilpowered.anvil.api.datastore.Repository; 22 | import org.anvilpowered.datasync.api.model.snapshot.Snapshot; 23 | 24 | import java.util.Optional; 25 | import java.util.concurrent.CompletableFuture; 26 | 27 | public interface SnapshotRepository< 28 | TKey, 29 | TDataKey, 30 | TDataStore> 31 | extends Repository, TDataStore> { 32 | 33 | boolean setSnapshotValue(Snapshot snapshot, TDataKey key, Optional optionalValue); 34 | 35 | Optional getSnapshotValue(Snapshot snapshot, TDataKey key); 36 | 37 | CompletableFuture setInventory(TKey id, byte[] inventory); 38 | 39 | CompletableFuture parseAndSetInventory(Object id, byte[] inventory); 40 | } 41 | -------------------------------------------------------------------------------- /datasync-api/src/main/java/org/anvilpowered/datasync/api/snapshotoptimization/SnapshotOptimizationManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.api.snapshotoptimization; 20 | 21 | import org.anvilpowered.anvil.api.datastore.Manager; 22 | 23 | public interface SnapshotOptimizationManager< 24 | TUser, 25 | TString, 26 | TCommandSource> 27 | extends Manager> { 28 | 29 | @Override 30 | default String getDefaultIdentifierSingularUpper() { 31 | return "Snapshot optimization"; 32 | } 33 | 34 | @Override 35 | default String getDefaultIdentifierPluralUpper() { 36 | return "Snapshot optimizations"; 37 | } 38 | 39 | @Override 40 | default String getDefaultIdentifierSingularLower() { 41 | return "snapshot optimization"; 42 | } 43 | 44 | @Override 45 | default String getDefaultIdentifierPluralLower() { 46 | return "snapshot optimizations"; 47 | } 48 | 49 | TString info(); 50 | 51 | TString stop(); 52 | } 53 | -------------------------------------------------------------------------------- /datasync-api/src/main/java/org/anvilpowered/datasync/api/snapshotoptimization/SnapshotOptimizationService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.api.snapshotoptimization; 20 | 21 | import org.anvilpowered.anvil.api.datastore.Component; 22 | 23 | import java.util.Collection; 24 | import java.util.UUID; 25 | 26 | public interface SnapshotOptimizationService< 27 | TKey, 28 | TUser, 29 | TCommandSource, 30 | TDataStore> 31 | extends Component { 32 | 33 | int getTotalMembers(); 34 | 35 | int getMembersCompleted(); 36 | 37 | int getSnapshotsDeleted(); 38 | 39 | int getSnapshotsUploaded(); 40 | 41 | boolean isOptimizationTaskRunning(); 42 | 43 | boolean stopOptimizationTask(); 44 | 45 | void addLockedPlayer(final UUID uuid); 46 | 47 | void removeLockedPlayer(final UUID uuid); 48 | 49 | boolean optimize(final Collection users, final TCommandSource source, final String name); 50 | 51 | boolean optimize(final TCommandSource source); 52 | } 53 | -------------------------------------------------------------------------------- /datasync-api/src/main/java/org/anvilpowered/datasync/api/task/SerializationTaskService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.api.task; 20 | 21 | public interface SerializationTaskService { 22 | 23 | /** 24 | * Starts serialization task 25 | */ 26 | void startSerializationTask(); 27 | 28 | /** 29 | * Stops serialization task 30 | */ 31 | void stopSerializationTask(); 32 | 33 | /** 34 | * @return Serialization task 35 | */ 36 | Runnable getSerializationTask(); 37 | } 38 | -------------------------------------------------------------------------------- /datasync-common/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(':datasync-api') 3 | implementation configurate_hocon 4 | } 5 | -------------------------------------------------------------------------------- /datasync-common/src/main/java/org/anvilpowered/datasync/api/DataSyncImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.api; 20 | 21 | import com.google.common.reflect.TypeToken; 22 | import com.google.inject.Injector; 23 | import com.google.inject.Module; 24 | import org.anvilpowered.anvil.api.Environment; 25 | import org.anvilpowered.datasync.api.key.DataKeyService; 26 | import org.anvilpowered.datasync.api.task.SerializationTaskService; 27 | import org.anvilpowered.datasync.common.plugin.DataSyncPluginInfo; 28 | 29 | @SuppressWarnings("UnstableApiUsage") 30 | public class DataSyncImpl extends DataSync { 31 | 32 | protected DataSyncImpl(Injector injector, Module module) { 33 | super(DataSyncPluginInfo.id, injector, module); 34 | } 35 | 36 | protected void applyToBuilder(Environment.Builder builder) { 37 | builder.addEarlyServices( 38 | new TypeToken>(getClass()) { 39 | }) 40 | .addEarlyServices(SerializationTaskService.class) 41 | .withRootCommand(); 42 | } 43 | 44 | @Override 45 | protected void whenReady(Environment environment) { 46 | super.whenReady(environment); 47 | DataSync.environment = environment; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /datasync-common/src/main/java/org/anvilpowered/datasync/common/command/CommonSyncCommandNode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.common.command; 20 | 21 | import com.google.inject.Inject; 22 | import org.anvilpowered.anvil.api.Environment; 23 | import org.anvilpowered.anvil.api.command.CommandNode; 24 | import org.anvilpowered.anvil.api.command.CommandService; 25 | import org.anvilpowered.anvil.api.registry.Registry; 26 | import org.anvilpowered.datasync.common.plugin.DataSyncPluginInfo; 27 | 28 | import java.util.Arrays; 29 | import java.util.Collections; 30 | import java.util.HashMap; 31 | import java.util.List; 32 | import java.util.Map; 33 | import java.util.Objects; 34 | import java.util.function.Function; 35 | import java.util.function.Predicate; 36 | 37 | public abstract class CommonSyncCommandNode 38 | implements CommandNode { 39 | 40 | protected static final List LOCK_ALIAS = Arrays.asList("lock", "l"); 41 | protected static final List RELOAD_ALIAS = Collections.singletonList("reload"); 42 | protected static final List TEST_ALIAS = Collections.singletonList("test"); 43 | protected static final List UPLOAD_ALIAS = Arrays.asList("upload", "up"); 44 | protected static final List HELP_ALIAS = Collections.singletonList("help"); 45 | protected static final List VERSION_ALIAS = Collections.singletonList("version"); 46 | 47 | protected static final String LOCK_DESCRIPTION = "Lock / Unlock sensitive commands."; 48 | protected static final String RELOAD_DESCRIPTION = "Reloads DataSync."; 49 | protected static final String TEST_DESCRIPTION = "Uploads and then downloads a snapshot."; 50 | protected static final String UPLOAD_DESCRIPTION = "Uploads all players on server."; 51 | protected static final String HELP_DESCRIPTION = "Shows this help page."; 52 | protected static final String VERSION_DESCRIPTION = "Shows plugin version."; 53 | protected static final String ROOT_DESCRIPTION 54 | = String.format("%s root command", DataSyncPluginInfo.name); 55 | 56 | protected static final String RELOAD_USAGE = "[-a|--all|-r|--regex] [plugin]"; 57 | 58 | protected static final String HELP_COMMAND = "/datasync help"; 59 | 60 | public static String[] SYNC_PATH = new String[]{"sync"}; 61 | 62 | private boolean alreadyLoaded; 63 | protected Map, Function> descriptions; 64 | protected Map, Predicate> permissions; 65 | protected Map, Function> usages; 66 | 67 | @Inject 68 | protected CommandService commandService; 69 | 70 | @Inject 71 | protected Environment environment; 72 | 73 | protected Registry registry; 74 | 75 | protected CommonSyncCommandNode(Registry registry) { 76 | this.registry = registry; 77 | registry.whenLoaded(() -> { 78 | if (alreadyLoaded) return; 79 | loadCommands(); 80 | alreadyLoaded = true; 81 | }).register(); 82 | alreadyLoaded = false; 83 | descriptions = new HashMap<>(); 84 | permissions = new HashMap<>(); 85 | usages = new HashMap<>(); 86 | descriptions.put(LOCK_ALIAS, c -> LOCK_DESCRIPTION); 87 | descriptions.put(RELOAD_ALIAS, c -> RELOAD_DESCRIPTION); 88 | descriptions.put(TEST_ALIAS, c -> TEST_DESCRIPTION); 89 | descriptions.put(UPLOAD_ALIAS, c -> UPLOAD_DESCRIPTION); 90 | descriptions.put(HELP_ALIAS, c -> HELP_DESCRIPTION); 91 | descriptions.put(VERSION_ALIAS, c -> VERSION_DESCRIPTION); 92 | usages.put(RELOAD_ALIAS, c -> RELOAD_USAGE); 93 | } 94 | 95 | protected abstract void loadCommands(); 96 | 97 | private static final String ERROR_MESSAGE = "Sync command has not been loaded yet"; 98 | 99 | @Override 100 | public Map, Function> getDescriptions() { 101 | return Objects.requireNonNull(descriptions, ERROR_MESSAGE); 102 | } 103 | 104 | @Override 105 | public Map, Predicate> getPermissions() { 106 | return Objects.requireNonNull(permissions, ERROR_MESSAGE); 107 | } 108 | 109 | @Override 110 | public Map, Function> getUsages() { 111 | return Objects.requireNonNull(usages, ERROR_MESSAGE); 112 | } 113 | 114 | @Override 115 | public String getName() { 116 | return DataSyncPluginInfo.id; 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /datasync-common/src/main/java/org/anvilpowered/datasync/common/command/optimize/CommonOptimizeCommandNode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.common.command.optimize; 20 | 21 | import com.google.inject.Inject; 22 | import org.anvilpowered.anvil.api.command.CommandNode; 23 | import org.anvilpowered.anvil.api.command.CommandService; 24 | import org.anvilpowered.anvil.api.registry.Registry; 25 | import org.anvilpowered.datasync.common.command.CommonSyncCommandNode; 26 | import org.anvilpowered.datasync.common.plugin.DataSyncPluginInfo; 27 | 28 | import java.util.Arrays; 29 | import java.util.Collections; 30 | import java.util.HashMap; 31 | import java.util.List; 32 | import java.util.Map; 33 | import java.util.Objects; 34 | import java.util.function.Function; 35 | import java.util.function.Predicate; 36 | 37 | public abstract class CommonOptimizeCommandNode 38 | implements CommandNode { 39 | 40 | protected static final List START_ALIAS = Arrays.asList("start", "s"); 41 | protected static final List INFO_ALIAS = Arrays.asList("info", "i"); 42 | protected static final List STOP_ALIAS = Collections.singletonList("stop"); 43 | protected static final List HELP_ALIAS = Collections.singletonList("help"); 44 | 45 | protected static final String START_DESCRIPTION 46 | = "Starts manual optimization, deletes old snapshots."; 47 | protected static final String INFO_DESCRIPTION 48 | = "Gets info on current manual optimization."; 49 | protected static final String STOP_DESCRIPTION 50 | = "Stops current manual optimization."; 51 | protected static final String HELP_DESCRIPTION 52 | = "Shows this help page."; 53 | protected static final String ROOT_DESCRIPTION 54 | = "Optimize base command. (To delete old snapshots)"; 55 | 56 | protected static final String START_USAGE = "all|user []"; 57 | 58 | protected static final String HELP_COMMAND = "/sync optimize help"; 59 | 60 | private boolean alreadyLoaded; 61 | protected Map, Function> descriptions; 62 | protected Map, Predicate> permissions; 63 | protected Map, Function> usages; 64 | 65 | @Inject 66 | protected CommandService commandService; 67 | 68 | protected Registry registry; 69 | 70 | protected CommonOptimizeCommandNode(Registry registry) { 71 | this.registry = registry; 72 | registry.whenLoaded(() -> { 73 | if (alreadyLoaded) return; 74 | loadCommands(); 75 | alreadyLoaded = true; 76 | }).register(); 77 | alreadyLoaded = false; 78 | descriptions = new HashMap<>(); 79 | permissions = new HashMap<>(); 80 | usages = new HashMap<>(); 81 | descriptions.put(START_ALIAS, c -> START_DESCRIPTION); 82 | descriptions.put(INFO_ALIAS, c -> INFO_DESCRIPTION); 83 | descriptions.put(STOP_ALIAS, c -> STOP_DESCRIPTION); 84 | descriptions.put(HELP_ALIAS, c -> HELP_DESCRIPTION); 85 | usages.put(START_ALIAS, c -> START_USAGE); 86 | } 87 | 88 | protected abstract void loadCommands(); 89 | 90 | private static final String ERROR_MESSAGE = "Sync command has not been loaded yet"; 91 | 92 | @Override 93 | public Map, Function> getDescriptions() { 94 | return Objects.requireNonNull(descriptions, ERROR_MESSAGE); 95 | } 96 | 97 | @Override 98 | public Map, Predicate> getPermissions() { 99 | return Objects.requireNonNull(permissions, ERROR_MESSAGE); 100 | } 101 | 102 | @Override 103 | public Map, Function> getUsages() { 104 | return Objects.requireNonNull(usages, ERROR_MESSAGE); 105 | } 106 | 107 | @Override 108 | public String getName() { 109 | return DataSyncPluginInfo.id; 110 | } 111 | 112 | @Override 113 | public String[] getPath() { 114 | return CommonSyncCommandNode.SYNC_PATH; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /datasync-common/src/main/java/org/anvilpowered/datasync/common/key/CommonDataKeyService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.common.key; 20 | 21 | import org.anvilpowered.datasync.api.key.DataKeyService; 22 | 23 | import java.util.HashMap; 24 | import java.util.Map; 25 | import java.util.Optional; 26 | 27 | public abstract class CommonDataKeyService implements DataKeyService { 28 | 29 | private Map nameMap; 30 | 31 | public CommonDataKeyService() { 32 | nameMap = new HashMap<>(); 33 | } 34 | 35 | @Override 36 | public void addMapping(K key, String name) { 37 | if (key != null && name != null) nameMap.put(key, name); 38 | } 39 | 40 | @Override 41 | public void removeMapping(K key) { 42 | nameMap.remove(key); 43 | } 44 | 45 | @Override 46 | public Optional getName(K key) { 47 | return Optional.ofNullable(nameMap.get(key)); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /datasync-common/src/main/java/org/anvilpowered/datasync/common/misc/CommonSyncUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.common.misc; 20 | 21 | import org.anvilpowered.datasync.api.misc.SyncUtils; 22 | 23 | import java.util.ArrayList; 24 | import java.util.List; 25 | import java.util.Optional; 26 | 27 | public class CommonSyncUtils implements SyncUtils { 28 | 29 | @Override 30 | public Optional> decodeOptimizationStrategy(List list) { 31 | List numsList = new ArrayList<>(); 32 | 33 | // check format 34 | if (list.stream().anyMatch(s -> { 35 | if (!(s instanceof String)) return true; 36 | String[] snums = ((String) s).split("[:]"); 37 | if (snums.length != 2) return true; 38 | int[] nums = new int[2]; 39 | try { 40 | nums[0] = Integer.parseInt(snums[0]); 41 | nums[1] = Integer.parseInt(snums[1]); 42 | } catch (NumberFormatException e) { 43 | e.printStackTrace(); 44 | return true; 45 | } 46 | if (nums[0] < 0 || nums[1] < 0) return true; 47 | numsList.add(nums); 48 | return false; 49 | } 50 | )) { 51 | return Optional.empty(); 52 | } 53 | 54 | for (int i = 0; i < numsList.size() - 1; i++) { 55 | if (numsList.get(i + 1)[0] != numsList.get(i)[0] * numsList.get(i)[1]) { 56 | return Optional.empty(); 57 | } 58 | } 59 | return Optional.of(numsList); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /datasync-common/src/main/java/org/anvilpowered/datasync/common/model/member/MongoMember.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.common.model.member; 20 | 21 | import com.google.common.base.Preconditions; 22 | import dev.morphia.annotations.Entity; 23 | import org.anvilpowered.anvil.base.model.MongoDbo; 24 | import org.anvilpowered.datasync.api.model.member.Member; 25 | import org.bson.types.ObjectId; 26 | 27 | import java.util.ArrayList; 28 | import java.util.List; 29 | import java.util.UUID; 30 | 31 | @Entity("members") 32 | public class MongoMember extends MongoDbo implements Member { 33 | 34 | private UUID userUUID; 35 | private boolean skipDeserialization; 36 | private List snapshotIds; 37 | 38 | @Override 39 | public UUID getUserUUID() { 40 | return userUUID; 41 | } 42 | 43 | @Override 44 | public void setUserUUID(UUID userUUID) { 45 | this.userUUID = userUUID; 46 | } 47 | 48 | @Override 49 | public List getSnapshotIds() { 50 | if (snapshotIds == null) { 51 | snapshotIds = new ArrayList<>(); 52 | } 53 | return snapshotIds; 54 | } 55 | 56 | @Override 57 | public void setSnapshotIds(List snapshotIds) { 58 | this.snapshotIds = Preconditions.checkNotNull(snapshotIds, "snapshotIds"); 59 | } 60 | 61 | @Override 62 | public boolean isSkipDeserialization() { 63 | return skipDeserialization; 64 | } 65 | 66 | @Override 67 | public void setSkipDeserialization(boolean skipDeserialization) { 68 | this.skipDeserialization = skipDeserialization; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /datasync-common/src/main/java/org/anvilpowered/datasync/common/model/member/XodusMember.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.common.model.member; 20 | 21 | import com.google.common.base.Preconditions; 22 | import jetbrains.exodus.entitystore.Entity; 23 | import jetbrains.exodus.entitystore.EntityId; 24 | import jetbrains.exodus.util.ByteArraySizedInputStream; 25 | import org.anvilpowered.anvil.api.datastore.XodusEntity; 26 | import org.anvilpowered.anvil.api.model.Mappable; 27 | import org.anvilpowered.anvil.base.model.XodusDbo; 28 | import org.anvilpowered.datasync.api.model.member.Member; 29 | 30 | import java.io.IOException; 31 | import java.util.ArrayList; 32 | import java.util.List; 33 | import java.util.UUID; 34 | 35 | @XodusEntity 36 | public class XodusMember extends XodusDbo implements Member, Mappable { 37 | 38 | private String userUUID; 39 | private boolean skipDeserialization; 40 | private List snapshotIds; 41 | 42 | @Override 43 | public UUID getUserUUID() { 44 | return UUID.fromString(userUUID); 45 | } 46 | 47 | @Override 48 | public void setUserUUID(UUID userUUID) { 49 | this.userUUID = userUUID.toString(); 50 | prePersist(); 51 | } 52 | 53 | @Override 54 | public List getSnapshotIds() { 55 | if (snapshotIds == null) { 56 | snapshotIds = new ArrayList<>(); 57 | } 58 | return snapshotIds; 59 | } 60 | 61 | @Override 62 | public void setSnapshotIds(List snapshotIds) { 63 | this.snapshotIds = Preconditions.checkNotNull(snapshotIds, "snapshotIds"); 64 | prePersist(); 65 | } 66 | 67 | @Override 68 | public boolean isSkipDeserialization() { 69 | return skipDeserialization; 70 | } 71 | 72 | @Override 73 | public void setSkipDeserialization(boolean skipDeserialization) { 74 | this.skipDeserialization = skipDeserialization; 75 | } 76 | 77 | @Override 78 | public Entity writeTo(Entity object) { 79 | super.writeTo(object); 80 | if (userUUID != null) { 81 | object.setProperty("userUUID", userUUID); 82 | } 83 | if (skipDeserialization) { 84 | object.setProperty("skipDeserialization", true); 85 | } 86 | try { 87 | object.setBlob("snapshotIds", 88 | new ByteArraySizedInputStream(Mappable.serializeUnsafe(getSnapshotIds()))); 89 | } catch (IOException e) { 90 | e.printStackTrace(); 91 | } 92 | return object; 93 | } 94 | 95 | @Override 96 | public void readFrom(Entity object) { 97 | super.readFrom(object); 98 | Comparable userUUID = object.getProperty("userUUID"); 99 | if (userUUID instanceof String) { 100 | this.userUUID = (String) userUUID; 101 | } 102 | Comparable skipDeserialization = object.getProperty("skipDeserialization"); 103 | if (skipDeserialization instanceof Boolean) { 104 | this.skipDeserialization = (Boolean) skipDeserialization; 105 | } 106 | Mappable.>deserialize(object.getBlob("snapshotIds")) 107 | .ifPresent(t -> snapshotIds = t); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /datasync-common/src/main/java/org/anvilpowered/datasync/common/model/snapshot/MongoSnapshot.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.common.model.snapshot; 20 | 21 | import com.google.common.base.Preconditions; 22 | import dev.morphia.annotations.Entity; 23 | import org.anvilpowered.anvil.base.model.MongoDbo; 24 | import org.anvilpowered.datasync.api.model.snapshot.Snapshot; 25 | import org.bson.types.ObjectId; 26 | 27 | import java.util.ArrayList; 28 | import java.util.HashMap; 29 | import java.util.List; 30 | import java.util.Map; 31 | 32 | @Entity("snapshots") 33 | public class MongoSnapshot extends MongoDbo implements Snapshot { 34 | 35 | private String name; 36 | 37 | private String server; 38 | 39 | private List modulesUsed; 40 | 41 | private List modulesFailed; 42 | 43 | private Map keys; 44 | 45 | private byte[] inventory; 46 | 47 | @Override 48 | public String getName() { 49 | return name; 50 | } 51 | 52 | @Override 53 | public void setName(String name) { 54 | this.name = name; 55 | } 56 | 57 | @Override 58 | public String getServer() { 59 | return server; 60 | } 61 | 62 | @Override 63 | public void setServer(String server) { 64 | this.server = server; 65 | } 66 | 67 | @Override 68 | public List getModulesUsed() { 69 | if (modulesUsed == null) { 70 | modulesUsed = new ArrayList<>(); 71 | } 72 | return modulesUsed; 73 | } 74 | 75 | @Override 76 | public void setModulesUsed(List modulesUsed) { 77 | this.modulesUsed = Preconditions.checkNotNull(modulesUsed, "modulesUsed"); 78 | } 79 | 80 | @Override 81 | public List getModulesFailed() { 82 | if (modulesFailed == null) { 83 | modulesFailed = new ArrayList<>(); 84 | } 85 | return modulesFailed; 86 | } 87 | 88 | @Override 89 | public void setModulesFailed(List modulesFailed) { 90 | this.modulesFailed = Preconditions.checkNotNull(modulesFailed, "modulesFailed"); 91 | } 92 | 93 | @Override 94 | public Map getKeys() { 95 | if (keys == null) { 96 | keys = new HashMap<>(); 97 | } 98 | return keys; 99 | } 100 | 101 | @Override 102 | public void setKeys(Map keys) { 103 | this.keys = Preconditions.checkNotNull(keys, "keys"); 104 | } 105 | 106 | @Override 107 | public byte[] getInventory() { 108 | return inventory; 109 | } 110 | 111 | @Override 112 | public void setInventory(byte[] inventory) { 113 | this.inventory = inventory; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /datasync-common/src/main/java/org/anvilpowered/datasync/common/model/snapshot/XodusSnapshot.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.common.model.snapshot; 20 | 21 | import com.google.common.base.Preconditions; 22 | import jetbrains.exodus.entitystore.Entity; 23 | import jetbrains.exodus.entitystore.EntityId; 24 | import jetbrains.exodus.util.ByteArraySizedInputStream; 25 | import jetbrains.exodus.util.LightByteArrayOutputStream; 26 | import org.anvilpowered.anvil.api.datastore.XodusEntity; 27 | import org.anvilpowered.anvil.api.model.Mappable; 28 | import org.anvilpowered.anvil.base.model.XodusDbo; 29 | import org.anvilpowered.datasync.api.model.snapshot.Snapshot; 30 | 31 | import java.io.IOException; 32 | import java.io.InputStream; 33 | import java.util.ArrayList; 34 | import java.util.HashMap; 35 | import java.util.List; 36 | import java.util.Map; 37 | 38 | @XodusEntity 39 | public class XodusSnapshot extends XodusDbo implements Snapshot, Mappable { 40 | 41 | private String name; 42 | 43 | private String server; 44 | 45 | private List modulesUsed; 46 | 47 | private List modulesFailed; 48 | 49 | private Map keys; 50 | 51 | private byte[] inventory; 52 | 53 | @Override 54 | public String getName() { 55 | return name; 56 | } 57 | 58 | @Override 59 | public void setName(String name) { 60 | this.name = name; 61 | } 62 | 63 | @Override 64 | public String getServer() { 65 | return server; 66 | } 67 | 68 | @Override 69 | public void setServer(String server) { 70 | this.server = server; 71 | } 72 | 73 | @Override 74 | public List getModulesUsed() { 75 | if (modulesUsed == null) { 76 | modulesUsed = new ArrayList<>(); 77 | } 78 | return modulesUsed; 79 | } 80 | 81 | @Override 82 | public void setModulesUsed(List modulesUsed) { 83 | this.modulesUsed = Preconditions.checkNotNull(modulesUsed, "modulesUsed"); 84 | } 85 | 86 | @Override 87 | public List getModulesFailed() { 88 | if (modulesFailed == null) { 89 | modulesFailed = new ArrayList<>(); 90 | } 91 | return modulesFailed; 92 | } 93 | 94 | @Override 95 | public void setModulesFailed(List modulesFailed) { 96 | this.modulesFailed = Preconditions.checkNotNull(modulesFailed, "modulesFailed"); 97 | } 98 | 99 | @Override 100 | public Map getKeys() { 101 | if (keys == null) { 102 | keys = new HashMap<>(); 103 | } 104 | return keys; 105 | } 106 | 107 | @Override 108 | public void setKeys(Map keys) { 109 | this.keys = Preconditions.checkNotNull(keys, "keys"); 110 | } 111 | 112 | @Override 113 | public byte[] getInventory() { 114 | return inventory; 115 | } 116 | 117 | @Override 118 | public void setInventory(byte[] inventory) { 119 | this.inventory = inventory; 120 | } 121 | 122 | @Override 123 | public Entity writeTo(Entity object) { 124 | super.writeTo(object); 125 | if (name != null) { 126 | object.setProperty("name", name); 127 | } 128 | if (server != null) { 129 | object.setProperty("server", server); 130 | } 131 | try { 132 | object.setBlob("modulesUsed", 133 | new ByteArraySizedInputStream(Mappable.serializeUnsafe(getModulesUsed()))); 134 | } catch (IOException e) { 135 | e.printStackTrace(); 136 | } 137 | try { 138 | object.setBlob("modulesFailed", 139 | new ByteArraySizedInputStream(Mappable.serializeUnsafe(getModulesFailed()))); 140 | } catch (IOException e) { 141 | e.printStackTrace(); 142 | } 143 | try { 144 | object.setBlob("keys", 145 | new ByteArraySizedInputStream(Mappable.serializeUnsafe(getKeys()))); 146 | } catch (IOException e) { 147 | e.printStackTrace(); 148 | } 149 | object.setBlob("inventory", 150 | new ByteArraySizedInputStream(inventory)); 151 | return object; 152 | } 153 | 154 | @Override 155 | public void readFrom(Entity object) { 156 | super.readFrom(object); 157 | Comparable name = object.getProperty("name"); 158 | if (name instanceof String) { 159 | this.name = (String) name; 160 | } 161 | Comparable server = object.getProperty("server"); 162 | if (name instanceof String) { 163 | this.server = (String) server; 164 | } 165 | Mappable.>deserialize(object.getBlob("modulesUsed")) 166 | .ifPresent(t -> modulesUsed = t); 167 | Mappable.>deserialize(object.getBlob("modulesFailed")) 168 | .ifPresent(t -> modulesFailed = t); 169 | Mappable.>deserialize(object.getBlob("keys")) 170 | .ifPresent(t -> keys = t); 171 | try { 172 | InputStream inputStream = object.getBlob("inventory"); 173 | if (inputStream != null) { 174 | LightByteArrayOutputStream outputStream = 175 | new LightByteArrayOutputStream(inputStream.available()); 176 | int next; 177 | while ((next = inputStream.read()) != -1) { 178 | outputStream.write(next); 179 | } 180 | setInventory(outputStream.toByteArray()); 181 | } 182 | } catch (IOException e) { 183 | e.printStackTrace(); 184 | } 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /datasync-common/src/main/java/org/anvilpowered/datasync/common/plugin/DataSyncPluginInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.common.plugin; 20 | 21 | import com.google.inject.Inject; 22 | import com.google.inject.Singleton; 23 | import org.anvilpowered.anvil.api.plugin.PluginInfo; 24 | import org.anvilpowered.anvil.api.util.TextService; 25 | 26 | @Singleton 27 | public final class DataSyncPluginInfo implements PluginInfo { 28 | public static final String id = "datasync"; 29 | public static final String name = "DataSync"; 30 | public static final String version = "$modVersion"; 31 | public static final String description 32 | = "A plugin to synchronize player inventories with a database"; 33 | public static final String url = "https://github.com/AnvilPowered/DataSync"; 34 | public static final String[] authors = {"Cableguy20"}; 35 | public static final String organizationName = "AnvilPowered"; 36 | public static final String buildDate = "$buildDate"; 37 | public TString pluginPrefix; 38 | 39 | @Inject 40 | public void setPluginPrefix(TextService textService) { 41 | pluginPrefix = textService.builder().green().append("[", name, "] ").build(); 42 | } 43 | 44 | @Override 45 | public String getId() { 46 | return id; 47 | } 48 | 49 | @Override 50 | public String getName() { 51 | return name; 52 | } 53 | 54 | @Override 55 | public String getVersion() { 56 | return version; 57 | } 58 | 59 | @Override 60 | public String getDescription() { 61 | return description; 62 | } 63 | 64 | @Override 65 | public String getUrl() { 66 | return url; 67 | } 68 | 69 | @Override 70 | public String[] getAuthors() { 71 | return authors; 72 | } 73 | 74 | @Override 75 | public String getOrganizationName() { 76 | return organizationName; 77 | } 78 | 79 | @Override 80 | public String getBuildDate() { 81 | return buildDate; 82 | } 83 | 84 | @Override 85 | public TString getPrefix() { 86 | return pluginPrefix; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /datasync-common/src/main/java/org/anvilpowered/datasync/common/registry/CommonConfigurationService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.common.registry; 20 | 21 | import com.google.inject.Inject; 22 | import com.google.inject.Singleton; 23 | import ninja.leaping.configurate.commented.CommentedConfigurationNode; 24 | import ninja.leaping.configurate.loader.ConfigurationLoader; 25 | import org.anvilpowered.anvil.api.registry.Keys; 26 | import org.anvilpowered.anvil.base.registry.BaseConfigurationService; 27 | import org.anvilpowered.datasync.api.registry.DataSyncKeys; 28 | 29 | @Singleton 30 | public class CommonConfigurationService extends BaseConfigurationService { 31 | 32 | @Inject 33 | public CommonConfigurationService(ConfigurationLoader configLoader) { 34 | super(configLoader); 35 | setDefault(Keys.DATA_DIRECTORY, "datasync"); 36 | setDefault(Keys.MONGODB_DBNAME, "datasync"); 37 | withDefault(); 38 | setName(DataSyncKeys.SERIALIZE_ENABLED_SERIALIZERS, "serialize.enabledSerializers"); 39 | setName(DataSyncKeys.DESERIALIZE_ON_JOIN, "serialize.deserializeOnJoin"); 40 | setName(DataSyncKeys.DESERIALIZE_ON_JOIN_DELAY_MILLIS, "serialize.deserializeOnJoinDelayMillis"); 41 | setName(DataSyncKeys.SERIALIZE_ON_DEATH, "serialize.serializeOnDeath"); 42 | setName(DataSyncKeys.SERIALIZE_ON_DISCONNECT, "serialize.serializeOnDisconnect"); 43 | setName(DataSyncKeys.SNAPSHOT_MIN_COUNT, "snapshot.minCount"); 44 | setName(DataSyncKeys.SNAPSHOT_OPTIMIZATION_STRATEGY, "snapshot.optimizationStrategy"); 45 | setName(DataSyncKeys.SNAPSHOT_UPLOAD_INTERVAL_MINUTES, "snapshot.uploadInterval"); 46 | setDescription(DataSyncKeys.SERIALIZE_ENABLED_SERIALIZERS, 47 | "\nThings to sync to DB." + 48 | "\nAvailable: datasync:experience, datasync:gameMode, datasync:health, datasync:hunger, datasync:inventory" 49 | ); 50 | setDescription(DataSyncKeys.DESERIALIZE_ON_JOIN, "\nWhether DataSync should deserialize players on join"); 51 | setDescription(DataSyncKeys.DESERIALIZE_ON_JOIN_DELAY_MILLIS, 52 | "\nThe number of milliseconds DataSync should wait before downloading a snapshot on join." 53 | + "\nNote: This only takes effect if deserializeOnJoin=true" 54 | + "\nOnly set this for multi-server environments like Velocity or Bungeecord." 55 | + "\n- This is necessary when the disconnect snapshot is uploaded too late." 56 | + "\n- Player inventories will be frozen until the snapshot is downloaded to prevent item loss." 57 | + "\n- A value around 5000-10000 should suffice for most heavy modpacks. Adjust as required." 58 | + "\nAdditional notes:" 59 | + "\n- If players are consistently losing inventories on join, increase this number." 60 | + "\n- If players are consistently having to wait on join, decrease this number." 61 | 62 | ); 63 | setDescription(DataSyncKeys.SERIALIZE_ON_DEATH, "\nWhether DataSync should serialize players to DB on death"); 64 | setDescription(DataSyncKeys.SERIALIZE_ON_DISCONNECT, "\nWhether DataSync should serialize players to DB on disconnect"); 65 | setDescription(DataSyncKeys.SNAPSHOT_MIN_COUNT, "\nMinimum number of snapshots to keep before deleting any"); 66 | setDescription(DataSyncKeys.SNAPSHOT_OPTIMIZATION_STRATEGY, 67 | "\nSnapshot optimization strategy. Format:\n" + 68 | "Must be \"x:y\" where\n" + 69 | "\t1) x and y are positive integers (x is minutes)\n" + 70 | "\t2) x[n + 1] = x[n] * y[n] where x[n] and y[n] are the values of x and y at line n respectively\n" + 71 | "Default of \"60:24\",\"1440:7\" will:\n" + 72 | "\t1) not remove any snapshots within the last hour\n" + 73 | "\t2) keep one snapshot per hour (not including first hour) for 24 hours\n" + 74 | "\t3) keep one snapshot per day (not including first day) for 7 days\n" + 75 | "\t4) delete all snapshots older than 7 days (keeping a minimum of minCount)" 76 | ); 77 | setDescription(DataSyncKeys.SNAPSHOT_UPLOAD_INTERVAL_MINUTES, "\nInterval for automatic serialization task. Set to 0 to disable, min 1, max 60. Recommended range 3-15"); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /datasync-common/src/main/java/org/anvilpowered/datasync/common/registry/CommonRegistry.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.common.registry; 20 | 21 | import com.google.inject.Singleton; 22 | import org.anvilpowered.anvil.api.registry.Keys; 23 | import org.anvilpowered.anvil.base.registry.BaseExtendedRegistry; 24 | 25 | @Singleton 26 | public class CommonRegistry extends BaseExtendedRegistry { 27 | 28 | public CommonRegistry() { 29 | setDefault(Keys.BASE_SCAN_PACKAGE, "org.anvilpowered.datasync.common.model"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /datasync-common/src/main/java/org/anvilpowered/datasync/common/serializer/CommonExperienceSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.common.serializer; 20 | 21 | import org.anvilpowered.datasync.api.serializer.ExperienceSerializer; 22 | 23 | public abstract class CommonExperienceSerializer< 24 | TDataKey, 25 | TUser> 26 | extends CommonSerializer 27 | implements ExperienceSerializer { 28 | 29 | @Override 30 | public String getName() { 31 | return "datasync:experience"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /datasync-common/src/main/java/org/anvilpowered/datasync/common/serializer/CommonGameModeSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.common.serializer; 20 | 21 | import org.anvilpowered.datasync.api.serializer.GameModeSerializer; 22 | 23 | public abstract class CommonGameModeSerializer< 24 | TDataKey, 25 | TUser> 26 | extends CommonSerializer 27 | implements GameModeSerializer { 28 | 29 | @Override 30 | public String getName() { 31 | return "datasync:gameMode"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /datasync-common/src/main/java/org/anvilpowered/datasync/common/serializer/CommonHealthSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.common.serializer; 20 | 21 | import org.anvilpowered.datasync.api.serializer.HealthSerializer; 22 | 23 | public abstract class CommonHealthSerializer< 24 | TDataKey, 25 | TUser> 26 | extends CommonSerializer 27 | implements HealthSerializer { 28 | 29 | @Override 30 | public String getName() { 31 | return "datasync:health"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /datasync-common/src/main/java/org/anvilpowered/datasync/common/serializer/CommonHungerSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.common.serializer; 20 | 21 | import org.anvilpowered.datasync.api.serializer.HungerSerializer; 22 | 23 | public abstract class CommonHungerSerializer< 24 | TDataKey, 25 | TUser> 26 | extends CommonSerializer 27 | implements HungerSerializer { 28 | 29 | @Override 30 | public String getName() { 31 | return "datasync:hunger"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /datasync-common/src/main/java/org/anvilpowered/datasync/common/serializer/CommonInventorySerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.common.serializer; 20 | 21 | import org.anvilpowered.datasync.api.serializer.InventorySerializer; 22 | 23 | public abstract class CommonInventorySerializer< 24 | TDataKey, 25 | TUser, 26 | TInventory, 27 | TItemStackSnapshot> 28 | extends CommonSerializer 29 | implements InventorySerializer { 30 | 31 | @Override 32 | public String getName() { 33 | return "datasync:inventory"; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /datasync-common/src/main/java/org/anvilpowered/datasync/common/serializer/CommonSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.common.serializer; 20 | 21 | import com.google.inject.Inject; 22 | import org.anvilpowered.datasync.api.serializer.Serializer; 23 | import org.anvilpowered.datasync.api.snapshot.SnapshotManager; 24 | 25 | public abstract class CommonSerializer< 26 | TDataKey, 27 | TUser> 28 | implements Serializer { 29 | 30 | @Inject 31 | protected SnapshotManager snapshotManager; 32 | } -------------------------------------------------------------------------------- /datasync-common/src/main/java/org/anvilpowered/datasync/common/serializer/user/CommonUserSerializerComponent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.common.serializer.user; 20 | 21 | import com.google.inject.Inject; 22 | import org.anvilpowered.anvil.api.registry.Keys; 23 | import org.anvilpowered.anvil.api.registry.Registry; 24 | import org.anvilpowered.anvil.api.util.UserService; 25 | import org.anvilpowered.anvil.base.datastore.BaseComponent; 26 | import org.anvilpowered.datasync.api.member.MemberRepository; 27 | import org.anvilpowered.datasync.api.model.snapshot.Snapshot; 28 | import org.anvilpowered.datasync.api.serializer.SnapshotSerializer; 29 | import org.anvilpowered.datasync.api.serializer.user.UserSerializerComponent; 30 | import org.anvilpowered.datasync.api.snapshot.SnapshotRepository; 31 | import org.slf4j.Logger; 32 | 33 | import java.util.Optional; 34 | import java.util.concurrent.CompletableFuture; 35 | 36 | public abstract class CommonUserSerializerComponent< 37 | TKey, 38 | TUser, 39 | TPlayer, 40 | TDataKey, 41 | TDataStore> 42 | extends BaseComponent 43 | implements UserSerializerComponent { 44 | 45 | @Inject 46 | protected Logger logger; 47 | 48 | @Inject 49 | protected MemberRepository memberRepository; 50 | 51 | @Inject 52 | protected SnapshotRepository snapshotRepository; 53 | 54 | @Inject 55 | protected SnapshotSerializer snapshotSerializer; 56 | 57 | @Inject 58 | protected Registry registry; 59 | 60 | @Inject 61 | protected UserService userService; 62 | 63 | @Override 64 | public CompletableFuture>> serialize(TUser user, String name) { 65 | Snapshot snapshot = snapshotRepository.generateEmpty(); 66 | snapshot.setName(name); 67 | snapshot.setServer(registry.getOrDefault(Keys.SERVER_NAME)); 68 | serialize(snapshot, user); 69 | return snapshotRepository.insertOne(snapshot).thenApplyAsync(optionalSnapshot -> { 70 | if (!optionalSnapshot.isPresent()) { 71 | logger.warn( 72 | "[DataSync] Snapshot upload failed for {}}! Check your DB configuration!", 73 | userService.getUserName(user) 74 | ); 75 | return Optional.empty(); 76 | } 77 | if (memberRepository.addSnapshotForUser(userService.getUUID(user), 78 | optionalSnapshot.get().getId()).join()) { 79 | return optionalSnapshot; 80 | } else { 81 | // remove snapshot from DB because it was not added to the user successfully 82 | snapshotRepository.deleteOne(optionalSnapshot.get().getId()).join(); 83 | return Optional.empty(); 84 | } 85 | }); 86 | } 87 | 88 | @Override 89 | public String getName() { 90 | return "datasync:player"; 91 | } 92 | 93 | @Override 94 | public boolean serialize(Snapshot snapshot, TUser user) { 95 | return snapshotSerializer.serialize(snapshot, user); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /datasync-common/src/main/java/org/anvilpowered/datasync/common/serializer/user/CommonUserTransitCache.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.common.serializer.user; 20 | 21 | import com.google.inject.Singleton; 22 | import org.anvilpowered.datasync.api.serializer.user.UserTransitCache; 23 | 24 | import java.util.UUID; 25 | import java.util.concurrent.CompletableFuture; 26 | import java.util.concurrent.ConcurrentHashMap; 27 | import java.util.concurrent.ConcurrentMap; 28 | 29 | @Singleton 30 | public class CommonUserTransitCache implements UserTransitCache { 31 | 32 | private final ConcurrentMap> uuids; 33 | 34 | public CommonUserTransitCache() { 35 | uuids = new ConcurrentHashMap<>(); 36 | } 37 | 38 | @Override 39 | public void joinStart(UUID userUUID, CompletableFuture waitFuture) { 40 | uuids.put(userUUID, waitFuture); 41 | } 42 | 43 | @Override 44 | public void joinEnd(UUID userUUID) { 45 | CompletableFuture waitFuture = uuids.remove(userUUID); 46 | // mark the wait future as invalid 47 | // in normal cases, this will be called after deserialization is already complete which will have no effect. 48 | // However, if the player leaves before waitFuture is done, mark it as invalid which prevents 49 | // premature deserialization 50 | if (waitFuture != null) { 51 | waitFuture.complete(false); 52 | } 53 | } 54 | 55 | @Override 56 | public boolean isJoining(UUID userUUID) { 57 | return uuids.containsKey(userUUID); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /datasync-common/src/main/java/org/anvilpowered/datasync/common/snapshot/CommonMongoSnapshotRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.common.snapshot; 20 | 21 | import dev.morphia.Datastore; 22 | import org.anvilpowered.anvil.base.datastore.BaseMongoRepository; 23 | import org.anvilpowered.datasync.api.model.snapshot.Snapshot; 24 | import org.bson.types.ObjectId; 25 | 26 | import java.util.concurrent.CompletableFuture; 27 | 28 | public class CommonMongoSnapshotRepository 29 | extends CommonSnapshotRepository 30 | implements BaseMongoRepository> { 31 | 32 | @Override 33 | public CompletableFuture setInventory(ObjectId id, byte[] inventory) { 34 | return update(asQuery(id), set("inventory", inventory)); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /datasync-common/src/main/java/org/anvilpowered/datasync/common/snapshot/CommonSnapshotManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.common.snapshot; 20 | 21 | import com.google.inject.Inject; 22 | import org.anvilpowered.anvil.api.registry.Registry; 23 | import org.anvilpowered.anvil.base.datastore.BaseManager; 24 | import org.anvilpowered.datasync.api.snapshot.SnapshotManager; 25 | import org.anvilpowered.datasync.api.snapshot.SnapshotRepository; 26 | 27 | public class CommonSnapshotManager 28 | extends BaseManager> 29 | implements SnapshotManager { 30 | 31 | @Inject 32 | public CommonSnapshotManager(Registry registry) { 33 | super(registry); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /datasync-common/src/main/java/org/anvilpowered/datasync/common/snapshot/CommonSnapshotRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.common.snapshot; 20 | 21 | import com.google.inject.Inject; 22 | import org.anvilpowered.anvil.base.datastore.BaseRepository; 23 | import org.anvilpowered.datasync.api.key.DataKeyService; 24 | import org.anvilpowered.datasync.api.model.snapshot.Snapshot; 25 | import org.anvilpowered.datasync.api.snapshot.SnapshotRepository; 26 | 27 | import java.util.Optional; 28 | import java.util.concurrent.CompletableFuture; 29 | 30 | public abstract class CommonSnapshotRepository< 31 | TKey, 32 | TDataKey, 33 | TDataStore> 34 | extends BaseRepository, TDataStore> 35 | implements SnapshotRepository { 36 | 37 | @Inject 38 | DataKeyService dataKeyService; 39 | 40 | @Override 41 | @SuppressWarnings("unchecked") 42 | public Class> getTClass() { 43 | return (Class>) getDataStoreContext().getEntityClassUnsafe("snapshot"); 44 | } 45 | 46 | @Override 47 | public boolean setSnapshotValue(Snapshot snapshot, TDataKey key, Optional optionalValue) { 48 | if (!optionalValue.isPresent()) { 49 | return false; 50 | } 51 | Optional optionalName = dataKeyService.getName(key); 52 | if (!optionalName.isPresent()) { 53 | return false; 54 | } 55 | snapshot.getKeys().put(optionalName.get(), optionalValue.get()); 56 | return true; 57 | } 58 | 59 | @Override 60 | public Optional getSnapshotValue(Snapshot snapshot, TDataKey key) { 61 | Optional optionalName = dataKeyService.getName(key); 62 | return optionalName.map(s -> snapshot.getKeys().get(s)); 63 | } 64 | 65 | @Override 66 | public CompletableFuture parseAndSetInventory( 67 | Object id, byte[] inventory) { 68 | return parse(id).map(i -> setInventory(i, inventory)) 69 | .orElse(CompletableFuture.completedFuture(false)); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /datasync-common/src/main/java/org/anvilpowered/datasync/common/snapshot/CommonXodusSnapshotRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.common.snapshot; 20 | 21 | import jetbrains.exodus.entitystore.EntityId; 22 | import jetbrains.exodus.entitystore.PersistentEntityStore; 23 | import jetbrains.exodus.util.ByteArraySizedInputStream; 24 | import org.anvilpowered.anvil.base.datastore.BaseXodusRepository; 25 | import org.anvilpowered.datasync.api.model.snapshot.Snapshot; 26 | 27 | import java.util.concurrent.CompletableFuture; 28 | 29 | public class CommonXodusSnapshotRepository 30 | extends CommonSnapshotRepository 31 | implements BaseXodusRepository> { 32 | 33 | @Override 34 | public CompletableFuture setInventory(EntityId id, byte[] inventory) { 35 | return update(asQuery(id), entity -> { 36 | entity.setBlob("inventory", new ByteArraySizedInputStream(inventory)); 37 | }); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /datasync-common/src/main/java/org/anvilpowered/datasync/common/snapshotoptimization/CommonSnapshotOptimizationManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.common.snapshotoptimization; 20 | 21 | import com.google.inject.Inject; 22 | import org.anvilpowered.anvil.api.plugin.PluginInfo; 23 | import org.anvilpowered.anvil.api.registry.Registry; 24 | import org.anvilpowered.anvil.api.util.TextService; 25 | import org.anvilpowered.anvil.base.datastore.BaseManager; 26 | import org.anvilpowered.datasync.api.snapshotoptimization.SnapshotOptimizationManager; 27 | import org.anvilpowered.datasync.api.snapshotoptimization.SnapshotOptimizationService; 28 | 29 | import java.text.DecimalFormat; 30 | import java.text.NumberFormat; 31 | 32 | public class CommonSnapshotOptimizationManager< 33 | TUser, 34 | TString, 35 | TCommandSource> 36 | extends BaseManager> 37 | implements SnapshotOptimizationManager { 38 | 39 | @Inject 40 | TextService textService; 41 | 42 | @Inject 43 | PluginInfo pluginInfo; 44 | 45 | private static final NumberFormat formatter = new DecimalFormat("#0.00"); 46 | 47 | @Inject 48 | public CommonSnapshotOptimizationManager(Registry registry) { 49 | super(registry); 50 | } 51 | 52 | @Override 53 | public TString info() { 54 | int uploaded = getPrimaryComponent().getSnapshotsUploaded(); 55 | int deleted = getPrimaryComponent().getSnapshotsDeleted(); 56 | int completed = getPrimaryComponent().getMembersCompleted(); 57 | int total = getPrimaryComponent().getTotalMembers(); 58 | 59 | if (getPrimaryComponent().isOptimizationTaskRunning()) { 60 | return textService.builder() 61 | .append(pluginInfo.getPrefix()) 62 | .yellow().append("Optimization task:\n") 63 | .gray().append("Snapshots uploaded: ") 64 | .yellow().append(uploaded, "\n") 65 | .gray().append("Snapshots deleted: ") 66 | .yellow().append(deleted, "\n") 67 | .gray().append("Members processed: ") 68 | .yellow().append(completed, "/", total, "\n") 69 | .gray().append("Progress: ") 70 | .yellow().append(formatter.format(completed * 100d / total), "%") 71 | .build(); 72 | } 73 | return textService.builder() 74 | .append(pluginInfo.getPrefix()) 75 | .yellow().append("There is currently no optimization task running") 76 | .build(); 77 | } 78 | 79 | @Override 80 | public TString stop() { 81 | TextService.Builder builder = textService.builder() 82 | .append(pluginInfo.getPrefix()).yellow(); 83 | if (getPrimaryComponent().stopOptimizationTask()) { 84 | builder.append("Successfully stopped optimization task"); 85 | } else { 86 | builder.append("There is currently no optimization task running"); 87 | } 88 | return builder.build(); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /datasync-common/src/main/java/org/anvilpowered/datasync/common/task/CommonSerializationTaskService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.common.task; 20 | 21 | import com.google.inject.Inject; 22 | import org.anvilpowered.anvil.api.registry.Registry; 23 | import org.anvilpowered.datasync.api.registry.DataSyncKeys; 24 | import org.anvilpowered.datasync.api.snapshotoptimization.SnapshotOptimizationManager; 25 | import org.anvilpowered.datasync.api.task.SerializationTaskService; 26 | 27 | public abstract class CommonSerializationTaskService< 28 | TUser, 29 | TString, 30 | TCommandSource> 31 | implements SerializationTaskService { 32 | 33 | @Inject 34 | protected SnapshotOptimizationManager 35 | snapshotOptimizationManager; 36 | 37 | protected Registry registry; 38 | 39 | protected int baseInterval; 40 | 41 | protected CommonSerializationTaskService(Registry registry) { 42 | this.registry = registry; 43 | registry.whenLoaded(this::registryLoaded).register(); 44 | } 45 | 46 | private void registryLoaded() { 47 | baseInterval = registry.getOrDefault(DataSyncKeys.SNAPSHOT_UPLOAD_INTERVAL_MINUTES); 48 | stopSerializationTask(); 49 | startSerializationTask(); 50 | } 51 | } -------------------------------------------------------------------------------- /datasync-sponge/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.github.johnrengelman.shadow' version '8.1.1' 3 | id 'org.spongepowered.gradle.plugin' version '1.1.1' 4 | } 5 | 6 | jar.enabled = false // we only want shadowJar 7 | 8 | dependencies { 9 | implementation project(':datasync-api') 10 | implementation project(':datasync-common') 11 | implementation configurate_hocon 12 | implementation 'org.spongepowered:spongeapi:7.3.0-SNAPSHOT' 13 | annotationProcessor 'org.spongepowered:spongeapi:7.3.0-SNAPSHOT' 14 | } 15 | 16 | shadowJar { 17 | String jarName = "DataSync-Sponge-${project.version}.jar" 18 | println "Building: " + jarName 19 | archiveFileName = jarName 20 | 21 | dependencies { 22 | include project(':datasync-api') 23 | include project(':datasync-common') 24 | } 25 | } 26 | 27 | artifacts { 28 | archives shadowJar 29 | } 30 | -------------------------------------------------------------------------------- /datasync-sponge/src/main/java/org/anvilpowered/datasync/sponge/DataSyncSponge.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.sponge; 20 | 21 | import com.google.inject.Inject; 22 | import com.google.inject.Injector; 23 | import org.anvilpowered.anvil.api.Environment; 24 | import org.anvilpowered.datasync.api.DataSyncImpl; 25 | import org.anvilpowered.datasync.common.plugin.DataSyncPluginInfo; 26 | import org.anvilpowered.datasync.sponge.listener.SpongePlayerListener; 27 | import org.anvilpowered.datasync.sponge.module.SpongeModule; 28 | import org.spongepowered.api.Sponge; 29 | import org.spongepowered.api.data.key.Key; 30 | import org.spongepowered.api.event.Listener; 31 | import org.spongepowered.api.event.game.GameReloadEvent; 32 | import org.spongepowered.api.plugin.Dependency; 33 | import org.spongepowered.api.plugin.Plugin; 34 | 35 | @Plugin( 36 | id = DataSyncPluginInfo.id, 37 | name = DataSyncPluginInfo.name, 38 | version = DataSyncPluginInfo.version, 39 | dependencies = @Dependency( 40 | id = "anvil", 41 | version = "0.3-SNAPSHOT" 42 | ), 43 | description = DataSyncPluginInfo.description, 44 | url = DataSyncPluginInfo.url, 45 | authors = "Cableguy20" 46 | ) 47 | public class DataSyncSponge extends DataSyncImpl> { 48 | 49 | @Inject 50 | public DataSyncSponge(Injector injector) { 51 | super(injector, new SpongeModule()); 52 | } 53 | 54 | @Override 55 | protected void applyToBuilder(Environment.Builder builder) { 56 | super.applyToBuilder(builder); 57 | builder.addEarlyServices(SpongePlayerListener.class, t -> 58 | Sponge.getEventManager().registerListeners(this, t)); 59 | } 60 | 61 | @Listener 62 | public void reload(GameReloadEvent event) { 63 | environment.reload(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /datasync-sponge/src/main/java/org/anvilpowered/datasync/sponge/command/SpongeSyncCommandNode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.sponge.command; 20 | 21 | import com.google.inject.Inject; 22 | import org.anvilpowered.anvil.api.registry.Registry; 23 | import org.anvilpowered.datasync.api.registry.DataSyncKeys; 24 | import org.anvilpowered.datasync.common.command.CommonSyncCommandNode; 25 | import org.anvilpowered.datasync.sponge.command.optimize.SpongeOptimizeCommandNode; 26 | import org.anvilpowered.datasync.sponge.command.snapshot.SpongeSnapshotCommandNode; 27 | import org.spongepowered.api.Sponge; 28 | import org.spongepowered.api.command.CommandSource; 29 | import org.spongepowered.api.command.args.GenericArguments; 30 | import org.spongepowered.api.command.spec.CommandExecutor; 31 | import org.spongepowered.api.command.spec.CommandSpec; 32 | import org.spongepowered.api.text.Text; 33 | 34 | import java.util.Arrays; 35 | import java.util.HashMap; 36 | import java.util.List; 37 | import java.util.Map; 38 | 39 | public class SpongeSyncCommandNode 40 | extends CommonSyncCommandNode { 41 | 42 | @Inject 43 | private SpongeOptimizeCommandNode optimizeCommandNode; 44 | 45 | @Inject 46 | private SpongeSnapshotCommandNode snapshotCommandNode; 47 | 48 | @Inject 49 | private SpongeSyncLockCommand syncLockCommand; 50 | 51 | @Inject 52 | private SpongeSyncReloadCommand syncReloadCommand; 53 | 54 | @Inject 55 | private SpongeSyncTestCommand syncTestCommand; 56 | 57 | @Inject 58 | private SpongeSyncUploadCommand syncUploadCommand; 59 | 60 | @Inject 61 | public SpongeSyncCommandNode(Registry registry) { 62 | super(registry); 63 | } 64 | 65 | @Override 66 | protected void loadCommands() { 67 | System.out.println("Loading Commands"); 68 | 69 | Map, CommandSpec> subCommands = new HashMap<>(); 70 | 71 | subCommands.put(Arrays.asList("optimize", "opt", "o"), optimizeCommandNode.getRoot()); 72 | subCommands.put(Arrays.asList("snapshot", "snap", "s"), snapshotCommandNode.getRoot()); 73 | 74 | Map lockChoices = new HashMap<>(); 75 | 76 | lockChoices.put("on", "on"); 77 | lockChoices.put("off", "off"); 78 | 79 | subCommands.put(LOCK_ALIAS, CommandSpec.builder() 80 | .description(Text.of(LOCK_DESCRIPTION)) 81 | .permission(registry.getDefault(DataSyncKeys.LOCK_COMMAND_PERMISSION)) 82 | .arguments( 83 | GenericArguments.optional(GenericArguments.choices(Text.of("value"), lockChoices)) 84 | ) 85 | .executor(syncLockCommand) 86 | .build()); 87 | 88 | subCommands.put(RELOAD_ALIAS, CommandSpec.builder() 89 | .description(Text.of(RELOAD_DESCRIPTION)) 90 | .permission(registry.getOrDefault(DataSyncKeys.RELOAD_COMMAND_PERMISSION)) 91 | .executor(syncReloadCommand) 92 | .build()); 93 | 94 | subCommands.put(TEST_ALIAS, CommandSpec.builder() 95 | .description(Text.of(TEST_DESCRIPTION)) 96 | .permission(registry.getOrDefault(DataSyncKeys.TEST_COMMAND_PERMISSION)) 97 | .executor(syncTestCommand) 98 | .build()); 99 | 100 | subCommands.put(UPLOAD_ALIAS, CommandSpec.builder() 101 | .description(Text.of(UPLOAD_DESCRIPTION)) 102 | .permission(registry.getOrDefault(DataSyncKeys.SNAPSHOT_CREATE_PERMISSION)) 103 | .executor(syncUploadCommand) 104 | .build()); 105 | 106 | subCommands.put(HELP_ALIAS, CommandSpec.builder() 107 | .description(Text.of(HELP_DESCRIPTION)) 108 | .executor(commandService.generateHelpCommand(this)) 109 | .build()); 110 | 111 | subCommands.put(VERSION_ALIAS, CommandSpec.builder() 112 | .description(Text.of(VERSION_DESCRIPTION)) 113 | .executor(commandService.generateVersionCommand(HELP_COMMAND)) 114 | .build()); 115 | 116 | CommandSpec root = CommandSpec.builder() 117 | .description(Text.of(ROOT_DESCRIPTION)) 118 | .executor(commandService.generateRootCommand(HELP_COMMAND)) 119 | .children(subCommands) 120 | .build(); 121 | 122 | Sponge.getCommandManager() 123 | .register(environment.getPlugin(), root, "sync", "datasync"); 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /datasync-sponge/src/main/java/org/anvilpowered/datasync/sponge/command/SpongeSyncLockCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.sponge.command; 20 | 21 | import com.google.inject.Inject; 22 | import org.anvilpowered.anvil.api.plugin.PluginInfo; 23 | import org.spongepowered.api.command.CommandException; 24 | import org.spongepowered.api.command.CommandResult; 25 | import org.spongepowered.api.command.CommandSource; 26 | import org.spongepowered.api.command.args.CommandContext; 27 | import org.spongepowered.api.command.spec.CommandExecutor; 28 | import org.spongepowered.api.entity.living.player.Player; 29 | import org.spongepowered.api.text.Text; 30 | import org.spongepowered.api.text.format.TextColors; 31 | 32 | import java.util.ArrayList; 33 | import java.util.List; 34 | import java.util.Optional; 35 | import java.util.UUID; 36 | 37 | public class SpongeSyncLockCommand implements CommandExecutor { 38 | 39 | @Inject 40 | PluginInfo pluginInfo; 41 | 42 | private static final List unlockedPlayers = new ArrayList<>(); 43 | 44 | public static void assertUnlocked(CommandSource source) throws CommandException { 45 | if (source instanceof Player && !unlockedPlayers.contains(((Player) source).getUniqueId())) { 46 | throw new CommandException(Text.of("You must first unlock this command with /sync lock off")); 47 | } 48 | } 49 | 50 | public static void lockPlayer(CommandSource source) { 51 | if (source instanceof Player) { 52 | unlockedPlayers.remove(((Player) source).getUniqueId()); 53 | } 54 | } 55 | 56 | @Override 57 | public CommandResult execute(CommandSource source, CommandContext context) { 58 | if (source instanceof Player) { 59 | Player player = (Player) source; 60 | Optional optionalValue = context.getOne(Text.of("value")); 61 | 62 | int index = unlockedPlayers.indexOf((player.getUniqueId())); 63 | 64 | if (!optionalValue.isPresent()) { 65 | source.sendMessage(Text.of(pluginInfo.getPrefix(), TextColors.YELLOW, "Currently ", index >= 0 ? "unlocked" : "locked")); 66 | return CommandResult.success(); 67 | } 68 | 69 | String value = optionalValue.get(); 70 | 71 | switch (value) { 72 | case "on": 73 | if (index >= 0) { 74 | unlockedPlayers.remove(index); 75 | source.sendMessage(Text.of(pluginInfo.getPrefix(), TextColors.YELLOW, "Lock enabled")); 76 | } else { 77 | source.sendMessage(Text.of(pluginInfo.getPrefix(), TextColors.YELLOW, "Lock already enabled")); 78 | } 79 | break; 80 | case "off": 81 | if (index < 0) { 82 | unlockedPlayers.add(player.getUniqueId()); 83 | source.sendMessage(Text.of(pluginInfo.getPrefix(), TextColors.YELLOW, "Lock disabled", TextColors.RED, " (be careful)")); 84 | } else { 85 | source.sendMessage(Text.of(pluginInfo.getPrefix(), TextColors.YELLOW, "Lock already disabled")); 86 | } 87 | break; 88 | default: 89 | source.sendMessage(Text.of(pluginInfo.getPrefix(), TextColors.RED, "Unrecognized option: \"", value, "\". Lock is ", TextColors.YELLOW, index >= 0 ? "disabled" : "enabled")); 90 | break; 91 | } 92 | 93 | 94 | } else { 95 | // console is always unlocked 96 | source.sendMessage(Text.of(pluginInfo.getPrefix(), TextColors.RED, "Console is always unlocked")); 97 | } 98 | 99 | return CommandResult.success(); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /datasync-sponge/src/main/java/org/anvilpowered/datasync/sponge/command/SpongeSyncReloadCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.sponge.command; 20 | 21 | import com.google.inject.Inject; 22 | import org.anvilpowered.anvil.api.plugin.PluginInfo; 23 | import org.anvilpowered.anvil.api.registry.Registry; 24 | import org.spongepowered.api.command.CommandResult; 25 | import org.spongepowered.api.command.CommandSource; 26 | import org.spongepowered.api.command.args.CommandContext; 27 | import org.spongepowered.api.command.spec.CommandExecutor; 28 | import org.spongepowered.api.text.Text; 29 | import org.spongepowered.api.text.format.TextColors; 30 | 31 | public class SpongeSyncReloadCommand implements CommandExecutor { 32 | 33 | @Inject 34 | private Registry registry; 35 | 36 | @Inject 37 | private PluginInfo pluginInfo; 38 | 39 | @Override 40 | public CommandResult execute(CommandSource source, CommandContext context) { 41 | registry.load(); 42 | source.sendMessage(Text.of(pluginInfo.getPrefix(), TextColors.GREEN, "Successfully reloaded!")); 43 | return CommandResult.success(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /datasync-sponge/src/main/java/org/anvilpowered/datasync/sponge/command/SpongeSyncTestCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.sponge.command; 20 | 21 | import com.google.inject.Inject; 22 | import org.anvilpowered.anvil.api.plugin.PluginInfo; 23 | import org.anvilpowered.datasync.api.serializer.user.UserSerializerManager; 24 | import org.spongepowered.api.command.CommandResult; 25 | import org.spongepowered.api.command.CommandSource; 26 | import org.spongepowered.api.command.args.CommandContext; 27 | import org.spongepowered.api.command.spec.CommandExecutor; 28 | import org.spongepowered.api.entity.living.player.Player; 29 | import org.spongepowered.api.entity.living.player.User; 30 | import org.spongepowered.api.text.Text; 31 | import org.spongepowered.api.text.format.TextColors; 32 | 33 | public class SpongeSyncTestCommand implements CommandExecutor { 34 | 35 | @Inject 36 | private UserSerializerManager userSerializerManager; 37 | 38 | @Inject 39 | private PluginInfo pluginInfo; 40 | 41 | @Override 42 | public CommandResult execute(CommandSource source, CommandContext context) { 43 | if (!(source instanceof Player)) { 44 | source.sendMessage(Text.of(pluginInfo.getPrefix(), TextColors.RED, "Run as player")); 45 | return CommandResult.empty(); 46 | } 47 | Player player = (Player) source; 48 | userSerializerManager.serialize(player) 49 | .exceptionally(e -> { 50 | e.printStackTrace(); 51 | source.sendMessage(Text.of((Object[]) e.getStackTrace())); 52 | return null; 53 | }) 54 | .thenAcceptAsync(text -> { 55 | if (text == null) { 56 | return; 57 | } 58 | source.sendMessage(text); 59 | source.sendMessage(Text.of(pluginInfo.getPrefix(), 60 | TextColors.GREEN, "Deserializing in 5 seconds")); 61 | try { 62 | Thread.sleep(5000); 63 | } catch (InterruptedException e) { 64 | e.printStackTrace(); 65 | } 66 | userSerializerManager.restore(player.getUniqueId(), null) 67 | .thenAcceptAsync(source::sendMessage); 68 | }); 69 | return CommandResult.success(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /datasync-sponge/src/main/java/org/anvilpowered/datasync/sponge/command/SpongeSyncUploadCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.sponge.command; 20 | 21 | import com.google.inject.Inject; 22 | import org.anvilpowered.datasync.api.serializer.user.UserSerializerManager; 23 | import org.spongepowered.api.Sponge; 24 | import org.spongepowered.api.command.CommandException; 25 | import org.spongepowered.api.command.CommandResult; 26 | import org.spongepowered.api.command.CommandSource; 27 | import org.spongepowered.api.command.args.CommandContext; 28 | import org.spongepowered.api.command.spec.CommandExecutor; 29 | import org.spongepowered.api.entity.living.player.User; 30 | import org.spongepowered.api.text.Text; 31 | 32 | public class SpongeSyncUploadCommand implements CommandExecutor { 33 | 34 | @Inject 35 | private UserSerializerManager userSerializer; 36 | 37 | @Override 38 | public CommandResult execute(CommandSource source, CommandContext context) throws CommandException { 39 | SpongeSyncLockCommand.assertUnlocked(source); 40 | // serialize everyone on the server 41 | userSerializer.serialize(Sponge.getServer().getOnlinePlayers()).thenAcceptAsync(source::sendMessage); 42 | return CommandResult.success(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /datasync-sponge/src/main/java/org/anvilpowered/datasync/sponge/command/optimize/SpongeOptimizeCommandNode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.sponge.command.optimize; 20 | 21 | import com.google.inject.Inject; 22 | import org.anvilpowered.anvil.api.registry.Registry; 23 | import org.anvilpowered.datasync.api.registry.DataSyncKeys; 24 | import org.anvilpowered.datasync.common.command.optimize.CommonOptimizeCommandNode; 25 | import org.spongepowered.api.command.CommandCallable; 26 | import org.spongepowered.api.command.CommandSource; 27 | import org.spongepowered.api.command.args.GenericArguments; 28 | import org.spongepowered.api.command.spec.CommandExecutor; 29 | import org.spongepowered.api.command.spec.CommandSpec; 30 | import org.spongepowered.api.text.Text; 31 | 32 | import java.util.HashMap; 33 | import java.util.List; 34 | import java.util.Map; 35 | 36 | public class SpongeOptimizeCommandNode 37 | extends CommonOptimizeCommandNode { 38 | 39 | CommandSpec root; 40 | 41 | @Inject 42 | private SpongeOptimizeInfoCommand optimizeInfoCommand; 43 | 44 | @Inject 45 | private SpongeOptimizeStartCommand optimizeStartCommand; 46 | 47 | @Inject 48 | private SpongeOptimizeStopCommand optimizeStopCommand; 49 | 50 | @Inject 51 | public SpongeOptimizeCommandNode(Registry registry) { 52 | super(registry); 53 | } 54 | 55 | @Override 56 | protected void loadCommands() { 57 | 58 | Map, CommandCallable> subCommands = new HashMap<>(); 59 | 60 | Map optimizeStartChoices = new HashMap<>(); 61 | 62 | optimizeStartChoices.put("all", "all"); 63 | optimizeStartChoices.put("user", "user"); 64 | 65 | subCommands.put(START_ALIAS, CommandSpec.builder() 66 | .description(Text.of(START_DESCRIPTION)) 67 | .permission(registry.getOrDefault(DataSyncKeys.MANUAL_OPTIMIZATION_BASE_PERMISSION)) 68 | .arguments( 69 | GenericArguments.choices(Text.of("mode"), optimizeStartChoices), 70 | GenericArguments.optional(GenericArguments.user(Text.of("user"))) 71 | ) 72 | .executor(optimizeStartCommand) 73 | .build()); 74 | 75 | subCommands.put(INFO_ALIAS, CommandSpec.builder() 76 | .description(Text.of(INFO_DESCRIPTION)) 77 | .permission(registry.getOrDefault(DataSyncKeys.MANUAL_OPTIMIZATION_BASE_PERMISSION)) 78 | .executor(optimizeInfoCommand) 79 | .build()); 80 | 81 | subCommands.put(STOP_ALIAS, CommandSpec.builder() 82 | .description(Text.of(STOP_DESCRIPTION)) 83 | .permission(registry.getOrDefault(DataSyncKeys.MANUAL_OPTIMIZATION_BASE_PERMISSION)) 84 | .executor(optimizeStopCommand) 85 | .build()); 86 | 87 | subCommands.put(HELP_ALIAS, CommandSpec.builder() 88 | .description(Text.of(HELP_DESCRIPTION)) 89 | .permission(registry.getOrDefault(DataSyncKeys.MANUAL_OPTIMIZATION_BASE_PERMISSION)) 90 | .executor(commandService.generateHelpCommand(this)) 91 | .build()); 92 | 93 | root = CommandSpec.builder() 94 | .description(Text.of(ROOT_DESCRIPTION)) 95 | .permission(registry.getOrDefault(DataSyncKeys.MANUAL_OPTIMIZATION_BASE_PERMISSION)) 96 | .executor(commandService.generateRootCommand(HELP_COMMAND)) 97 | .children(subCommands) 98 | .build(); 99 | } 100 | 101 | public CommandSpec getRoot() { 102 | if (root == null) { 103 | loadCommands(); 104 | } 105 | return root; 106 | } 107 | 108 | @Override 109 | public String getName() { 110 | return "optimize"; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /datasync-sponge/src/main/java/org/anvilpowered/datasync/sponge/command/optimize/SpongeOptimizeInfoCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.sponge.command.optimize; 20 | 21 | import org.anvilpowered.datasync.api.snapshotoptimization.SnapshotOptimizationManager; 22 | import org.spongepowered.api.command.CommandResult; 23 | import org.spongepowered.api.command.CommandSource; 24 | import org.spongepowered.api.command.args.CommandContext; 25 | import org.spongepowered.api.command.spec.CommandExecutor; 26 | import org.spongepowered.api.entity.living.player.User; 27 | import org.spongepowered.api.text.Text; 28 | 29 | import javax.inject.Inject; 30 | 31 | public class SpongeOptimizeInfoCommand implements CommandExecutor { 32 | 33 | @Inject 34 | private SnapshotOptimizationManager snapshotOptimizationManager; 35 | 36 | @Override 37 | public CommandResult execute(CommandSource source, CommandContext context) { 38 | source.sendMessage(snapshotOptimizationManager.info()); 39 | return CommandResult.success(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /datasync-sponge/src/main/java/org/anvilpowered/datasync/sponge/command/optimize/SpongeOptimizeStartCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.sponge.command.optimize; 20 | 21 | import com.google.inject.Inject; 22 | import org.anvilpowered.anvil.api.plugin.PluginInfo; 23 | import org.anvilpowered.datasync.api.registry.DataSyncKeys; 24 | import org.anvilpowered.datasync.api.snapshotoptimization.SnapshotOptimizationManager; 25 | import org.anvilpowered.datasync.sponge.command.SpongeSyncLockCommand; 26 | import org.spongepowered.api.command.CommandException; 27 | import org.spongepowered.api.command.CommandResult; 28 | import org.spongepowered.api.command.CommandSource; 29 | import org.spongepowered.api.command.args.CommandContext; 30 | import org.spongepowered.api.command.spec.CommandExecutor; 31 | import org.spongepowered.api.entity.living.player.User; 32 | import org.spongepowered.api.text.Text; 33 | import org.spongepowered.api.text.format.TextColors; 34 | 35 | import java.util.Collection; 36 | import java.util.Optional; 37 | 38 | public class SpongeOptimizeStartCommand implements CommandExecutor { 39 | 40 | @Inject 41 | private PluginInfo pluginInfo; 42 | 43 | @Inject 44 | private SnapshotOptimizationManager snapshotOptimizationManager; 45 | 46 | @Override 47 | public CommandResult execute(CommandSource source, CommandContext context) throws CommandException { 48 | 49 | SpongeSyncLockCommand.assertUnlocked(source); 50 | 51 | Optional optionalMode = context.getOne(Text.of("mode")); 52 | Collection users = context.getAll(Text.of("user")); 53 | 54 | if (!optionalMode.isPresent()) { 55 | throw new CommandException(Text.of(pluginInfo.getPrefix(), "Mode is required")); 56 | } 57 | 58 | if (optionalMode.get().equals("all")) { 59 | if (!source.hasPermission(DataSyncKeys.MANUAL_OPTIMIZATION_ALL_PERMISSION.getFallbackValue())) { 60 | throw new CommandException(Text.of(pluginInfo.getPrefix(), "You do not have permission to start optimization task: all")); 61 | } else if (snapshotOptimizationManager.getPrimaryComponent().optimize(source)) { 62 | source.sendMessage(Text.of(pluginInfo.getPrefix(), TextColors.YELLOW, "Successfully started optimization task: all")); 63 | } else { 64 | throw new CommandException(Text.of(pluginInfo.getPrefix(), "Optimizer already running! Use /sync optimize info")); 65 | } 66 | snapshotOptimizationManager.getPrimaryComponent().optimize(source); 67 | } else { 68 | if (users.isEmpty()) { 69 | throw new CommandException(Text.of(pluginInfo.getPrefix(), "No users were selected by your query")); 70 | } else if (snapshotOptimizationManager.getPrimaryComponent().optimize(users, source, "Manual")) { 71 | source.sendMessage(Text.of(pluginInfo.getPrefix(), TextColors.YELLOW, "Successfully started optimization task: user")); 72 | } else { 73 | throw new CommandException(Text.of(pluginInfo.getPrefix(), "Optimizer already running! Use /sync optimize info")); 74 | } 75 | } 76 | 77 | return CommandResult.success(); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /datasync-sponge/src/main/java/org/anvilpowered/datasync/sponge/command/optimize/SpongeOptimizeStopCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.sponge.command.optimize; 20 | 21 | import org.anvilpowered.datasync.api.snapshotoptimization.SnapshotOptimizationManager; 22 | import org.anvilpowered.datasync.sponge.command.SpongeSyncLockCommand; 23 | import org.spongepowered.api.command.CommandException; 24 | import org.spongepowered.api.command.CommandResult; 25 | import org.spongepowered.api.command.CommandSource; 26 | import org.spongepowered.api.command.args.CommandContext; 27 | import org.spongepowered.api.command.spec.CommandExecutor; 28 | import org.spongepowered.api.entity.living.player.User; 29 | import org.spongepowered.api.text.Text; 30 | 31 | import javax.inject.Inject; 32 | 33 | public class SpongeOptimizeStopCommand implements CommandExecutor { 34 | 35 | @Inject 36 | private SnapshotOptimizationManager snapshotOptimizationManager; 37 | 38 | @Override 39 | public CommandResult execute(CommandSource source, CommandContext context) throws CommandException { 40 | SpongeSyncLockCommand.assertUnlocked(source); 41 | source.sendMessage(snapshotOptimizationManager.stop()); 42 | return CommandResult.success(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /datasync-sponge/src/main/java/org/anvilpowered/datasync/sponge/command/snapshot/SpongeSnapshotCreateCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.sponge.command.snapshot; 20 | 21 | import com.google.inject.Inject; 22 | import org.anvilpowered.anvil.api.plugin.PluginInfo; 23 | import org.anvilpowered.datasync.api.serializer.user.UserSerializerManager; 24 | import org.anvilpowered.datasync.sponge.command.SpongeSyncLockCommand; 25 | import org.spongepowered.api.command.CommandException; 26 | import org.spongepowered.api.command.CommandResult; 27 | import org.spongepowered.api.command.CommandSource; 28 | import org.spongepowered.api.command.args.CommandContext; 29 | import org.spongepowered.api.command.spec.CommandExecutor; 30 | import org.spongepowered.api.entity.living.player.User; 31 | import org.spongepowered.api.text.Text; 32 | 33 | import java.util.Optional; 34 | 35 | public class SpongeSnapshotCreateCommand implements CommandExecutor { 36 | 37 | @Inject 38 | private PluginInfo pluginInfo; 39 | 40 | @Inject 41 | private UserSerializerManager userSerializer; 42 | 43 | @Override 44 | public CommandResult execute(CommandSource source, CommandContext context) throws CommandException { 45 | SpongeSyncLockCommand.assertUnlocked(source); 46 | Optional optionalUser = context.getOne(Text.of("user")); 47 | if (!optionalUser.isPresent()) { 48 | throw new CommandException(Text.of(pluginInfo.getPrefix(), "User is required")); 49 | } 50 | userSerializer.serialize(optionalUser.get()).thenAcceptAsync(source::sendMessage); 51 | return CommandResult.success(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /datasync-sponge/src/main/java/org/anvilpowered/datasync/sponge/command/snapshot/SpongeSnapshotDeleteCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.sponge.command.snapshot; 20 | 21 | import com.google.inject.Inject; 22 | import org.anvilpowered.anvil.api.plugin.PluginInfo; 23 | import org.anvilpowered.datasync.api.member.MemberManager; 24 | import org.anvilpowered.datasync.sponge.command.SpongeSyncLockCommand; 25 | import org.spongepowered.api.command.CommandException; 26 | import org.spongepowered.api.command.CommandResult; 27 | import org.spongepowered.api.command.CommandSource; 28 | import org.spongepowered.api.command.args.CommandContext; 29 | import org.spongepowered.api.command.spec.CommandExecutor; 30 | import org.spongepowered.api.entity.living.player.User; 31 | import org.spongepowered.api.text.Text; 32 | 33 | import java.util.Optional; 34 | 35 | public class SpongeSnapshotDeleteCommand implements CommandExecutor { 36 | 37 | @Inject 38 | private MemberManager memberManager; 39 | 40 | @Inject 41 | private PluginInfo pluginInfo; 42 | 43 | @Override 44 | public CommandResult execute(CommandSource source, CommandContext context) throws CommandException { 45 | SpongeSyncLockCommand.assertUnlocked(source); 46 | Optional optionalUser = context.getOne(Text.of("user")); 47 | if (!optionalUser.isPresent()) { 48 | throw new CommandException(Text.of(pluginInfo.getPrefix(), "User is required")); 49 | } 50 | memberManager.deleteSnapshot( 51 | optionalUser.get().getUniqueId(), 52 | context.getOne(Text.of("snapshot")).orElse(null) 53 | ).thenAcceptAsync(source::sendMessage); 54 | return CommandResult.success(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /datasync-sponge/src/main/java/org/anvilpowered/datasync/sponge/command/snapshot/SpongeSnapshotInfoCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.sponge.command.snapshot; 20 | 21 | import com.google.inject.Inject; 22 | import org.anvilpowered.anvil.api.plugin.PluginInfo; 23 | import org.anvilpowered.datasync.api.member.MemberManager; 24 | import org.spongepowered.api.command.CommandException; 25 | import org.spongepowered.api.command.CommandResult; 26 | import org.spongepowered.api.command.CommandSource; 27 | import org.spongepowered.api.command.args.CommandContext; 28 | import org.spongepowered.api.command.spec.CommandExecutor; 29 | import org.spongepowered.api.entity.living.player.User; 30 | import org.spongepowered.api.text.Text; 31 | 32 | import java.util.Optional; 33 | 34 | public class SpongeSnapshotInfoCommand implements CommandExecutor { 35 | 36 | @Inject 37 | private MemberManager memberManager; 38 | 39 | @Inject 40 | private PluginInfo pluginInfo; 41 | 42 | @Override 43 | public CommandResult execute(CommandSource source, CommandContext context) throws CommandException { 44 | Optional optionalUser = context.getOne(Text.of("user")); 45 | if (!optionalUser.isPresent()) { 46 | throw new CommandException(Text.of(pluginInfo.getPrefix(), "User is required")); 47 | } 48 | memberManager.info( 49 | optionalUser.get().getUniqueId(), 50 | context.getOne(Text.of("snapshot")).orElse(null) 51 | ).thenAcceptAsync(source::sendMessage); 52 | return CommandResult.success(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /datasync-sponge/src/main/java/org/anvilpowered/datasync/sponge/command/snapshot/SpongeSnapshotListCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.sponge.command.snapshot; 20 | 21 | import com.google.inject.Inject; 22 | import org.anvilpowered.datasync.api.member.MemberManager; 23 | import org.spongepowered.api.Sponge; 24 | import org.spongepowered.api.command.CommandException; 25 | import org.spongepowered.api.command.CommandResult; 26 | import org.spongepowered.api.command.CommandSource; 27 | import org.spongepowered.api.command.args.CommandContext; 28 | import org.spongepowered.api.command.spec.CommandExecutor; 29 | import org.spongepowered.api.entity.living.player.User; 30 | import org.spongepowered.api.service.pagination.PaginationList; 31 | import org.spongepowered.api.service.pagination.PaginationService; 32 | import org.spongepowered.api.text.Text; 33 | import org.spongepowered.api.text.format.TextColors; 34 | 35 | import java.util.Optional; 36 | 37 | public class SpongeSnapshotListCommand implements CommandExecutor { 38 | 39 | @Inject 40 | private MemberManager memberManager; 41 | 42 | @Override 43 | public CommandResult execute(CommandSource source, CommandContext context) throws CommandException { 44 | Optional optionalUser = context.getOne(Text.of("user")); 45 | if (!optionalUser.isPresent()) { 46 | throw new CommandException(Text.of("User is required")); 47 | } 48 | memberManager.list(optionalUser.get().getUniqueId()).thenAcceptAsync(list -> { 49 | Optional paginationService = Sponge.getServiceManager().provide(PaginationService.class); 50 | if (!paginationService.isPresent()) return; 51 | PaginationList.Builder paginationBuilder = 52 | paginationService.get() 53 | .builder() 54 | .title(Text.of(TextColors.GOLD, "Snapshots - ", optionalUser.get().getName())) 55 | .padding(Text.of(TextColors.DARK_GREEN, "-")) 56 | .contents(list).linesPerPage(20); 57 | paginationBuilder.build().sendTo(source); 58 | }); 59 | return CommandResult.success(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /datasync-sponge/src/main/java/org/anvilpowered/datasync/sponge/command/snapshot/SpongeSnapshotRestoreCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.sponge.command.snapshot; 20 | 21 | import com.google.inject.Inject; 22 | import org.anvilpowered.anvil.api.plugin.PluginInfo; 23 | import org.anvilpowered.datasync.api.serializer.user.UserSerializerManager; 24 | import org.anvilpowered.datasync.sponge.command.SpongeSyncLockCommand; 25 | import org.spongepowered.api.command.CommandException; 26 | import org.spongepowered.api.command.CommandResult; 27 | import org.spongepowered.api.command.CommandSource; 28 | import org.spongepowered.api.command.args.CommandContext; 29 | import org.spongepowered.api.command.spec.CommandExecutor; 30 | import org.spongepowered.api.entity.living.player.User; 31 | import org.spongepowered.api.text.Text; 32 | 33 | import java.util.Optional; 34 | 35 | public class SpongeSnapshotRestoreCommand implements CommandExecutor { 36 | 37 | @Inject 38 | private UserSerializerManager userSerializer; 39 | 40 | @Inject 41 | private PluginInfo pluginInfo; 42 | 43 | @Override 44 | public CommandResult execute(CommandSource source, CommandContext context) throws CommandException { 45 | SpongeSyncLockCommand.assertUnlocked(source); 46 | Optional optionalUser = context.getOne(Text.of("user")); 47 | if (!optionalUser.isPresent()) { 48 | throw new CommandException(Text.of(pluginInfo.getPrefix(), "User is required")); 49 | } 50 | userSerializer.restore( 51 | optionalUser.get().getUniqueId(), 52 | context.getOne(Text.of("snapshot")) 53 | .orElse(null) 54 | ).thenAcceptAsync(source::sendMessage); 55 | return CommandResult.success(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /datasync-sponge/src/main/java/org/anvilpowered/datasync/sponge/event/SerializerInitializationEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.sponge.event; 20 | 21 | import org.anvilpowered.datasync.api.serializer.SnapshotSerializer; 22 | import org.anvilpowered.datasync.api.snapshot.SnapshotManager; 23 | import org.spongepowered.api.data.key.Key; 24 | import org.spongepowered.api.entity.living.player.User; 25 | import org.spongepowered.api.event.cause.Cause; 26 | import org.spongepowered.api.event.impl.AbstractEvent; 27 | 28 | public class SerializerInitializationEvent extends AbstractEvent { 29 | 30 | private final Cause cause; 31 | private final SnapshotSerializer snapshotSerializer; 32 | private final SnapshotManager< Key> snapshotRepository; 33 | 34 | public SerializerInitializationEvent( 35 | SnapshotSerializer snapshotSerializer, 36 | SnapshotManager> snapshotRepository, 37 | Cause cause) { 38 | this.cause = cause; 39 | this.snapshotSerializer = snapshotSerializer; 40 | this.snapshotRepository = snapshotRepository; 41 | } 42 | 43 | @Override 44 | public Cause getCause() { 45 | return cause; 46 | } 47 | 48 | public SnapshotSerializer getSnapshotSerializer() { 49 | return snapshotSerializer; 50 | } 51 | 52 | public SnapshotManager> getSnapshotRepository() { 53 | return snapshotRepository; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /datasync-sponge/src/main/java/org/anvilpowered/datasync/sponge/keys/SpongeDataKeyService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.sponge.keys; 20 | 21 | import com.google.inject.Inject; 22 | import com.google.inject.Singleton; 23 | import org.anvilpowered.datasync.common.key.CommonDataKeyService; 24 | import org.spongepowered.api.data.key.Key; 25 | import org.spongepowered.api.data.key.Keys; 26 | 27 | @Singleton 28 | public class SpongeDataKeyService extends CommonDataKeyService> { 29 | 30 | @Inject 31 | public SpongeDataKeyService() { 32 | addMapping(Keys.FOOD_LEVEL, "food_level"); 33 | addMapping(Keys.SATURATION, "saturation"); 34 | addMapping(Keys.HEALTH, "health"); 35 | addMapping(Keys.TOTAL_EXPERIENCE, "total_experience"); 36 | addMapping(Keys.GAME_MODE, "game_mode"); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /datasync-sponge/src/main/java/org/anvilpowered/datasync/sponge/listener/SpongePlayerListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.sponge.listener; 20 | 21 | import com.google.inject.Inject; 22 | import com.google.inject.Singleton; 23 | import org.anvilpowered.anvil.api.plugin.PluginInfo; 24 | import org.anvilpowered.anvil.api.registry.Registry; 25 | import org.anvilpowered.datasync.api.registry.DataSyncKeys; 26 | import org.anvilpowered.datasync.api.serializer.user.UserSerializerManager; 27 | import org.anvilpowered.datasync.sponge.command.SpongeSyncLockCommand; 28 | import org.spongepowered.api.Sponge; 29 | import org.spongepowered.api.entity.living.player.Player; 30 | import org.spongepowered.api.entity.living.player.User; 31 | import org.spongepowered.api.event.Listener; 32 | import org.spongepowered.api.event.entity.DestructEntityEvent; 33 | import org.spongepowered.api.event.filter.Getter; 34 | import org.spongepowered.api.event.filter.cause.Root; 35 | import org.spongepowered.api.event.network.ClientConnectionEvent; 36 | import org.spongepowered.api.text.Text; 37 | import org.spongepowered.api.text.format.TextColors; 38 | 39 | @Singleton 40 | public class SpongePlayerListener { 41 | 42 | private Registry registry; 43 | 44 | @Inject 45 | private PluginInfo pluginInfo; 46 | 47 | @Inject 48 | private UserSerializerManager userSerializerManager; 49 | 50 | private boolean joinSerializationEnabled; 51 | private boolean disconnectSerializationEnabled; 52 | private boolean deathSerializationEnabled; 53 | 54 | @Inject 55 | public SpongePlayerListener(Registry registry) { 56 | this.registry = registry; 57 | registry.whenLoaded(this::registryLoaded).register(); 58 | } 59 | 60 | private void registryLoaded() { 61 | joinSerializationEnabled = registry.getOrDefault(DataSyncKeys.DESERIALIZE_ON_JOIN); 62 | if (!joinSerializationEnabled) { 63 | sendWarning("serialize.deserializeOnJoin"); 64 | } 65 | disconnectSerializationEnabled = registry.getOrDefault(DataSyncKeys.SERIALIZE_ON_DISCONNECT); 66 | if (!disconnectSerializationEnabled) { 67 | sendWarning("serialize.serializeOnDisconnect"); 68 | } 69 | deathSerializationEnabled = registry.getOrDefault(DataSyncKeys.SERIALIZE_ON_DEATH); 70 | if (!deathSerializationEnabled) { 71 | sendWarning("serialize.serializeOnDeath"); 72 | } 73 | } 74 | 75 | private void sendWarning(String name) { 76 | Sponge.getServer().getConsole().sendMessage( 77 | Text.of(pluginInfo.getPrefix(), TextColors.RED, 78 | "Attention! You have opted to disable ", name, ".\n" + 79 | "If you would like to enable this, set `", name, "=true` in the config and restart your server or run /sync reload") 80 | ); 81 | } 82 | 83 | @Listener 84 | public void onPlayerJoin(ClientConnectionEvent.Join joinEvent, @Root Player player) { 85 | if (joinSerializationEnabled) { 86 | userSerializerManager.deserializeJoin(player) 87 | .thenAcceptAsync(Sponge.getServer().getConsole()::sendMessage); 88 | } 89 | } 90 | 91 | @Listener 92 | public void onPlayerDisconnect(ClientConnectionEvent.Disconnect disconnectEvent, 93 | @Root Player player) { 94 | SpongeSyncLockCommand.lockPlayer(player); 95 | if (disconnectSerializationEnabled) { 96 | userSerializerManager.serializeSafe(player, "Disconnect") 97 | .thenAcceptAsync(Sponge.getServer().getConsole()::sendMessage); 98 | } 99 | } 100 | 101 | @Listener 102 | public void onPlayerDeath(DestructEntityEvent.Death deathEvent, 103 | @Getter("getTargetEntity") Player player) { 104 | if (deathSerializationEnabled) { 105 | userSerializerManager.serializeSafe(player, "Death") 106 | .thenAcceptAsync(Sponge.getServer().getConsole()::sendMessage); 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /datasync-sponge/src/main/java/org/anvilpowered/datasync/sponge/module/SpongeModule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.sponge.module; 20 | 21 | import com.google.inject.TypeLiteral; 22 | import dev.morphia.Datastore; 23 | import jetbrains.exodus.entitystore.EntityId; 24 | import jetbrains.exodus.entitystore.PersistentEntityStore; 25 | import org.anvilpowered.anvil.api.command.CommandNode; 26 | import org.anvilpowered.datasync.api.key.DataKeyService; 27 | import org.anvilpowered.datasync.api.serializer.ExperienceSerializer; 28 | import org.anvilpowered.datasync.api.serializer.GameModeSerializer; 29 | import org.anvilpowered.datasync.api.serializer.HealthSerializer; 30 | import org.anvilpowered.datasync.api.serializer.HungerSerializer; 31 | import org.anvilpowered.datasync.api.serializer.InventorySerializer; 32 | import org.anvilpowered.datasync.api.serializer.SnapshotSerializer; 33 | import org.anvilpowered.datasync.api.task.SerializationTaskService; 34 | import org.anvilpowered.datasync.common.module.CommonModule; 35 | import org.anvilpowered.datasync.common.registry.CommonConfigurationService; 36 | import org.anvilpowered.datasync.common.serializer.user.CommonUserSerializerComponent; 37 | import org.anvilpowered.datasync.common.snapshotoptimization.CommonSnapshotOptimizationService; 38 | import org.anvilpowered.datasync.sponge.command.SpongeSyncCommandNode; 39 | import org.anvilpowered.datasync.sponge.keys.SpongeDataKeyService; 40 | import org.anvilpowered.datasync.sponge.registry.SpongeConfigurationService; 41 | import org.anvilpowered.datasync.sponge.serializer.SpongeExperienceSerializer; 42 | import org.anvilpowered.datasync.sponge.serializer.SpongeGameModeSerializer; 43 | import org.anvilpowered.datasync.sponge.serializer.SpongeHealthSerializer; 44 | import org.anvilpowered.datasync.sponge.serializer.SpongeHungerSerializer; 45 | import org.anvilpowered.datasync.sponge.serializer.SpongeInventorySerializer; 46 | import org.anvilpowered.datasync.sponge.serializer.SpongeSnapshotSerializer; 47 | import org.anvilpowered.datasync.sponge.serializer.user.SpongeUserSerializerComponent; 48 | import org.anvilpowered.datasync.sponge.snapshotoptimization.SpongeSnapshotOptimizationService; 49 | import org.anvilpowered.datasync.sponge.task.SpongeSerializationTaskService; 50 | import org.bson.types.ObjectId; 51 | import org.spongepowered.api.command.CommandSource; 52 | import org.spongepowered.api.data.key.Key; 53 | import org.spongepowered.api.entity.living.player.Player; 54 | import org.spongepowered.api.entity.living.player.User; 55 | import org.spongepowered.api.item.inventory.Inventory; 56 | import org.spongepowered.api.item.inventory.ItemStackSnapshot; 57 | import org.spongepowered.api.text.Text; 58 | 59 | public class SpongeModule extends CommonModule< 60 | Key, 61 | Player, 62 | User, 63 | Text, 64 | CommandSource> { 65 | 66 | @Override 67 | protected void configure() { 68 | super.configure(); 69 | 70 | bind(CommonConfigurationService.class).to(SpongeConfigurationService.class); 71 | 72 | bind(new TypeLiteral>() { 73 | }).to(SpongeExperienceSerializer.class); 74 | bind(new TypeLiteral>() { 75 | }).to(SpongeGameModeSerializer.class); 76 | bind(new TypeLiteral>() { 77 | }).to(SpongeHealthSerializer.class); 78 | bind(new TypeLiteral>() { 79 | }).to(SpongeHealthSerializer.class); 80 | bind(new TypeLiteral>() { 81 | }).to(SpongeHungerSerializer.class); 82 | bind(new TypeLiteral>() { 83 | }).to(SpongeInventorySerializer.class); 84 | bind(new TypeLiteral>() { 85 | }).to(SpongeSnapshotSerializer.class); 86 | bind(new TypeLiteral>>() { 87 | }).to(SpongeDataKeyService.class); 88 | bind(SerializationTaskService.class).to(SpongeSerializationTaskService.class); 89 | 90 | bind(new TypeLiteral, Datastore>>() { 91 | }).to(new TypeLiteral>() { 92 | }); 93 | 94 | bind(new TypeLiteral, PersistentEntityStore>>() { 95 | }).to(new TypeLiteral>() { 96 | }); 97 | 98 | bind(new TypeLiteral, Datastore>>() { 99 | }).to(new TypeLiteral>() { 100 | }); 101 | 102 | bind(new TypeLiteral, PersistentEntityStore>>() { 103 | }).to(new TypeLiteral>() { 104 | }); 105 | 106 | bind(new TypeLiteral>() { 107 | }).to(SpongeSyncCommandNode.class); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /datasync-sponge/src/main/java/org/anvilpowered/datasync/sponge/registry/SpongeConfigurationService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.sponge.registry; 20 | 21 | import com.google.inject.Inject; 22 | import com.google.inject.Singleton; 23 | import ninja.leaping.configurate.commented.CommentedConfigurationNode; 24 | import ninja.leaping.configurate.loader.ConfigurationLoader; 25 | import org.anvilpowered.datasync.common.registry.CommonConfigurationService; 26 | import org.spongepowered.api.config.DefaultConfig; 27 | 28 | @Singleton 29 | public class SpongeConfigurationService extends CommonConfigurationService { 30 | 31 | @Inject 32 | public SpongeConfigurationService( 33 | @DefaultConfig(sharedRoot = false) 34 | ConfigurationLoader configLoader) { 35 | super(configLoader); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /datasync-sponge/src/main/java/org/anvilpowered/datasync/sponge/serializer/SpongeExperienceSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.sponge.serializer; 20 | 21 | import org.anvilpowered.datasync.api.model.snapshot.Snapshot; 22 | import org.anvilpowered.datasync.common.serializer.CommonExperienceSerializer; 23 | import org.anvilpowered.datasync.sponge.util.Utils; 24 | import org.spongepowered.api.data.key.Key; 25 | import org.spongepowered.api.data.key.Keys; 26 | import org.spongepowered.api.entity.living.player.User; 27 | 28 | public class SpongeExperienceSerializer extends CommonExperienceSerializer, User> { 29 | 30 | @Override 31 | public boolean serialize(Snapshot snapshot, User user) { 32 | return Utils.serialize(snapshotManager, snapshot, user, Keys.TOTAL_EXPERIENCE); 33 | } 34 | 35 | @Override 36 | public boolean deserialize(Snapshot snapshot, User user) { 37 | return Utils.deserialize(snapshotManager, snapshot, user, Keys.TOTAL_EXPERIENCE); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /datasync-sponge/src/main/java/org/anvilpowered/datasync/sponge/serializer/SpongeGameModeSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.sponge.serializer; 20 | 21 | import org.anvilpowered.datasync.api.model.snapshot.Snapshot; 22 | import org.anvilpowered.datasync.common.serializer.CommonGameModeSerializer; 23 | import org.anvilpowered.datasync.sponge.util.Utils; 24 | import org.spongepowered.api.data.key.Key; 25 | import org.spongepowered.api.data.key.Keys; 26 | import org.spongepowered.api.entity.living.player.User; 27 | 28 | public class SpongeGameModeSerializer extends CommonGameModeSerializer, User> { 29 | 30 | @Override 31 | public boolean serialize(Snapshot snapshot, User user) { 32 | return Utils.serialize(snapshotManager, snapshot, user, Keys.GAME_MODE); 33 | } 34 | 35 | @Override 36 | public boolean deserialize(Snapshot snapshot, User user) { 37 | return Utils.deserialize(snapshotManager, snapshot, user, Keys.GAME_MODE); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /datasync-sponge/src/main/java/org/anvilpowered/datasync/sponge/serializer/SpongeHealthSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.sponge.serializer; 20 | 21 | import org.anvilpowered.datasync.api.model.snapshot.Snapshot; 22 | import org.anvilpowered.datasync.common.serializer.CommonHealthSerializer; 23 | import org.anvilpowered.datasync.sponge.util.Utils; 24 | import org.spongepowered.api.data.key.Key; 25 | import org.spongepowered.api.data.key.Keys; 26 | import org.spongepowered.api.entity.living.player.User; 27 | 28 | import java.util.Optional; 29 | 30 | public class SpongeHealthSerializer extends CommonHealthSerializer, User> { 31 | 32 | @Override 33 | public boolean serialize(Snapshot snapshot, User user) { 34 | Optional health = user.get(Keys.HEALTH).flatMap(h -> { 35 | if (h <= 0) { 36 | return user.get(Keys.MAX_HEALTH); 37 | } else { 38 | return Optional.of(h); 39 | } 40 | }); 41 | return snapshotManager.getPrimaryComponent() 42 | .setSnapshotValue(snapshot, Keys.HEALTH, health); 43 | } 44 | 45 | @Override 46 | public boolean deserialize(Snapshot snapshot, User user) { 47 | return Utils.deserialize(snapshotManager, snapshot, user, Keys.HEALTH); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /datasync-sponge/src/main/java/org/anvilpowered/datasync/sponge/serializer/SpongeHungerSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.sponge.serializer; 20 | 21 | import org.anvilpowered.datasync.api.model.snapshot.Snapshot; 22 | import org.anvilpowered.datasync.common.serializer.CommonHungerSerializer; 23 | import org.anvilpowered.datasync.sponge.util.Utils; 24 | import org.spongepowered.api.data.key.Key; 25 | import org.spongepowered.api.data.key.Keys; 26 | import org.spongepowered.api.entity.living.player.User; 27 | 28 | public class SpongeHungerSerializer extends CommonHungerSerializer, User> { 29 | 30 | @Override 31 | public boolean serialize(Snapshot snapshot, User user) { 32 | // second statement should still run if first one fails 33 | boolean a = Utils.serialize(snapshotManager, snapshot, user, Keys.FOOD_LEVEL); 34 | boolean b = Utils.serialize(snapshotManager, snapshot, user, Keys.SATURATION); 35 | return a && b; 36 | } 37 | 38 | @Override 39 | public boolean deserialize(Snapshot snapshot, User user) { 40 | // second statement should still run if first one fails 41 | boolean a = Utils.deserialize(snapshotManager, snapshot, user, Keys.FOOD_LEVEL); 42 | boolean b = Utils.deserialize(snapshotManager, snapshot, user, Keys.SATURATION); 43 | return a && b; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /datasync-sponge/src/main/java/org/anvilpowered/datasync/sponge/serializer/SpongeSnapshotSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.sponge.serializer; 20 | 21 | import com.google.inject.Inject; 22 | import com.google.inject.Singleton; 23 | import org.anvilpowered.anvil.api.plugin.PluginInfo; 24 | import org.anvilpowered.anvil.api.registry.Registry; 25 | import org.anvilpowered.datasync.common.serializer.CommonSnapshotSerializer; 26 | import org.anvilpowered.datasync.sponge.DataSyncSponge; 27 | import org.anvilpowered.datasync.sponge.event.SerializerInitializationEvent; 28 | import org.spongepowered.api.Sponge; 29 | import org.spongepowered.api.data.key.Key; 30 | import org.spongepowered.api.entity.living.player.Player; 31 | import org.spongepowered.api.entity.living.player.User; 32 | import org.spongepowered.api.event.cause.Cause; 33 | import org.spongepowered.api.event.cause.EventContext; 34 | import org.spongepowered.api.event.cause.EventContextKeys; 35 | import org.spongepowered.api.item.inventory.Inventory; 36 | import org.spongepowered.api.item.inventory.ItemStackSnapshot; 37 | import org.spongepowered.api.text.Text; 38 | import org.spongepowered.api.text.format.TextColors; 39 | 40 | @Singleton 41 | public class SpongeSnapshotSerializer extends CommonSnapshotSerializer, User, Player, Inventory, ItemStackSnapshot> { 42 | 43 | @Inject 44 | public SpongeSnapshotSerializer(Registry registry) { 45 | super(registry); 46 | } 47 | 48 | @Inject 49 | private PluginInfo pluginInfo; 50 | 51 | @Inject 52 | private DataSyncSponge dataSyncSponge; 53 | 54 | @Override 55 | protected void postLoadedEvent() { 56 | Sponge.getPluginManager().fromInstance(dataSyncSponge).ifPresent(container -> { 57 | EventContext eventContext 58 | = EventContext.builder().add(EventContextKeys.PLUGIN, container).build(); 59 | Sponge.getEventManager().post(new SerializerInitializationEvent(this, 60 | snapshotManager, Cause.of(eventContext, dataSyncSponge))); 61 | }); 62 | } 63 | 64 | @Override 65 | protected void announceEnabled(String name) { 66 | Sponge.getServer().getConsole().sendMessage( 67 | Text.of(pluginInfo.getPrefix(), TextColors.YELLOW, "Enabling ", name, " serializer") 68 | ); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /datasync-sponge/src/main/java/org/anvilpowered/datasync/sponge/serializer/user/SpongeUserSerializerComponent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.sponge.serializer.user; 20 | 21 | import com.google.inject.Inject; 22 | import org.anvilpowered.datasync.api.model.snapshot.Snapshot; 23 | import org.anvilpowered.datasync.api.registry.DataSyncKeys; 24 | import org.anvilpowered.datasync.api.snapshotoptimization.SnapshotOptimizationManager; 25 | import org.anvilpowered.datasync.common.serializer.user.CommonUserSerializerComponent; 26 | import org.spongepowered.api.command.CommandSource; 27 | import org.spongepowered.api.data.key.Key; 28 | import org.spongepowered.api.entity.living.player.Player; 29 | import org.spongepowered.api.entity.living.player.User; 30 | import org.spongepowered.api.plugin.PluginContainer; 31 | import org.spongepowered.api.scheduler.Task; 32 | import org.spongepowered.api.text.Text; 33 | 34 | import java.util.Optional; 35 | import java.util.concurrent.CompletableFuture; 36 | 37 | public class SpongeUserSerializerComponent< 38 | TKey, 39 | TDataStore> 40 | extends CommonUserSerializerComponent, TDataStore> { 41 | 42 | @Inject 43 | private PluginContainer pluginContainer; 44 | 45 | @Inject 46 | private SnapshotOptimizationManager snapshotOptimizationManager; 47 | 48 | @Override 49 | public boolean deserialize(Snapshot snapshot, User user) { 50 | CompletableFuture result = new CompletableFuture<>(); 51 | Task.builder().execute(() -> 52 | result.complete(snapshotSerializer.deserialize(snapshot, user)) 53 | ).submit(pluginContainer); 54 | return result.join(); 55 | } 56 | 57 | @Override 58 | public CompletableFuture>> deserialize(User user, CompletableFuture waitFuture) { 59 | snapshotOptimizationManager.getPrimaryComponent().addLockedPlayer(user.getUniqueId()); 60 | // save current user data 61 | Snapshot previousState = snapshotRepository.generateEmpty(); 62 | serialize(previousState, user); 63 | if (registry.getOrDefault(DataSyncKeys.SERIALIZE_ENABLED_SERIALIZERS) 64 | .contains("datasync:inventory")) { 65 | user.getInventory().clear(); 66 | } 67 | return waitFuture.thenApplyAsync(shouldDeserialize -> { 68 | if (!shouldDeserialize) { 69 | return Optional.>empty(); 70 | } 71 | return memberRepository.getLatestSnapshotForUser(user.getUniqueId()) 72 | .exceptionally(e -> { 73 | e.printStackTrace(); 74 | return Optional.empty(); 75 | }) 76 | .thenApplyAsync(optionalSnapshot -> { 77 | // make sure user is still online 78 | if (!user.isOnline()) { 79 | logger.warn("{} has logged off. Skipping deserialization!", user.getName()); 80 | return Optional.>empty(); 81 | } 82 | if (!optionalSnapshot.isPresent()) { 83 | logger.warn("Could not find snapshot for " + user.getName() + "! " + 84 | "Check your DB configuration! Rolling back user."); 85 | deserialize(previousState, user); 86 | return Optional.>empty(); 87 | } 88 | if (deserialize(optionalSnapshot.get(), user)) { 89 | return optionalSnapshot; 90 | } 91 | return Optional.>empty(); 92 | }).join(); 93 | }).thenApplyAsync(s -> { 94 | snapshotOptimizationManager.getPrimaryComponent() 95 | .removeLockedPlayer(user.getUniqueId()); 96 | return s; 97 | }); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /datasync-sponge/src/main/java/org/anvilpowered/datasync/sponge/task/SpongeSerializationTaskService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.sponge.task; 20 | 21 | import com.google.inject.Inject; 22 | import com.google.inject.Singleton; 23 | import org.anvilpowered.anvil.api.plugin.PluginInfo; 24 | import org.anvilpowered.anvil.api.registry.Registry; 25 | import org.anvilpowered.datasync.common.task.CommonSerializationTaskService; 26 | import org.spongepowered.api.Sponge; 27 | import org.spongepowered.api.command.CommandSource; 28 | import org.spongepowered.api.entity.living.player.User; 29 | import org.spongepowered.api.plugin.PluginContainer; 30 | import org.spongepowered.api.scheduler.Task; 31 | import org.spongepowered.api.text.Text; 32 | import org.spongepowered.api.text.format.TextColors; 33 | 34 | import java.util.concurrent.TimeUnit; 35 | 36 | @Singleton 37 | public class SpongeSerializationTaskService extends CommonSerializationTaskService { 38 | 39 | @Inject 40 | private PluginContainer pluginContainer; 41 | 42 | @Inject 43 | private PluginInfo pluginInfo; 44 | 45 | private Task task = null; 46 | 47 | @Inject 48 | public SpongeSerializationTaskService(Registry registry) { 49 | super(registry); 50 | } 51 | 52 | @Override 53 | public void startSerializationTask() { 54 | if (baseInterval > 0) { 55 | Sponge.getServer().getConsole().sendMessage(Text.of(pluginInfo.getPrefix(), 56 | TextColors.YELLOW, "Submitting sync task! Upload interval: ", 57 | baseInterval, " minutes")); 58 | task = Task.builder().async().interval(30, TimeUnit.SECONDS) 59 | .execute(getSerializationTask()).submit(pluginContainer); 60 | } else { 61 | Sponge.getServer().getConsole().sendMessage(Text.of(pluginInfo.getPrefix(), 62 | TextColors.RED, "Sync task has been disabled from config!")); 63 | } 64 | } 65 | 66 | @Override 67 | public void stopSerializationTask() { 68 | if (task != null) task.cancel(); 69 | } 70 | 71 | @Override 72 | public Runnable getSerializationTask() { 73 | return () -> { 74 | if (snapshotOptimizationManager.getPrimaryComponent().isOptimizationTaskRunning()) { 75 | Sponge.getServer().getConsole() 76 | .sendMessage(Text.of(pluginInfo.getPrefix(), 77 | TextColors.RED, "Optimization task already running! Task will skip")); 78 | } else { 79 | snapshotOptimizationManager.getPrimaryComponent() 80 | .optimize( 81 | Sponge.getServer().getOnlinePlayers(), 82 | Sponge.getServer().getConsole(), 83 | "Auto" 84 | ); 85 | } 86 | }; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /datasync-sponge/src/main/java/org/anvilpowered/datasync/sponge/util/Utils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package org.anvilpowered.datasync.sponge.util; 20 | 21 | import com.google.common.reflect.TypeToken; 22 | import org.anvilpowered.datasync.api.model.snapshot.Snapshot; 23 | import org.anvilpowered.datasync.api.snapshot.SnapshotManager; 24 | import org.spongepowered.api.data.key.Key; 25 | import org.spongepowered.api.data.value.BaseValue; 26 | import org.spongepowered.api.entity.living.player.User; 27 | import org.spongepowered.api.entity.living.player.gamemode.GameMode; 28 | import org.spongepowered.api.entity.living.player.gamemode.GameModes; 29 | 30 | import java.util.Optional; 31 | 32 | public class Utils { 33 | 34 | public static boolean serialize(SnapshotManager> snapshotManager, 35 | Snapshot snapshot, User user, 36 | Key> key) { 37 | return snapshotManager.getPrimaryComponent() 38 | .setSnapshotValue(snapshot, key, user.get(key)); 39 | } 40 | 41 | public static boolean deserialize(SnapshotManager< Key> snapshotManager, 42 | Snapshot snapshot, User user, 43 | Key> key) { 44 | Optional optionalSnapshot = snapshotManager.getPrimaryComponent() 45 | .getSnapshotValue(snapshot, key); 46 | if (!optionalSnapshot.isPresent()) { 47 | return false; 48 | } 49 | 50 | try { 51 | user.offer(key, (E) decode(optionalSnapshot.get(), key)); 52 | return true; 53 | } catch (Exception e) { 54 | e.printStackTrace(); 55 | return false; 56 | } 57 | } 58 | 59 | private static Object decode(Object value, Key> key) { 60 | TypeToken typeToken = key.getElementToken(); 61 | 62 | if (typeToken.isSubtypeOf(GameMode.class)) { 63 | switch (value.toString()) { 64 | case "ADVENTURE": 65 | return GameModes.ADVENTURE; 66 | case "CREATIVE": 67 | return GameModes.CREATIVE; 68 | case "SPECTATOR": 69 | return GameModes.SPECTATOR; 70 | case "SURVIVAL": 71 | return GameModes.SURVIVAL; 72 | // "NOT_SET" 73 | default: 74 | return GameModes.NOT_SET; 75 | } 76 | } 77 | return value; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /datasync-sponge/src/test/java/rocks/milspecsg/msdatasync/tests/ExampleTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * DataSync - AnvilPowered 3 | * Copyright (C) 2020 Cableguy20 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU Lesser General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package rocks.milspecsg.msdatasync.tests; 20 | 21 | import org.junit.jupiter.api.Test; 22 | 23 | public class ExampleTests { 24 | 25 | @Test 26 | void exampleTest() { 27 | System.out.println("Starting example test..."); 28 | System.out.println("Finished!"); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # dependencies 2 | aopalliance=aopalliance:aopalliance:1.0 3 | beanutils=commons-beanutils:commons-beanutils:1.9.2 4 | bson=org.mongodb:bson:3.12.0 5 | bungee=net.md-5:bungeecord-api:1.14-SNAPSHOT 6 | configurate_core=org.spongepowered:configurate-core:3.6 7 | configurate_hocon=org.spongepowered:configurate-hocon:3.6 8 | guava=com.google.guava:guava:28.1-jre 9 | guice=com.google.inject:guice:4.1.0 10 | h2=com.h2database:h2-mvstore:1.4.200 11 | jackson_annotations=com.fasterxml.jackson.core:jackson-annotations:2.9.9 12 | jackson_core=com.fasterxml.jackson.core:jackson-core:2.9.9 13 | jackson_databind=com.fasterxml.jackson.core:jackson-databind:2.9.9 14 | jasypt=org.jasypt:jasypt:1.9.2 15 | javasisst=org.javassist:javassist:3.26.0-GA 16 | jsondb=com.github.Jsondb:jsondb-core:-SNAPSHOT 17 | javax=javax.inject:javax.inject:1 18 | jxpath=commons-jxpath:commons-jxpath:1.3 19 | mongo_java_driver=org.mongodb:mongo-java-driver:3.11.0 20 | mongodb_driver_sync=org.mongodb:mongodb-driver-sync:3.11.0 21 | morphia=org.mongodb.morphia:morphia:1.3.2 22 | microutils_logging=io.github.microutils:kotlin-logging:1.5.4 23 | nitrite=org.dizitart:nitrite:3.3.0 24 | objenesis=org.objenesis:objenesis:3.1 25 | okhttp3=com.squareup.okhttp3:okhttp:3.9.1 26 | podam=uk.co.jemos.podam:podam:7.1.0.RELEASE 27 | reflections=org.reflections:reflections:0.9.10 28 | typesafe_config=com.typesafe:config:1.4.0 29 | xodus=org.jetbrains.xodus:xodus-openAPI:1.3.124 30 | xodus_compress=org.jetbrains.xodus:xodus-compress:1.3.124 31 | xodus_entity_store=org.jetbrains.xodus:xodus-entity-store:1.3.124 32 | xodus_environment=org.jetbrains.xodus:xodus-environment:1.3.124 33 | xodus_utils=org.jetbrains.xodus:xodus-utils:1.3.124 34 | xodus_vfs=org.jetbrains.xodus:xodus-vfs:1.3.124 35 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anvilpowered/datasync/35954be1a7ac7a52f3745180dd92006c4b5bcf5d/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Feb 01 14:06:59 CET 2020 2 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip 3 | distributionBase=GRADLE_USER_HOME 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | # Determine the Java command to use to start the JVM. 86 | if [ -n "$JAVA_HOME" ] ; then 87 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 88 | # IBM's JDK on AIX uses strange locations for the executables 89 | JAVACMD="$JAVA_HOME/jre/sh/java" 90 | else 91 | JAVACMD="$JAVA_HOME/bin/java" 92 | fi 93 | if [ ! -x "$JAVACMD" ] ; then 94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 95 | 96 | Please set the JAVA_HOME variable in your environment to match the 97 | location of your Java installation." 98 | fi 99 | else 100 | JAVACMD="java" 101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 102 | 103 | Please set the JAVA_HOME variable in your environment to match the 104 | location of your Java installation." 105 | fi 106 | 107 | # Increase the maximum file descriptors if we can. 108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 109 | MAX_FD_LIMIT=`ulimit -H -n` 110 | if [ $? -eq 0 ] ; then 111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 112 | MAX_FD="$MAX_FD_LIMIT" 113 | fi 114 | ulimit -n $MAX_FD 115 | if [ $? -ne 0 ] ; then 116 | warn "Could not set maximum file descriptor limit: $MAX_FD" 117 | fi 118 | else 119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 120 | fi 121 | fi 122 | 123 | # For Darwin, add options to specify how the application appears in the dock 124 | if $darwin; then 125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 126 | fi 127 | 128 | # For Cygwin or MSYS, switch paths to Windows format before running java 129 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 130 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 131 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 132 | JAVACMD=`cygpath --unix "$JAVACMD"` 133 | 134 | # We build the pattern for arguments to be converted via cygpath 135 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 136 | SEP="" 137 | for dir in $ROOTDIRSRAW ; do 138 | ROOTDIRS="$ROOTDIRS$SEP$dir" 139 | SEP="|" 140 | done 141 | OURCYGPATTERN="(^($ROOTDIRS))" 142 | # Add a user-defined pattern to the cygpath arguments 143 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 144 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 145 | fi 146 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 147 | i=0 148 | for arg in "$@" ; do 149 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 150 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 151 | 152 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 153 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 154 | else 155 | eval `echo args$i`="\"$arg\"" 156 | fi 157 | i=`expr $i + 1` 158 | done 159 | case $i in 160 | 0) set -- ;; 161 | 1) set -- "$args0" ;; 162 | 2) set -- "$args0" "$args1" ;; 163 | 3) set -- "$args0" "$args1" "$args2" ;; 164 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 165 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 166 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 167 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 168 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 169 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 170 | esac 171 | fi 172 | 173 | # Escape application args 174 | save () { 175 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 176 | echo " " 177 | } 178 | APP_ARGS=`save "$@"` 179 | 180 | # Collect all arguments for the java command, following the shell quoting and substitution rules 181 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 182 | 183 | exec "$JAVACMD" "$@" 184 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 33 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 34 | 35 | @rem Find java.exe 36 | if defined JAVA_HOME goto findJavaFromJavaHome 37 | 38 | set JAVA_EXE=java.exe 39 | %JAVA_EXE% -version >NUL 2>&1 40 | if "%ERRORLEVEL%" == "0" goto init 41 | 42 | echo. 43 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 44 | echo. 45 | echo Please set the JAVA_HOME variable in your environment to match the 46 | echo location of your Java installation. 47 | 48 | goto fail 49 | 50 | :findJavaFromJavaHome 51 | set JAVA_HOME=%JAVA_HOME:"=% 52 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 53 | 54 | if exist "%JAVA_EXE%" goto init 55 | 56 | echo. 57 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 58 | echo. 59 | echo Please set the JAVA_HOME variable in your environment to match the 60 | echo location of your Java installation. 61 | 62 | goto fail 63 | 64 | :init 65 | @rem Get command-line arguments, handling Windows variants 66 | 67 | if not "%OS%" == "Windows_NT" goto win9xME_args 68 | 69 | :win9xME_args 70 | @rem Slurp the command line arguments. 71 | set CMD_LINE_ARGS= 72 | set _SKIP=2 73 | 74 | :win9xME_args_slurp 75 | if "x%~1" == "x" goto execute 76 | 77 | set CMD_LINE_ARGS=%* 78 | 79 | :execute 80 | @rem Setup the command line 81 | 82 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 83 | 84 | @rem Execute Gradle 85 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 86 | 87 | :end 88 | @rem End local scope for the variables with windows NT shell 89 | if "%ERRORLEVEL%"=="0" goto mainEnd 90 | 91 | :fail 92 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 93 | rem the _cmd.exe /c_ return code! 94 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 95 | exit /b 1 96 | 97 | :mainEnd 98 | if "%OS%"=="Windows_NT" endlocal 99 | 100 | :omega 101 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anvilpowered/datasync/35954be1a7ac7a52f3745180dd92006c4b5bcf5d/icon.png -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'DataSync' 2 | include 'datasync-api' 3 | include 'datasync-common' 4 | include 'datasync-sponge' 5 | --------------------------------------------------------------------------------