Compare commits
20 commits
Author | SHA1 | Date | |
---|---|---|---|
5c8db873c6 | |||
bddc380f8f | |||
307b3427e8 | |||
44eb9d1d9c | |||
19b122990c | |||
a005e2d0ef | |||
472b117f70 | |||
a9dfaa546c | |||
93899a86d1 | |||
d86f5b87f1 | |||
21a40835b5 | |||
792898135d | |||
15bca9670b | |||
e4b59167f6 | |||
1c27c3da01 | |||
2715c3fbb5 | |||
8319cd850a | |||
dabc717bd4 | |||
275288447f | |||
55acbd4868 |
156 changed files with 9938 additions and 1188 deletions
51
Jenkinsfile
vendored
Normal file
51
Jenkinsfile
vendored
Normal file
|
@ -0,0 +1,51 @@
|
|||
pipeline {
|
||||
agent any
|
||||
|
||||
options {
|
||||
buildDiscarder(
|
||||
logRotator(
|
||||
numToKeepStr: '5'
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
stages {
|
||||
stage("Build on Linux") {
|
||||
agent {
|
||||
label 'linux'
|
||||
}
|
||||
|
||||
tools {
|
||||
jdk "jdk17"
|
||||
}
|
||||
|
||||
steps {
|
||||
script {
|
||||
sh '''
|
||||
#!/bin/bash
|
||||
|
||||
git clean -xfd
|
||||
git reset --hard
|
||||
git fetch
|
||||
export JAVA_OPTS=-Dfile.encoding=UTF-8
|
||||
|
||||
java -version
|
||||
|
||||
chmod +x gradlew
|
||||
./gradlew -Dorg.gradle.java.home="$JAVA_HOME" build publish
|
||||
|
||||
'''
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
archiveArtifacts artifacts: "build/libs/*.jar"
|
||||
deleteDir()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -12,4 +12,4 @@ If the mod becomes widely used, I will begin using deprecation notices.
|
|||
Compatibility
|
||||
=====
|
||||
|
||||
1) Lightman's Currency
|
||||
1) Lightman's Currency (possible future compatibility)
|
61
build.gradle
61
build.gradle
|
@ -2,7 +2,6 @@ plugins {
|
|||
id 'eclipse'
|
||||
id 'idea'
|
||||
id 'maven-publish'
|
||||
id 'java-library'
|
||||
id 'net.minecraftforge.gradle' version '[6.0,6.2)'
|
||||
id 'org.parchmentmc.librarian.forgegradle' version '1.+'
|
||||
}
|
||||
|
@ -20,11 +19,6 @@ java {
|
|||
withJavadocJar()
|
||||
}
|
||||
|
||||
configurations {
|
||||
provided
|
||||
compile.extendsFrom(provided)
|
||||
}
|
||||
|
||||
// Mojang ships Java 17 to end users in 1.18+, so your mod should target Java 17.
|
||||
java.toolchain.languageVersion = JavaLanguageVersion.of(17)
|
||||
|
||||
|
@ -39,16 +33,17 @@ minecraft {
|
|||
// See more information here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md
|
||||
//
|
||||
// Parchment is an unofficial project maintained by ParchmentMC, separate from MinecraftForge
|
||||
// Additional setup is needed to use their mappings: https://parchmentmc.org/docs/getting-started
|
||||
// Additional setup is needed to use their mappings: https://github.com/ParchmentMC/Parchment/wiki/Getting-Started
|
||||
//
|
||||
// Use non-default mappings at your own risk. They may not always work.
|
||||
// Simply re-run your setup task after changing the mappings to update your workspace.
|
||||
mappings channel: mapping_channel, version: mapping_version
|
||||
//mappings channel: mapping_channel, version: "${parchment_version}-${minecraft_version}"
|
||||
mappings channel: mapping_channel, version: "${minecraft_version}"
|
||||
|
||||
// When true, this property will have all Eclipse/IntelliJ IDEA run configurations run the "prepareX" task for the given run configuration before launching the game.
|
||||
// In most cases, it is not necessary to enable.
|
||||
// enableEclipsePrepareRuns = true
|
||||
// enableIdeaPrepareRuns = true
|
||||
enableEclipsePrepareRuns = true
|
||||
enableIdeaPrepareRuns = true
|
||||
|
||||
// This property allows configuring Gradle's ProcessResources task(s) to run on IDE output locations before launching the game.
|
||||
// It is REQUIRED to be set to true for this template to function.
|
||||
|
@ -58,7 +53,7 @@ minecraft {
|
|||
// When true, this property will add the folder name of all declared run configurations to generated IDE run configurations.
|
||||
// The folder name can be set on a run configuration using the "folderName" property.
|
||||
// By default, the folder name of a run configuration is the name of the Gradle project containing it.
|
||||
// generateRunFolders = true
|
||||
generateRunFolders = true
|
||||
|
||||
// This property enables access transformers for use in development.
|
||||
// They will be applied to the Minecraft artifact.
|
||||
|
@ -66,7 +61,7 @@ minecraft {
|
|||
// However, it must be at "META-INF/accesstransformer.cfg" in the final mod jar to be loaded by Forge.
|
||||
// This default location is a best practice to automatically put the file in the right place in the final jar.
|
||||
// See https://docs.minecraftforge.net/en/latest/advanced/accesstransformers/ for more information.
|
||||
// accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
|
||||
accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
|
||||
|
||||
// Default run configurations.
|
||||
// These can be tweaked, removed, or duplicated as needed.
|
||||
|
@ -87,6 +82,9 @@ minecraft {
|
|||
// Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels
|
||||
property 'forge.logging.console.level', 'debug'
|
||||
|
||||
// Comma-separated list of namespaces to load gametests from. Empty = all namespaces.
|
||||
property 'forge.enabledGameTestNamespaces', mod_id
|
||||
|
||||
mods {
|
||||
"${mod_id}" {
|
||||
source sourceSets.main
|
||||
|
@ -125,11 +123,7 @@ minecraft {
|
|||
sourceSets.main.resources { srcDir 'src/generated/resources' }
|
||||
|
||||
repositories {
|
||||
//mavenCentral()
|
||||
maven {
|
||||
name = "Aria's Creations Caches"
|
||||
url = "https://maven.zontreck.com/repository/internal"
|
||||
}
|
||||
mavenCentral()
|
||||
// Put repositories for dependencies here
|
||||
// ForgeGradle automatically adds the Forge maven and Maven Central for you
|
||||
|
||||
|
@ -145,7 +139,7 @@ repositories {
|
|||
|
||||
maven {
|
||||
name = "zontreck Maven"
|
||||
url = "https://maven.zontreck.com/repository/zontreck"
|
||||
url = "https://git.zontreck.com/api/packages/AriasCreations/maven"
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -158,15 +152,6 @@ dependencies {
|
|||
// then special handling is done to allow a setup of a vanilla dependency without the use of an external repository.
|
||||
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
|
||||
|
||||
provided "dev.zontreck:LibAC:${libac}"
|
||||
implementation "dev.zontreck:LibAC:${libac}"
|
||||
minecraftLibrary "dev.zontreck:LibAC:${libac}"
|
||||
|
||||
|
||||
provided "dev.zontreck:EventsBus:${eventsbus}"
|
||||
implementation "dev.zontreck:EventsBus:${eventsbus}"
|
||||
minecraftLibrary "dev.zontreck:EventsBus:${eventsbus}"
|
||||
|
||||
// Example mod dependency with JEI - using fg.deobf() ensures the dependency is remapped to your development mappings
|
||||
// The JEI API is declared for compile time use, while the full JEI artifact is used at runtime
|
||||
// compileOnly fg.deobf("mezz.jei:jei-${mc_version}-common-api:${jei_version}")
|
||||
|
@ -204,11 +189,6 @@ tasks.named('processResources', ProcessResources).configure {
|
|||
|
||||
// Example for how to get properties into the manifest for reading at runtime.
|
||||
tasks.named('jar', Jar).configure {
|
||||
from {
|
||||
configurations.provided.asFileTree.collect{zipTree(it)}
|
||||
}
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
|
||||
manifest {
|
||||
attributes([
|
||||
'Specification-Title' : mod_id,
|
||||
|
@ -231,10 +211,12 @@ tasks.named('jar', Jar).configure {
|
|||
// }
|
||||
|
||||
|
||||
def MAVEN_PASSWORD_PROPERTY = "AriasCreationsMavenPassword"
|
||||
def MAVEN_PASSWORD = "AriasCreationsMavenPassword"
|
||||
def MAVEN_USER = "AriasCreationsMavenUser"
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
mavenJava(MavenPublication) {
|
||||
register('mavenJava', MavenPublication) {
|
||||
artifact jar
|
||||
artifact sourcesJar
|
||||
artifact javadocJar
|
||||
|
@ -242,13 +224,12 @@ publishing {
|
|||
}
|
||||
repositories {
|
||||
maven {
|
||||
url = "https://maven.zontreck.com/repository/zontreck"
|
||||
url = "https://git.zontreck.com/api/packages/MinecraftMods/maven"
|
||||
name = "ariascreations"
|
||||
if (project.findProperty(MAVEN_PASSWORD_PROPERTY) != null) {
|
||||
credentials {
|
||||
username = "admin"
|
||||
password = project.findProperty(MAVEN_PASSWORD_PROPERTY)
|
||||
}
|
||||
|
||||
credentials {
|
||||
username = project.findProperty(MAVEN_USER)
|
||||
password = project.findProperty(MAVEN_PASSWORD)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
460
changelog.txt
460
changelog.txt
|
@ -1,460 +0,0 @@
|
|||
1.19.x Changelog
|
||||
43.1
|
||||
====
|
||||
- 43.1.1 Add ability to Auto register capabilities via annotation (#8972)
|
||||
- 43.1.0 1.19.2 RB
|
||||
|
||||
43.0
|
||||
====
|
||||
- 43.0.22 Added ItemDecorator API (#8794)
|
||||
- 43.0.21 [1.19.x] Custom usage animations for items (#8932)
|
||||
- 43.0.20 Allow registering custom `ColorResolver`s (#8880)
|
||||
- 43.0.19 [1.19] Allow custom outline rendering on EntityRenderers and BlockEntityRenderers (#8938)
|
||||
- 43.0.18 Redirect checks for entity selector use to a permission (#8947)
|
||||
This allows greater flexibility for configuring servers with
|
||||
operator-like permissions to user groups through the permissions API and
|
||||
their permissions handler of choice without needing to grant the
|
||||
vanilla operator permission to any player.
|
||||
The new permission is "forge:use_entity_selectors", which is granted by
|
||||
default to players with permission level 2 (GAMEMASTERS) and above.
|
||||
The hook falls back to checking the permission level if the source of
|
||||
the command is not a ServerPlayer, such as for command blocks and
|
||||
functions.
|
||||
- 43.0.17 Allow FakePlayer to report its position (#8963)
|
||||
- 43.0.16 Add alternate version of renderEntityInInventory to allow for directly specifying the angles (#8961)
|
||||
- 43.0.15 Add cancellable ToastAddEvent (#8952)
|
||||
- 43.0.14 Modify ScreenEvent.RenderInventoryMobEffects to allow moving the effect stack left or right (#8951)
|
||||
- 43.0.13 Fix Enchantment#doPostHurt and Enchantment#doPostAttack being called twice for players. Fixes MC-248272 (#8948)
|
||||
- 43.0.12 Remove reflective implementation of ICustomPacket. (#8973)
|
||||
Make vanilla custom packets able to be sent multiple times. Closes #8969
|
||||
- 43.0.11 Filter name spaces to directories only. Closes #8413
|
||||
- 43.0.10 Fix a corner case where the UMLB can not extract a version from a library. (#8967)
|
||||
- 43.0.9 Fix worlds with removed dimension types unable to load. (#8959) Closes #8800
|
||||
- 43.0.8 Fix issue where unknown chunk generators would cause DFU to fail. (#8957)
|
||||
- 43.0.7 Fix comments and documentation that were missed during the review of #8712 (#8945)
|
||||
- 43.0.6 Make AnvilUpdateEvent fire even if the second input is empty, which means it fires even if only changing the item name. (#8905)
|
||||
- 43.0.5 Fix `LivingEntity#isBlocking` to use `ToolActions#SHIELD_BLOCK` instead of `UseAnim#BLOCK` (#8933)
|
||||
- 43.0.4 Add Custom HolderSet Types allowing for logical combining of sets. (#8928)
|
||||
- 43.0.3 Add values to VersionSupportMatrix to support loading mods that restrict versions to 1.19.1 on 1.19.2 (#8946)
|
||||
- 43.0.2 Fix certain particles not updating their bounding box when their position changes (#8925)
|
||||
- 43.0.1 Update EventBus to address concurrency issue in ModLauncher Factory. Closes #8924
|
||||
- 43.0.0 1.19.2
|
||||
|
||||
42.0
|
||||
====
|
||||
- 42.0.9 Remove calls to getStepHeight in Player#maybeBackOffFromEdge (#8927)
|
||||
- 42.0.8 Add forge tags for tools and armors, these DO NOT replace ToolActions, and are designed just for Recipes. (#8914)
|
||||
- 42.0.7 Add Biomes.BEACH to Tags (#8892)
|
||||
- 42.0.6 Let NetworkInstance.isRemotePresent check minecraft:register for channel IDs. (#8921)
|
||||
- 42.0.5 Add an event for when the chunk ticket level is updated (#8909)
|
||||
- 42.0.4 Re-add PotentialSpawns event (#8712)
|
||||
- 42.0.3 Fix misplaced patch in ItemEntityRenderer breaking ItemEntityRenderer#shouldBob() (#8919)
|
||||
- 42.0.2 [1.19] [HotFix] Fix the dedicated server not having access to the JiJ filesystems. (#8931)
|
||||
- 42.0.1 Match Mojang's action bar fix for MC-72687 (#8917)
|
||||
- 42.0.0 Forge 1.19.1
|
||||
Load natives from classpath
|
||||
Make command argument types a forge registry
|
||||
Add `EntityMobGriefingEvent` to `Allay#wantsToPickUp`
|
||||
Overhaul `ServerChatEvent` to use `ChatDecorator` system
|
||||
Remove `ClientChatEvent#setMessage` for now
|
||||
Gradle 7.5
|
||||
|
||||
41.1
|
||||
====
|
||||
- 41.1.0 Mark 1.19 RB
|
||||
|
||||
41.0
|
||||
====
|
||||
- 41.0.113 Allow faces of an "elements" model to be made emissive (#8890)
|
||||
- 41.0.112 Fix invalid channel names sent from the server causing the network thread to error. (#8902)
|
||||
- 41.0.111 Fix PlayerEvent.BreakSpeed using magic block position to signify invalid position. Closes #8906
|
||||
- 41.0.110 Fix cases where URIs would not work properly with JarInJar (#8900)
|
||||
- 41.0.109 Add new hook to allow modification of lightmap via Dimension special effects (#8863)
|
||||
- 41.0.108 Fix Forge's packet handling on play messages. (#8875)
|
||||
- 41.0.107 Add API for tab list header/footer (#8803)
|
||||
- 41.0.106 Allow modded blocks overriding canStickTo prevent sticking to vanilla blocks/other modded blocks (#8837)
|
||||
- 41.0.105 Multiple tweaks and fixes to the recent changes in the client refactor PR: Part 3 (#8864)
|
||||
Fix weighted baked models not respecting children render types
|
||||
Allow fluid container model to use base texture as particle
|
||||
Fix inverted behavior in composite model building. Fixes #8871
|
||||
- 41.0.104 Fix crossbows not firing ArrowLooseEvent (#8887)
|
||||
- 41.0.103 Add User-Agent header to requests made by the update checker (#8881)
|
||||
Format: Java-http-client/<Java version> MinecraftForge/<ForgeVer> <ModId>/<ModVersion>
|
||||
- 41.0.102 Output the full path in a crash report so it is easier to find the outer mod when a crash in Jar-In-Jar occurs. (#8856)
|
||||
- 41.0.101 Clean up the pick item ("middle mouse click") patches (#8870)
|
||||
- 41.0.100 [1.19.x] Hotfix for test mods while the refactor is ongoing
|
||||
- 41.0.99 add event to SugarCaneBlock (#8877)
|
||||
- 41.0.98 Fix Global Loot Modifiers not using Dispatch Codec (#8859)
|
||||
- 41.0.97 Allow block render types to be set in datagen (#8852)
|
||||
- 41.0.96 Fix renderBreakingTexture not using the target's model data (#8849)
|
||||
- 41.0.95 Multiple tweaks and fixes to the recent changes in the client refactor PR: Part 2 (#8854)
|
||||
* Add getter for the component names in an unbaked geometry
|
||||
* Fix render type hint not being copied in BlockGeometryBakingContext
|
||||
* Ensure BlockRenderDispatches's renderSingleBlock uses the correct buffer
|
||||
- 41.0.94 [1.19.x] Apply general renames, A SRG is provided for modders. (#8840)
|
||||
See https://gist.github.com/SizableShrimp/882a671ff74256d150776da08c89ef72
|
||||
- 41.0.93 Fix mob block breaking AI not working correctly when chunk 0,0 is unloaded. Closes #8853
|
||||
- 41.0.92 Fix crash when breaking blocks with multipart models and remove caching. Closes #8850
|
||||
- 41.0.91 Fixed `CompositeModel.Baked.Builder.build()` passing arguments in the wrong order (#8846)
|
||||
- 41.0.90 Make cutout mipmaps explicitly opt-in for item/entity rendering (#8845)
|
||||
* Make cutout mipmaps explicitly opt-in for item/entity rendering
|
||||
* Default render type domain to "minecraft" in model datagens
|
||||
- 41.0.89 Fixed multipart block models not using the new model driven render type system. (#8844)
|
||||
- 41.0.88 Update to the latest JarJar to fix a collision issue where multiple jars could provide an exact match. (#8847)
|
||||
- 41.0.87 Add FML config to disable DFU optimizations client-side. (#8842)
|
||||
* Add client-side command line argument to disable DFU optimizations.
|
||||
* Switch to using FMLConfig value instead.
|
||||
- 41.0.86 [1.19] Fixed broken BufferBuilder.putBulkData(ByteBuffer) added by Forge (#8819)
|
||||
* Fixes BufferBuilder.putBulkData(ByteBuffer)
|
||||
* use nextElementByte
|
||||
* Fixed merge conflict
|
||||
- 41.0.85 [1.19.x] Fix shulker boxes allowing input of items, that return false for Item#canFitInsideContainerItems, through hoppers. (#8823)
|
||||
* Make ShulkerBoxBlockEntity#canPlaceItemThroughFace delegate to Item#canFitInsideContainerItems.
|
||||
* Switch to using Or and add comment.
|
||||
* Switch Or to And.
|
||||
- 41.0.84 [1.19.x] Added RenderLevelStageEvent to replace RenderLevelLastEvent (#8820)
|
||||
* Ported RenderLevelStageEvent from 1.18.2
|
||||
* Updated to fix merge conflicts
|
||||
- 41.0.83 [1.19.x] Fix door datagenerator (#8821)
|
||||
* Fix door datagenerator
|
||||
Fix datagenerator for door blocks. Successor to #8687, addresses comments made there about statement complexity.
|
||||
* Fix extra space around parameter
|
||||
Fix extra space before comma around a parameter.
|
||||
- 41.0.82 Create PieceBeardifierModifier to re-enable piecewise beardifier definitions (#8798)
|
||||
- 41.0.81 Allow blocks to provide a dynamic MaterialColor for display on maps (#8812)
|
||||
- 41.0.80 [1.19.x] BiomeTags Fixes/Improvements (#8711)
|
||||
* dimension specific tag fix
|
||||
* remove forge:is_beach cause vanilla has it already
|
||||
* remove forge tags for new 1.19 vanilla tags (savanna, beach, overworld, end)
|
||||
Co-authored-by: Flemmli97 <Flemmli97@users.noreply.github.com>
|
||||
- 41.0.79 1.19 - Remove GlobalLootModifierSerializer and move to Codecs (#8721)
|
||||
* convert GLM serializer class to codec
|
||||
* cleanup
|
||||
* GLM list needs to be sorted
|
||||
* datagen
|
||||
* simplify serialization
|
||||
* fix test mods (oops)
|
||||
* properly use suppliers for codec as they are registry obj
|
||||
- 41.0.78 Implement item hooks for potions and enchantments (#8718)
|
||||
* Implement item hooks for potions and enchantments
|
||||
* code style fixes
|
||||
- 41.0.77 Re-apply missing patch to ServerLevel.EntityCallbacks#onTrackingEnd() (#8828)
|
||||
- 41.0.76 Double Bar Rendering fixed (#8806) (#8807)
|
||||
* Double Bar Rendering fixed (#8806)
|
||||
* Added requested changes by sciwhiz12
|
||||
- 41.0.75 Multiple tweaks and fixes to the recent changes in the client refactor PR (#8836)
|
||||
* Add an easy way to get the NamedGuiOverlay from a vanilla overlay
|
||||
* Fix static member ordering crash in UnitTextureAtlasSprite
|
||||
* Allow boss bar rendering to be cancelled
|
||||
* Make fluid container datagen use the new name
|
||||
- 41.0.74 Add FogMode to ViewportEvent.RenderFog (#8825)
|
||||
- 41.0.73 Provide additional context to the getFieldOfView event (#8830)
|
||||
- 41.0.72 Pass renderType to IForgeBakedModel.useAmbientOcclusion (#8834)
|
||||
- 41.0.71 Load custom ITransformationServices from the classpath in dev (#8818)
|
||||
* Add a classpath transformer discoverer to load custom transformation services from the classpath
|
||||
* Update ClasspathTransformerDiscoverer to 1.18
|
||||
* Update license year
|
||||
* Update license header
|
||||
* Fix the other license headers
|
||||
* Update ClasspathTransformerDiscoverer to 1.19
|
||||
- 41.0.70 Handle modded packets on the network thread (#8703)
|
||||
* Handle modded packets on the network thread
|
||||
- On the server we simply need to remove the call to
|
||||
ensureRunningOnSameThread.
|
||||
- On the client side, we now handle the packet at the very start of the
|
||||
call. We make sure we're running from a network thread to prevent
|
||||
calling the handling code twice.
|
||||
While this does mean we no longer call .release(), in practice this
|
||||
doesn't cause any leaks as ClientboundCustomPayloadPacket releases
|
||||
for us.
|
||||
* Clarify behaviour a little in the documentation
|
||||
* Javadoc formatting
|
||||
* Add a helper method for handling packets on the main thread
|
||||
Also rename the network thread one. Should make it clearer the expected
|
||||
behaviour of the two, and make it clearer there's a potentially breaking
|
||||
change.
|
||||
* Add back consumer() methods
|
||||
Also document EventNetworkChannel, to clarify the thread behaviour
|
||||
there.
|
||||
* Add since = "1.19" to deprecated annotations
|
||||
- 41.0.69 Cache resource listing calls in resource packs (#8829)
|
||||
* Make the resource lookups cached.
|
||||
* Include configurability and handle patch cleanup.
|
||||
* Document and comment the cache manager.
|
||||
* Make thread selection configurable.
|
||||
* Implement a configurable loading mechanic that falls back to default behaviour when the config is not bound yet.
|
||||
* Use boolean supplier and fix wildcard import.
|
||||
* Clean up the VPR since this is more elegant.
|
||||
* Clean up the VPR since this is more elegant.
|
||||
* Address review comments.
|
||||
* Address more review comments.
|
||||
* Fix formatting on `getSource`
|
||||
* Address comments by ichtt
|
||||
* Adapt to pups requests.
|
||||
* Stupid idea.
|
||||
* Attempt this again with a copy on write list.
|
||||
* Fix a concurrency and loading issue.
|
||||
* Fix #8813
|
||||
Checks if the paths are valid resource paths.
|
||||
* Move the new methods on vanilla Patch.
|
||||
- 41.0.68 Update SJH and JIJ
|
||||
- 41.0.67 Fix #8833 (#8835)
|
||||
- 41.0.66 Fix backwards fabulous check in SimpleBakedModel (#8832)
|
||||
Yet another blunder we missed during the review of #8786.
|
||||
- 41.0.65 Make texture atlas in StandaloneGeometryBakingContext configurable (#8831)
|
||||
- 41.0.64 [1.19.X] Client code cleanup, updates, and other refactors (#8786)
|
||||
* Revert "Allow safely registering RenderType predicates at any time (#8685)"
|
||||
This reverts commit be7275443fd939db9c58bcad47079c3767789ac1.
|
||||
* Renderable API refactors
|
||||
- Rename "render values" to "context"
|
||||
- Rename SimpleRenderable to CompositeRenderable to better reflect its use
|
||||
- Remove IMultipartRenderValues since it doesn't have any real use
|
||||
- Add extensive customization options to BakedModelRenderable
|
||||
* ClientRegistry and MinecraftForgeClient refactors
|
||||
- Add sprite loader manager and registration event
|
||||
- Add spectator shader manager and registration event
|
||||
- Add client tooltip factory manager and registration event
|
||||
- Add recipe book manager and registration event
|
||||
- Add key mapping registration event
|
||||
- Remove ClientRegistry, as everything has been moved out of it
|
||||
- Remove registration methods from MinecraftForgeClient, as they have dedicated events now
|
||||
* Dimension special effects refactors
|
||||
- Fold handlers into an extension class and remove public mutable fields
|
||||
- Add dimension special effects manager and registration event
|
||||
* HUD overlay refactors
|
||||
- Rename to IGuiOverlay match vanilla (instead of Ingame)
|
||||
- Add overlay manager and registration event
|
||||
- Move vanilla overlays to a standalone enum
|
||||
* Model loader refactors
|
||||
- Rename IModelLoader to IGeometryLoader
|
||||
- Add loader manager and registration event
|
||||
- Fold all model events into one
|
||||
- Move registration of additionally loaded models to an event
|
||||
- Remove ForgeModelBakery and related classes as they served no purpose anymore
|
||||
* Render properties refactors
|
||||
- Rename all render properties to client extensions and relocate accordingly
|
||||
- Move lookups to the respective interfaces
|
||||
* Model data refactors
|
||||
- Convert model data to a final class backed by an immutable map and document mutability requirements. This addresses several thread-safety issues in the current implementation which could result in race conditions
|
||||
- Transfer ownership of the data manager to the client level. This addresses several issues that arise when multiple levels are used at once
|
||||
* GUI and widget refactors
|
||||
- Move all widgets to the correct package
|
||||
- Rename GuiUtils and children to match vanilla naming
|
||||
* New vertex pipeline API
|
||||
- Move to vanilla's VertexConsumer
|
||||
- Roll back recent PR making VertexConsumer format-aware. This is the opposite of what vanilla does, and should not be relevant with the updated lighting pipeline
|
||||
* Lighting pipeline refactors
|
||||
- Move to dedicated lighting package
|
||||
- Separate flat and smooth lighters
|
||||
- Convert from a vertex pipeline transformer to a pure vertex source (input is baked quads)
|
||||
* Model geometry API refactors
|
||||
- Rename IModelGeometry to IUnbakedGeometry
|
||||
- Rename IModelConfiguration to IGeometryBakingContext
|
||||
- Rename other elements to match vanilla naming
|
||||
- Remove current changes to ModelState, as they do not belong there. Transforms should be specified through vanilla's system. ModelState is intended to transfer state from the blockstate JSON
|
||||
- Remove multipart geometries and geometry parts. After some discussion, these should not be exposed. Instead, geometries should be baked with only the necessary parts enabled
|
||||
* Make render types a first-class citizen in baked models
|
||||
- Add named render types (block + entity + fabulous entity)
|
||||
- Add named render type manager + registration event
|
||||
- Make BakedModel aware of render types and transfer control over which ones are used to it instead of ItemBlockRenderTypes (fallback)
|
||||
- (additional) Add concatenated list view. A wrapper for multiple lists that iterates through them in order without the cost of merging them. Useful for merging lists of baked quads
|
||||
* General event refactors
|
||||
- Several renames to either match vanilla or improve clarity
|
||||
- Relocate client chat event dispatching out of common code
|
||||
* Forge model type refactors
|
||||
- Rename SeparatePerspectiveModel to SeparateTransformsModel
|
||||
- Rename ItemModelMesherForge to ForgeItemModelShaper
|
||||
- Rename DynamicBucketModel to DynamicFluidContainerModel
|
||||
- Prefix all OBJ-related classes with "Obj" and decouple parsing from construction
|
||||
- Extract ElementsModel from model loader registry
|
||||
- Add EmptyModel (baked, unbaked and loader)
|
||||
- Refactor CompositeModel to take over ItemMultiLayerBakedModel
|
||||
- Remove FluidModel as it's not used and isn't compatible with the new fluid rendering in modern versions
|
||||
- Move model loader registration to a proper event handler
|
||||
- Update names of several JSON fields (backwards-compatible)
|
||||
- Update datagens to match
|
||||
* Miscellaneous changes and overlapping patches
|
||||
- Dispatch all new registration events
|
||||
- Convert ExtendedServerListData to a record
|
||||
- Add/remove hooks from ForgeHooksClient as necessary
|
||||
* Update test mods
|
||||
* Fix VertexConsumerWrapper returning parent instead of itself
|
||||
* Additional event cleanup pass
|
||||
As discussed on Discord:
|
||||
- Remove "@hidden" and "@see <callsite>" javadoc annotations from all client events and replace them with @ApiStatus.Internal annotation
|
||||
- Make all events that shouldn't be fired directly into abstract classes with protected constructors
|
||||
- Another styling pass, just in case (caught some missed classes)
|
||||
* Add proper deprecation javadocs and de-dupe some vertex consumer code
|
||||
* Replace sets of chunk render types with a faster BitSet-backed collection
|
||||
This largely addresses potential performance concerns that using a plain HashSet might involve by making lookups and iteration as linear as they can likely be (aside from using a plain byte/int/long for bit storage). Further performance concerns related to the implementation may be addressed separately, as all the implementation details are hidden from the end user
|
||||
* Requested changes
|
||||
- Remove MinecraftForgeClient and move members to Minecraft, IForgeMinecraft and StencilManager
|
||||
- Allow non-default elements to be passed into VertexConsumer and add support to derived classes
|
||||
- Move array instantiation out of quad processing in lighting pipeline
|
||||
- Fix flipped fluid container model
|
||||
- Set default UV1 to the correct values in the remapping pipeline
|
||||
- Minor documentation changes
|
||||
* Add/update EXC entries and fix AT comment
|
||||
* Add test mod as per Orion's request
|
||||
* Additional requested changes
|
||||
* Allow custom model types to request the particle texture to be loaded
|
||||
* Even more requested changes
|
||||
* Improve generics in ConcatenatedListView and add missing fallbacks
|
||||
* Fix fluid render types being bound to the fluid and not its holder
|
||||
* Remove non-contractual nullability in ChunkRenderTypeSet and add isEmpty
|
||||
Additionally, introduce chunk render type checks in ItemBlockRenderTypes
|
||||
Co-authored-by: Dennis C <xfacthd@gmx.de>
|
||||
- 41.0.63 Implement full support for IPv6 (#8742)
|
||||
- 41.0.62 Fix certain user-configured options being overwritten incorrectly due to validators. (#8780)
|
||||
- 41.0.61 Allow safely registering RenderType predicates at any time (#8685)
|
||||
- 41.0.60 Fix crash after loading error due to fluid texture gathering and config lookup (#8802)
|
||||
- 41.0.59 Remove the configuration option for handling empty tags in ingredients. (#8799)
|
||||
Now empty tags are considered broken in all states.
|
||||
- 41.0.58 Fix MC-105317 Structure blocks do not rotate entities correctly when loading (#8792)
|
||||
- 41.0.57 Fire ChunkWatchEvents after sending packets (#8747)
|
||||
- 41.0.56 Add item handler capability to chest boats (#8787)
|
||||
- 41.0.55 Add getter for correct BiomeSpecialEffectsBuilder to BiomeInfo$Builder (#8781)
|
||||
- 41.0.54 Fix BlockToolModificationEvent missing cancelable annotation (#8778)
|
||||
- 41.0.53 Fix ticking chunk tickets from forge's chunk manager not causing chunks to fully tick (#8775)
|
||||
- 41.0.52 Fix default audio device config loading string comparison issue (#8767)
|
||||
- 41.0.51 Fix missed vanilla method overrides in ForgeRegistry (#8766)
|
||||
- 41.0.50 Add MinecraftServer reference to ServerTickEvent (#8765)
|
||||
- 41.0.49 Fix TagsProviders for datapack registries not recognizing existing files (#8761)
|
||||
- 41.0.48 Add callback after a BlockState was changed and the neighbors were updated (#8686)
|
||||
- 41.0.47 Add biome tag entries for 1.19 biomes (#8684)
|
||||
- 41.0.46 Make fishing rods use tool actions for relevant logic (#8681)
|
||||
- 41.0.45 Update BootstrapLauncher to 1.1.1 and remove the forced
|
||||
merge of text2speech since new BSL does it.
|
||||
- 41.0.44 Merge text2speech libs together so the natives are part of the jar
|
||||
- 41.0.43 Make Forge ConfigValues implement Supplier. (#8776)
|
||||
- 41.0.42 Fix merge derp in AbstractModProvider and logic derp in ModDiscoverer
|
||||
- 41.0.41 Add "send to mods in order" method to ModList and use it (#8759)
|
||||
* Add "send to mods in order" method to ModList and use it in RegistryEvents and DataGen..
|
||||
* Also preserve order in runAll
|
||||
* Do better comparator thanks @pupnewfster
|
||||
* postEvent as well.
|
||||
- 41.0.40 Update SJH to 2.0.2.. (#8774)
|
||||
* Update SJH to 2.0.3..
|
||||
- 41.0.39 Sanity check the version specified in the mod file (#8749)
|
||||
* Sanity check the version specified in the mod file to
|
||||
make sure it's compatible with JPMS standards for
|
||||
version strings.
|
||||
Closes #8748
|
||||
Requires SPI 6
|
||||
- 41.0.38 Fix SP-Devtime world loading crash due to missing server configs (#8757)
|
||||
- 41.0.37 Remove ForgeWorldPreset and related code (#8756)
|
||||
Vanilla has a working replacement.
|
||||
- 41.0.36 Change ConfigValue#get() to throw if called before config loaded (#8236)
|
||||
This prevents silent issues where a mod gets the value of the setting
|
||||
before configs are loaded, which means the default value is always
|
||||
returned.
|
||||
As there may be situations where the getting the config setting before
|
||||
configs are loaded is needed, and it is not preferable to hardcode the
|
||||
default value, the original behavior is made available through #getRaw.
|
||||
Implements and closes #7716
|
||||
* Remove getRaw() method
|
||||
This is effectively replaced with the expression `spec.isLoaded() ?
|
||||
configValue.get() : configValue.getDefault()`.
|
||||
* Remove forceSystemNanoTime config setting
|
||||
As implemented, it never had any effect as any place where the config
|
||||
value would be queried happens before the configs are loaded.
|
||||
- 41.0.35 Fix EnumArgument to use enum names for suggestions (#8728)
|
||||
Previously, the suggestions used the string representation of the enum
|
||||
through Enum#toString, which can differ from the name of the enum as
|
||||
required by Enum#valueOf, causing invalid suggestions (both in gui and
|
||||
through the error message).
|
||||
- 41.0.34 Jar-In-Jar (#8715)
|
||||
- 41.0.33 [1.19] Fix data-gen output path of custom data-pack registries (#8724)
|
||||
- 41.0.32 Fix player dive and surface animations in custom fluids (#8738)
|
||||
- 41.0.31 [1.19.x] Affect ItemEntity Motion in Custom Fluids (#8737)
|
||||
- 41.0.30 [1.19] Add support for items to add enchantments without setting them in NBT (#8719)
|
||||
- 41.0.29 [1.19.x] Add stock biome modifier types for adding features and spawns (#8697)
|
||||
- 41.0.28 [1.19.x] Fluid API Overhaul (#8695)
|
||||
- 41.0.27 Replace StructureSpawnListGatherEvent with StructureModifiers (#8717)
|
||||
- 41.0.26 Use stack sensitive translation key by default for FluidAttributes. (#8707)
|
||||
- 41.0.25 Delete LootItemRandomChanceCondition which added looting bonus enchantment incorrectly. (#8733)
|
||||
- 41.0.24 Update EventBus to 6.0, ModLauncher to 10.0.1 and BootstrapLauncher to 1.1 (#8725)
|
||||
- 41.0.23 Replace support bot with support action (#8700)
|
||||
- 41.0.22 Fix Reach Distance / Attack Range being clamped at 6.0 (#8699)
|
||||
- 41.0.21 [1.19.x] Fix mods' worldgen data not being loaded when creating new singleplayer worlds (#8693)
|
||||
- 41.0.20 [1.19.x] Fix experimental confirmation screen (#8727)
|
||||
- 41.0.19 Move is_mountain to forge's tag instead of vanilla's (#8726)
|
||||
- 41.0.18 [1.19.x] Add CommandBuildContext to Register Command Events (#8716)
|
||||
- 41.0.17 Only rewrite datagen cache when needed (#8709)
|
||||
- 41.0.16 Implement a simple feature system for Forge (#8670)
|
||||
* Implement a simple feature system for Forge. Allows mods to demand certain features are available in the loading system. An example for java_version is provided, but not expected to be used widely. This is more targeted to properties of the display, such as GL version and glsl profile.
|
||||
Requires https://github.com/MinecraftForge/ForgeSPI/pull/13 to be merged first in ForgeSPI, and the SPI to be updated appropriately in build.gradle files.
|
||||
* rebase onto 1.19 and add in SPI update
|
||||
- 41.0.15 displayTest option in mods.toml (#8656)
|
||||
* displayTest option in mods.toml
|
||||
* "MATCH_VERSION" (or none) is existing match version string behaviour
|
||||
* "IGNORE_SERVER_VERSION" accepts anything and sends special SERVERONLY string
|
||||
* "IGNORE_ALL_VERSION" accepts anything and sends an empty string
|
||||
* "NONE" allows the mod to supply their own displaytest using the IExtensionPoint mechanism.
|
||||
* Update display test with feedback and added the mods.toml discussion in mdk.
|
||||
- 41.0.14 Update forgeSPI to v5 (#8696)
|
||||
- 41.0.13 Make IVertexConsumers such as the lighting pipeline, be aware of which format they are dealing with. (#8692)
|
||||
Also fix Lighting pipeline ignoring the overlay coords from the block renderer.
|
||||
- 41.0.12 Fixed misaligned patch to invalidateCaps in Entity (#8705)
|
||||
- 41.0.11 Fix readAdditionalLevelSaveData (#8704)
|
||||
- 41.0.10 Fixes setPos to syncPacketPositionCodec (#8702)
|
||||
- 41.0.9 Fix wrong param passed to PlayLevelSoundEvent.AtEntity (#8688)
|
||||
- 41.0.8 Override initialize in SlotItemHandler, so it uses the itemhandler instead of container (#8679)
|
||||
- 41.0.7 Update MDK for 1.19 changes (#8675)
|
||||
- 41.0.6 Add helper to RecipeType, and fix eclipse compiler error in test class.
|
||||
- 41.0.5 Update modlauncher to latest (#8691)
|
||||
- 41.0.4 Fix getting entity data serializer id crashing due to improper port to new registry system (#8678)
|
||||
- 41.0.3 Fire registry events in the order vanilla registers to registries (#8677)
|
||||
Custom registries are still fired in alphabetical order, after all vanilla registries.
|
||||
Move forge's data_serializers registry to forge namespace.
|
||||
- 41.0.2 Add method with pre/post wrap to allow setting/clearing mod context. (#8682)
|
||||
Fixes ActiveContainer in ModContext not being present in registry events. Closes #8680
|
||||
- 41.0.1 Fix the Curlie oopsie
|
||||
- 41.0.0 Forge 1.19
|
||||
* Bump pack.mcmeta formats
|
||||
* 1.19 biome modifiers
|
||||
* Mark ClientPlayerNetworkEvent.LoggedOutEvent's getters as nullable
|
||||
* Add docs and package-info to client extension interfaces package
|
||||
* Move RenderBlockOverlayEvent hooks to ForgeHooksClient
|
||||
* Add package-infos to client events package
|
||||
* Rename SoundLoadEvent to SoundEngineLoadEvent
|
||||
This reduces confusion from consumers which may think the
|
||||
name SoundLoadEvent refers to an individual sound being loaded rather
|
||||
than the sound engine.
|
||||
* Document and change SoundLoadEvent to fire on mod bus
|
||||
Previously, it fired on both the mod bus and the Forge bus, which is
|
||||
confusing for consumers.
|
||||
* Delete SoundSetupEvent
|
||||
Looking at its original implementation shows that there isn't an
|
||||
appropriate place in the new sound code to reinsert the event, and the
|
||||
place of 'sound engine/manager initialization event' is taken already by SoundLoadEvent.
|
||||
* Perform some cleanup on client events
|
||||
- Removed nullable annotations from ClientPlayerNetworkEvent
|
||||
- Renamed #getPartialTicks methods to #getPartialTick, to be consistent
|
||||
with vanilla's naming of the partial tick
|
||||
- Cleanup documentation to remove line breaks, use the
|
||||
spelling 'cancelled' over
|
||||
'canceled', and improve docs on existing and
|
||||
new methods.
|
||||
* Remove EntityEvent.CanUpdate
|
||||
Closes MinecraftForge/MinecraftForge#6394
|
||||
* Switch to Jetbrains nullability annotations
|
||||
* New PlayLevelSoundEvent; replaces old PlaySoundAtEntityEvent
|
||||
* Remove ForgeWorldPresetScreens
|
||||
* Remove IForgeRegistryEntry
|
||||
* Remove use of List<Throwable> in FML's CompletableFutures
|
||||
* Add docs to mod loading stages, stages, and phases
|
||||
* Gradle 7.4.2
|
||||
* Use SLF4J in FMLLoader and other subprojects
|
||||
* Switch dynamic versions in subprojects to pinned ones
|
||||
* Switch ForgeRoot and MDK to FG plugin markers
|
||||
* Configure Forge javadoc task
|
||||
The task now uses a custom stylesheet with MCForge elements, and
|
||||
configured to combine the generation from the four FML subprojects
|
||||
(fmlloader, fmlcore, javafmllanguage, mclanguage) and the Forge project
|
||||
into the javadoc output.
|
||||
* Update docs/md files, for 1.19 update and the move away from IRC to Discord.
|
||||
* Make "Potentially dangerous alternative prefix" a debug warning, not info.
|
||||
Co-authored-by: Curle <curle@gemwire.uk>
|
||||
Co-authored-by: sciwhiz12 <arnoldnunag12@gmail.com>
|
||||
|
|
@ -1,28 +1,20 @@
|
|||
# Sets default memory used for gradle commands. Can be overridden by user or command line properties.
|
||||
# This is required to provide enough memory for the Minecraft decompilation process.
|
||||
org.gradle.jvmargs=-Xmx3G
|
||||
org.gradle.jvmargs=-Xmx3G -Dfile.encoding=utf-8
|
||||
org.gradle.daemon=false
|
||||
|
||||
|
||||
parchment_version=2023.09.03
|
||||
# luckperms_api_version=5.4
|
||||
|
||||
libac=1.4.18
|
||||
eventsbus=1.0.31
|
||||
## Environment Properties
|
||||
|
||||
# The Minecraft version must agree with the Forge version to get a valid artifact
|
||||
minecraft_version=1.20.1
|
||||
minecraft_version=1.19.2
|
||||
# The Minecraft version range can use any release version of Minecraft as bounds.
|
||||
# Snapshots, pre-releases, and release candidates are not guaranteed to sort properly
|
||||
# as they do not follow standard versioning conventions.
|
||||
minecraft_version_range=[1.20.1,1.21)
|
||||
minecraft_version_range=[1.19.2,1.20)
|
||||
# The Forge version must agree with the Minecraft version to get a valid artifact
|
||||
forge_version=47.2.0
|
||||
forge_version=43.4.2
|
||||
# The Forge version range can use any version of Forge as bounds or match the loader version range
|
||||
forge_version_range=[47,)
|
||||
forge_version_range=[43,)
|
||||
# The loader version range can only use the major version of Forge/FML as bounds
|
||||
loader_version_range=[47,)
|
||||
loader_version_range=[43,)
|
||||
# The mapping channel to use for mappings.
|
||||
# The default set of supported mapping channels are ["official", "snapshot", "snapshot_nodoc", "stable", "stable_nodoc"].
|
||||
# Additional mapping channels can be registered through the "channelProviders" extension in a Gradle plugin.
|
||||
|
@ -37,14 +29,15 @@ loader_version_range=[47,)
|
|||
#
|
||||
# Parchment is an unofficial project maintained by ParchmentMC, separate from Minecraft Forge.
|
||||
# Additional setup is needed to use their mappings, see https://parchmentmc.org/docs/getting-started
|
||||
mapping_channel=parchment
|
||||
mapping_channel=official
|
||||
# The mapping version to query from the mapping channel.
|
||||
# This must match the format required by the mapping channel.
|
||||
mapping_version=2023.09.03-1.20.1
|
||||
|
||||
|
||||
parchment_version=2022.11.27
|
||||
# luckperms_api_version=5.4
|
||||
libac=1.5.33
|
||||
eventsbus=1.0.48
|
||||
## Environment Properties
|
||||
## Mod Properties
|
||||
|
||||
# The unique mod identifier for the mod. Must be lowercase in English locale. Must fit the regex [a-z][a-z0-9_]{1,63}
|
||||
# Must match the String constant located in the main mod class annotated with @Mod.
|
||||
mod_id=libzontreck
|
||||
|
@ -53,7 +46,7 @@ mod_name=Zontreck Library Mod
|
|||
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
|
||||
mod_license=GPLv3
|
||||
# The mod version. See https://semver.org/
|
||||
mod_version=1.10.011524.0045
|
||||
mod_version=1192.13.100924.2250
|
||||
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
|
||||
# This should match the base package used for the mod sources.
|
||||
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||
|
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
3
gradle/wrapper/gradle-wrapper.properties
vendored
3
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,5 +1,6 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
|
||||
networkTimeout=10000
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
|
12
gradlew
vendored
12
gradlew
vendored
|
@ -55,7 +55,7 @@
|
|||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
|
@ -80,11 +80,11 @@ do
|
|||
esac
|
||||
done
|
||||
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=${0##*/}
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
|
@ -143,16 +143,12 @@ fi
|
|||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
|
|
1
gradlew.bat
vendored
1
gradlew.bat
vendored
|
@ -26,7 +26,6 @@ if "%OS%"=="Windows_NT" setlocal
|
|||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
pluginManagement {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
maven { url = "https://maven.zontreck.com/repository/internal" }
|
||||
maven {
|
||||
name = 'MinecraftForge'
|
||||
url = 'https://maven.minecraftforge.net/'
|
||||
}
|
||||
maven { url = 'https://maven.parchmentmc.org' } // Add this line
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.5.0'
|
||||
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.7.0'
|
||||
}
|
||||
|
|
106
src/main/java/dev/zontreck/ariaslib/args/Argument.java
Normal file
106
src/main/java/dev/zontreck/ariaslib/args/Argument.java
Normal file
|
@ -0,0 +1,106 @@
|
|||
package dev.zontreck.ariaslib.args;
|
||||
|
||||
import dev.zontreck.ariaslib.exceptions.WrongArgumentTypeException;
|
||||
|
||||
public abstract class Argument<T> implements Cloneable
|
||||
{
|
||||
public boolean hasValue = false;
|
||||
public String name;
|
||||
|
||||
|
||||
/**
|
||||
* Initializes a boolean only command line toggle
|
||||
*
|
||||
* @param name The option name
|
||||
*/
|
||||
public Argument(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current argument's type
|
||||
*
|
||||
* @return The argument type!
|
||||
*/
|
||||
public abstract ArgumentType getType();
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the value.
|
||||
*
|
||||
* @return The value
|
||||
* @throws IllegalArgumentException When there is no value
|
||||
*/
|
||||
public T getValue() throws IllegalArgumentException {
|
||||
throw new IllegalArgumentException("No value");
|
||||
}
|
||||
|
||||
/**
|
||||
* Directly cast to the Argument type Long
|
||||
* @return
|
||||
* @throws WrongArgumentTypeException Throws when type does not match
|
||||
*/
|
||||
public LongArgument getAsLong() throws WrongArgumentTypeException {
|
||||
if(this instanceof LongArgument)
|
||||
{
|
||||
return (LongArgument) this;
|
||||
}
|
||||
|
||||
throw new WrongArgumentTypeException();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Directly cast to the Argument type String
|
||||
* @return
|
||||
* @throws WrongArgumentTypeException Throws when type does not match
|
||||
*/
|
||||
public StringArgument getAsString() throws WrongArgumentTypeException {
|
||||
if(this instanceof StringArgument)
|
||||
{
|
||||
return (StringArgument) this;
|
||||
}
|
||||
|
||||
throw new WrongArgumentTypeException();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Directly cast to the Argument type Integer
|
||||
* @return
|
||||
* @throws WrongArgumentTypeException Throws when type does not match
|
||||
*/
|
||||
public IntegerArgument getAsInteger() throws WrongArgumentTypeException
|
||||
{
|
||||
if(this instanceof IntegerArgument)
|
||||
{
|
||||
return (IntegerArgument) this;
|
||||
}
|
||||
|
||||
throw new WrongArgumentTypeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Argument<T> clone() {
|
||||
Argument<T> arg = null;
|
||||
try{
|
||||
|
||||
if(getType() == ArgumentType.LONG)
|
||||
{
|
||||
arg = (Argument<T>) new LongArgument(name, getAsLong().getValue());
|
||||
} else if(getType() == ArgumentType.STRING)
|
||||
{
|
||||
arg = (Argument<T>) new StringArgument(name, getAsString().getValue());
|
||||
} else if(getType() == ArgumentType.BOOLEAN) {
|
||||
arg = (Argument<T>) new BooleanArgument(name);
|
||||
} else if(getType() == ArgumentType.INTEGER){
|
||||
arg = (Argument<T>) new IntegerArgument(name, getAsInteger().getValue());
|
||||
}
|
||||
}catch (WrongArgumentTypeException ex)
|
||||
{
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
return arg;
|
||||
}
|
||||
}
|
25
src/main/java/dev/zontreck/ariaslib/args/ArgumentType.java
Normal file
25
src/main/java/dev/zontreck/ariaslib/args/ArgumentType.java
Normal file
|
@ -0,0 +1,25 @@
|
|||
package dev.zontreck.ariaslib.args;
|
||||
|
||||
public enum ArgumentType {
|
||||
/**
|
||||
* This indicates a string. It may possibly have a default value
|
||||
*/
|
||||
STRING,
|
||||
/**
|
||||
* This indicates a boolean
|
||||
* <p>
|
||||
* This may have a default value, which initiates a BooleanArgument
|
||||
*/
|
||||
BOOLEAN,
|
||||
|
||||
/**
|
||||
* This indicates a data type of integer
|
||||
* The type of integer arg is determined by the length of the integer.
|
||||
*/
|
||||
INTEGER,
|
||||
|
||||
/**
|
||||
* This is a long value, which can hold larger values than a integer. The type of integer arg is determined by the length of the integer.
|
||||
*/
|
||||
LONG
|
||||
}
|
63
src/main/java/dev/zontreck/ariaslib/args/Arguments.java
Normal file
63
src/main/java/dev/zontreck/ariaslib/args/Arguments.java
Normal file
|
@ -0,0 +1,63 @@
|
|||
package dev.zontreck.ariaslib.args;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class Arguments implements Cloneable
|
||||
{
|
||||
private Map<String, Argument<?>> args = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Set the argument in the args list
|
||||
* @param arg
|
||||
*/
|
||||
public void setArg(Argument arg) {
|
||||
args.put(arg.name, arg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for and returns the argument
|
||||
*
|
||||
* @param argName The argument's name
|
||||
* @return The argument instance, or null if not found
|
||||
*/
|
||||
public Argument getArg(String argName) {
|
||||
if (hasArg(argName))
|
||||
return args.get(argName);
|
||||
else return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the argument is set.
|
||||
*
|
||||
* @param argName The argument's name to check for
|
||||
* @return True if the argument is present. This does not indicate if the argument has a value
|
||||
*/
|
||||
public boolean hasArg(String argName) {
|
||||
return args.containsKey(argName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the argument (if it exists), for whether a value is set
|
||||
*
|
||||
* @param argName This is the argument name
|
||||
* @return True if a value is set
|
||||
* @throws IllegalArgumentException If there is no such argument
|
||||
*/
|
||||
public boolean argHasValue(String argName) throws IllegalArgumentException {
|
||||
if (hasArg(argName)) {
|
||||
return getArg(argName).hasValue;
|
||||
} else throw new IllegalArgumentException(("No such argument"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Arguments clone() {
|
||||
Arguments arg = new Arguments();
|
||||
for(Map.Entry<String, Argument<?>> entry : args.entrySet())
|
||||
{
|
||||
arg.setArg(entry.getValue().clone());
|
||||
}
|
||||
|
||||
return arg;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package dev.zontreck.ariaslib.args;
|
||||
|
||||
public class ArgumentsBuilder {
|
||||
private Arguments args = new Arguments();
|
||||
|
||||
public static ArgumentsBuilder builder() {
|
||||
return new ArgumentsBuilder();
|
||||
}
|
||||
|
||||
public ArgumentsBuilder withArgument(Argument arg) {
|
||||
args.setArg(arg);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Arguments build()
|
||||
{
|
||||
return args;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
package dev.zontreck.ariaslib.args;
|
||||
|
||||
public class ArgumentsParser {
|
||||
|
||||
/**
|
||||
* Parses and returns the arguments list with keeping defaults in mind
|
||||
* @param args
|
||||
* @param defaults
|
||||
* @return Arguments with defaults set
|
||||
*/
|
||||
public static Arguments parseArguments(String[] args, Arguments defaults) {
|
||||
Arguments arguments = defaults.clone();
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
Argument arg = parseArgument(args[i]);
|
||||
if (arg != null) {
|
||||
Argument defaultArg = null;
|
||||
if (defaults.hasArg(arg.name)) {
|
||||
defaultArg = defaults.getArg(arg.name);
|
||||
}
|
||||
|
||||
if (!arg.hasValue) {
|
||||
if (defaultArg != null) {
|
||||
arg = defaultArg;
|
||||
}
|
||||
}
|
||||
|
||||
arguments.setArg(arg);
|
||||
}
|
||||
}
|
||||
return arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses and returns an argument with a type set
|
||||
* @param arg The argument to parse with double tack
|
||||
* @return Typed Argument
|
||||
* @throws IllegalArgumentException when no type matches and the input is malformed in some way
|
||||
*/
|
||||
public static Argument parseArgument(String arg) {
|
||||
if (arg.startsWith("--")) {
|
||||
String[] parts = arg.split("=");
|
||||
String name = getNamePart(parts[0]);
|
||||
if (parts.length == 1) {
|
||||
return new BooleanArgument(name);
|
||||
|
||||
} else if (parts.length == 2) {
|
||||
String value = getValuePart(parts[1]);
|
||||
ArgumentType typeOfArg = getArgumentType(value);
|
||||
switch(typeOfArg)
|
||||
{
|
||||
case INTEGER:
|
||||
{
|
||||
return new IntegerArgument(name, Integer.parseInt(value));
|
||||
}
|
||||
case LONG:
|
||||
{
|
||||
return new LongArgument(name, Long.parseLong(value));
|
||||
}
|
||||
case BOOLEAN:
|
||||
{
|
||||
return new BooleanArgument(name);
|
||||
}
|
||||
default:
|
||||
{
|
||||
return new StringArgument(name, value);
|
||||
}
|
||||
}
|
||||
} else throw new IllegalArgumentException("The argument is malformed. Remember to use --arg=val, or --toggle");
|
||||
} else {
|
||||
throw new IllegalArgumentException("Not a valid argument format");
|
||||
}
|
||||
}
|
||||
|
||||
protected static String getNamePart(String entry) {
|
||||
return entry.substring(2);
|
||||
}
|
||||
|
||||
protected static String getValuePart(String entry) {
|
||||
return entry;
|
||||
}
|
||||
|
||||
protected static ArgumentType getArgumentType(String input) {
|
||||
try {
|
||||
Integer.parseInt(input);
|
||||
return ArgumentType.INTEGER;
|
||||
}catch(Exception e){}
|
||||
try{
|
||||
Long.parseLong(input);
|
||||
return ArgumentType.LONG;
|
||||
}catch(Exception E){
|
||||
|
||||
}
|
||||
|
||||
if(input.isEmpty())
|
||||
return ArgumentType.BOOLEAN;
|
||||
else return ArgumentType.STRING;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package dev.zontreck.ariaslib.args;
|
||||
|
||||
public class BooleanArgument extends Argument<Boolean> {
|
||||
private boolean value;
|
||||
|
||||
/**
|
||||
* Initializes a boolean only command line toggle
|
||||
*
|
||||
* @param name The option name
|
||||
*/
|
||||
public BooleanArgument(String name) {
|
||||
super(name);
|
||||
|
||||
this.hasValue = true;
|
||||
this.value = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArgumentType getType() {
|
||||
return ArgumentType.BOOLEAN;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BooleanArgument{" +
|
||||
name + "=true" +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package dev.zontreck.ariaslib.args;
|
||||
|
||||
public class IntegerArgument extends Argument<Integer> {
|
||||
private int value;
|
||||
|
||||
public IntegerArgument(String name, int value) {
|
||||
super(name);
|
||||
this.hasValue = true;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArgumentType getType() {
|
||||
return ArgumentType.INTEGER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "IntegerArgument{" +
|
||||
name + "=" +
|
||||
value +
|
||||
'}';
|
||||
}
|
||||
}
|
30
src/main/java/dev/zontreck/ariaslib/args/LongArgument.java
Normal file
30
src/main/java/dev/zontreck/ariaslib/args/LongArgument.java
Normal file
|
@ -0,0 +1,30 @@
|
|||
package dev.zontreck.ariaslib.args;
|
||||
|
||||
public class LongArgument extends Argument<Long> {
|
||||
private long value;
|
||||
|
||||
public LongArgument(String name, long value) {
|
||||
super(name);
|
||||
this.hasValue = true;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArgumentType getType() {
|
||||
return ArgumentType.LONG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LongArgument{" +
|
||||
name + "=" +
|
||||
value +
|
||||
'}';
|
||||
}
|
||||
}
|
30
src/main/java/dev/zontreck/ariaslib/args/StringArgument.java
Normal file
30
src/main/java/dev/zontreck/ariaslib/args/StringArgument.java
Normal file
|
@ -0,0 +1,30 @@
|
|||
package dev.zontreck.ariaslib.args;
|
||||
|
||||
public class StringArgument extends Argument<String> {
|
||||
|
||||
private String value;
|
||||
|
||||
public StringArgument(String name, String value) {
|
||||
super(name);
|
||||
this.value = value;
|
||||
this.hasValue = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArgumentType getType() {
|
||||
return ArgumentType.STRING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "StringArgument{" +
|
||||
name + "=" +
|
||||
value +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package dev.zontreck.ariaslib.exceptions;
|
||||
|
||||
public class EventRegistrationException extends Exception{
|
||||
public EventRegistrationException(String message){
|
||||
super(message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package dev.zontreck.ariaslib.exceptions;
|
||||
|
||||
|
||||
public class WrongArgumentTypeException extends Exception
|
||||
{
|
||||
|
||||
}
|
34
src/main/java/dev/zontreck/ariaslib/file/AriaIO.java
Normal file
34
src/main/java/dev/zontreck/ariaslib/file/AriaIO.java
Normal file
|
@ -0,0 +1,34 @@
|
|||
package dev.zontreck.ariaslib.file;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public class AriaIO {
|
||||
public static void write(Path fileName, Entry folder) {
|
||||
try {
|
||||
DataOutputStream dos = new DataOutputStream(new FileOutputStream(fileName.toFile()));
|
||||
folder.write(dos);
|
||||
dos.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Entry read(Path fileName) {
|
||||
try {
|
||||
DataInputStream dis = new DataInputStream(new FileInputStream(fileName.toFile()));
|
||||
return Entry.read(dis);
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Path resolveDataFile(String main) {
|
||||
return Paths.get(main + ".aria");
|
||||
}
|
||||
}
|
281
src/main/java/dev/zontreck/ariaslib/file/Entry.java
Normal file
281
src/main/java/dev/zontreck/ariaslib/file/Entry.java
Normal file
|
@ -0,0 +1,281 @@
|
|||
package dev.zontreck.ariaslib.file;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An entry in the serialized file
|
||||
*/
|
||||
public class Entry<K> {
|
||||
public static final byte YES = 1;
|
||||
public static final byte NO = 0;
|
||||
|
||||
public EntryType type;
|
||||
public String name;
|
||||
public K value;
|
||||
|
||||
public Entry(K v, String name) {
|
||||
value = v;
|
||||
this.name = name;
|
||||
if (v instanceof String) {
|
||||
type = EntryType.STRING;
|
||||
} else if (v instanceof Integer) {
|
||||
type = EntryType.INT;
|
||||
} else if (v instanceof List<?>) {
|
||||
type = EntryType.FOLDER;
|
||||
} else if (v instanceof Boolean) {
|
||||
type = EntryType.BOOL;
|
||||
} else if (v instanceof Long) {
|
||||
type = EntryType.LONG;
|
||||
} else if (v instanceof Short) {
|
||||
type = EntryType.SHORT;
|
||||
} else if (v instanceof Byte) {
|
||||
type = EntryType.BYTE;
|
||||
} else if (v instanceof Double) {
|
||||
type = EntryType.DOUBLE;
|
||||
} else if (v instanceof Float) {
|
||||
type = EntryType.FLOAT;
|
||||
} else if (v instanceof int[]) {
|
||||
type = EntryType.INT_ARRAY;
|
||||
} else if (v instanceof String[]) {
|
||||
type = EntryType.STRING_ARRAY;
|
||||
} else if (v instanceof byte[]) {
|
||||
type = EntryType.BYTE_ARRAY;
|
||||
} else if (v instanceof long[]) {
|
||||
type = EntryType.LONG_ARRAY;
|
||||
} else {
|
||||
type = EntryType.INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
private Entry() {
|
||||
}
|
||||
|
||||
public static Entry read(DataInputStream dis) throws IOException {
|
||||
EntryType et = EntryType.of(dis.readByte());
|
||||
int nameLen = dis.readInt();
|
||||
byte[] nm = new byte[nameLen];
|
||||
for (int i = 0; i < nameLen; i++) {
|
||||
nm[i] = dis.readByte();
|
||||
}
|
||||
Entry work = new Entry<>();
|
||||
work.type = et;
|
||||
work.name = new String(nm);
|
||||
//System.out.println("Read start: " + work.name + " [ " + work.type.toString() + " ]");
|
||||
|
||||
switch (et) {
|
||||
case FOLDER: {
|
||||
Entry<List<Entry>> entries = (Entry<List<Entry>>) work;
|
||||
entries.value = new ArrayList<>();
|
||||
|
||||
int numEntries = dis.readInt();
|
||||
for (int i = 0; i < numEntries; i++) {
|
||||
entries.value.add(Entry.read(dis));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case STRING: {
|
||||
Entry<String> w = (Entry<String>) work;
|
||||
int vLen = dis.readInt();
|
||||
byte[] x = new byte[vLen];
|
||||
for (int i = 0; i < vLen; i++) {
|
||||
x[i] = dis.readByte();
|
||||
}
|
||||
w.value = new String(x);
|
||||
break;
|
||||
}
|
||||
case INT: {
|
||||
Entry<Integer> w = (Entry<Integer>) work;
|
||||
w.value = dis.readInt();
|
||||
break;
|
||||
}
|
||||
case BOOL: {
|
||||
Entry<Boolean> w = (Entry<Boolean>) work;
|
||||
byte b = dis.readByte();
|
||||
if (b == YES) w.value = true;
|
||||
else w.value = false;
|
||||
|
||||
break;
|
||||
}
|
||||
case LONG: {
|
||||
Entry<Long> w = (Entry<Long>) work;
|
||||
w.value = dis.readLong();
|
||||
|
||||
break;
|
||||
}
|
||||
case SHORT: {
|
||||
Entry<Short> w = (Entry<Short>) work;
|
||||
w.value = dis.readShort();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case BYTE: {
|
||||
Entry<Byte> w = (Entry<Byte>) work;
|
||||
w.value = dis.readByte();
|
||||
break;
|
||||
}
|
||||
case DOUBLE: {
|
||||
Entry<Double> w = (Entry<Double>) work;
|
||||
w.value = dis.readDouble();
|
||||
break;
|
||||
}
|
||||
case FLOAT: {
|
||||
Entry<Float> w = (Entry<Float>) work;
|
||||
w.value = dis.readFloat();
|
||||
break;
|
||||
}
|
||||
case INT_ARRAY: {
|
||||
Entry<int[]> w = (Entry<int[]>) work;
|
||||
int num = dis.readInt();
|
||||
w.value = new int[num];
|
||||
|
||||
for (int i = 0; i < num; i++) {
|
||||
w.value[i] = dis.readInt();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case STRING_ARRAY: {
|
||||
Entry<String[]> w = (Entry<String[]>) work;
|
||||
int num = dis.readInt();
|
||||
w.value = new String[num];
|
||||
for (int i = 0; i < num; i++) {
|
||||
int len = dis.readInt();
|
||||
byte[] bStr = new byte[len];
|
||||
for (int j = 0; j < len; j++) {
|
||||
bStr[j] = dis.readByte();
|
||||
}
|
||||
w.value[i] = new String(bStr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BYTE_ARRAY: {
|
||||
Entry<byte[]> w = (Entry<byte[]>) work;
|
||||
int num = dis.readInt();
|
||||
w.value = new byte[num];
|
||||
for (int i = 0; i < num; i++) {
|
||||
w.value[i] = dis.readByte();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LONG_ARRAY: {
|
||||
Entry<long[]> w = (Entry<long[]>) work;
|
||||
int num = dis.readInt();
|
||||
w.value = new long[num];
|
||||
for (int i = 0; i < num; i++) {
|
||||
w.value[i] = dis.readLong();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//System.out.println("Read finished: " + work.name + " [ " + work.type.toString() + " ]");
|
||||
|
||||
return work;
|
||||
}
|
||||
|
||||
public void write(DataOutputStream dos) throws IOException {
|
||||
|
||||
dos.writeByte((int) type.value);
|
||||
byte[] nameBytes = name.getBytes();
|
||||
dos.writeInt(nameBytes.length);
|
||||
dos.write(nameBytes);
|
||||
|
||||
switch (type) {
|
||||
case FOLDER: {
|
||||
List<Entry<?>> entries = (List<Entry<?>>) value;
|
||||
dos.writeInt(entries.size());
|
||||
for (Entry<?> x :
|
||||
entries) {
|
||||
x.write(dos);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case STRING: {
|
||||
String s = (String) value;
|
||||
byte[] bS = s.getBytes();
|
||||
dos.writeInt(bS.length);
|
||||
dos.write(bS);
|
||||
|
||||
break;
|
||||
}
|
||||
case INT: {
|
||||
dos.writeInt((Integer) value);
|
||||
|
||||
break;
|
||||
}
|
||||
case BOOL: {
|
||||
boolean x = (Boolean) value;
|
||||
|
||||
if (x) dos.writeByte(YES);
|
||||
else dos.writeByte(NO);
|
||||
|
||||
break;
|
||||
}
|
||||
case LONG: {
|
||||
dos.writeLong((Long) value);
|
||||
|
||||
break;
|
||||
}
|
||||
case SHORT: {
|
||||
dos.writeShort((Short) value);
|
||||
|
||||
break;
|
||||
}
|
||||
case BYTE: {
|
||||
dos.write((Byte) value);
|
||||
break;
|
||||
}
|
||||
case DOUBLE: {
|
||||
dos.writeDouble((Double) value);
|
||||
break;
|
||||
}
|
||||
case FLOAT: {
|
||||
dos.writeFloat((Float) value);
|
||||
break;
|
||||
}
|
||||
case INT_ARRAY: {
|
||||
int[] arr = (int[]) value;
|
||||
dos.writeInt(arr.length);
|
||||
for (int x : arr
|
||||
) {
|
||||
dos.writeInt(x);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case STRING_ARRAY: {
|
||||
String[] arr = (String[]) value;
|
||||
dos.writeInt(arr.length);
|
||||
for (String s : arr) {
|
||||
byte[] bArr = s.getBytes();
|
||||
dos.writeInt(bArr.length);
|
||||
dos.write(bArr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BYTE_ARRAY: {
|
||||
byte[] arr = (byte[]) value;
|
||||
dos.writeInt(arr.length);
|
||||
for (byte b : arr) {
|
||||
dos.write(b);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LONG_ARRAY: {
|
||||
long[] arr = (long[]) value;
|
||||
dos.writeInt(arr.length);
|
||||
for (long L : arr) {
|
||||
dos.writeLong(L);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
36
src/main/java/dev/zontreck/ariaslib/file/EntryType.java
Normal file
36
src/main/java/dev/zontreck/ariaslib/file/EntryType.java
Normal file
|
@ -0,0 +1,36 @@
|
|||
package dev.zontreck.ariaslib.file;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public enum EntryType {
|
||||
FOLDER(0),
|
||||
STRING(1),
|
||||
INT(2),
|
||||
BOOL(3),
|
||||
LONG(4),
|
||||
SHORT(5),
|
||||
BYTE(6),
|
||||
DOUBLE(7),
|
||||
FLOAT(8),
|
||||
INT_ARRAY(9),
|
||||
STRING_ARRAY(10),
|
||||
BYTE_ARRAY(11),
|
||||
LONG_ARRAY(12),
|
||||
|
||||
INVALID(255);
|
||||
|
||||
public byte value;
|
||||
EntryType(int v)
|
||||
{
|
||||
value = (byte)v;
|
||||
}
|
||||
|
||||
public static EntryType of(byte b)
|
||||
{
|
||||
return Arrays.stream(values())
|
||||
.filter(c->c.value == b)
|
||||
.collect(Collectors.toList())
|
||||
.get(0);
|
||||
}
|
||||
}
|
118
src/main/java/dev/zontreck/ariaslib/file/EntryUtils.java
Normal file
118
src/main/java/dev/zontreck/ariaslib/file/EntryUtils.java
Normal file
|
@ -0,0 +1,118 @@
|
|||
package dev.zontreck.ariaslib.file;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class EntryUtils {
|
||||
public static Entry mkStr(String name, String value)
|
||||
{
|
||||
return new Entry<String>(value, name);
|
||||
}
|
||||
public static String getStr(Entry e)
|
||||
{
|
||||
Entry<String> eS = (Entry<String>) e;
|
||||
return eS.value;
|
||||
}
|
||||
public static Entry mkInt(String name, int value)
|
||||
{
|
||||
return new Entry<Integer>(value, name);
|
||||
}
|
||||
public static int getInt(Entry e)
|
||||
{
|
||||
Entry<Integer> eS = (Entry<Integer>) e;
|
||||
return eS.value;
|
||||
}
|
||||
public static Entry mkBool(String name, boolean value)
|
||||
{
|
||||
return new Entry<Boolean>(value, name);
|
||||
}
|
||||
public static boolean getBool(Entry e)
|
||||
{
|
||||
Entry<Boolean> eS = (Entry<Boolean>) e;
|
||||
return eS.value;
|
||||
}
|
||||
public static Entry mkLong(String name, long value)
|
||||
{
|
||||
return new Entry<Long>(value, name);
|
||||
}
|
||||
public static long getLong(Entry e)
|
||||
{
|
||||
Entry<Long> eS = (Entry<Long>) e;
|
||||
return eS.value;
|
||||
}
|
||||
public static Entry mkShort(String name, short value)
|
||||
{
|
||||
return new Entry<Short>(value, name);
|
||||
}
|
||||
public static short getShort(Entry e)
|
||||
{
|
||||
Entry<Short> eS = (Entry<Short>) e;
|
||||
return eS.value;
|
||||
}
|
||||
public static Entry mkByte(String name, byte value)
|
||||
{
|
||||
return new Entry<Byte>(value, name);
|
||||
}
|
||||
public static byte getByte(Entry e)
|
||||
{
|
||||
Entry<Byte> eS = (Entry<Byte>) e;
|
||||
return eS.value;
|
||||
}
|
||||
public static Entry mkDouble(String name, double value)
|
||||
{
|
||||
return new Entry<Double>(value, name);
|
||||
}
|
||||
public static double getDouble(Entry e)
|
||||
{
|
||||
Entry<Double> eS = (Entry<Double>) e;
|
||||
return eS.value;
|
||||
}
|
||||
public static Entry mkFloat(String name, float value)
|
||||
{
|
||||
return new Entry<Float>(value, name);
|
||||
}
|
||||
public static float getFloat(Entry e)
|
||||
{
|
||||
Entry<Float> eS = (Entry<Float>) e;
|
||||
return eS.value;
|
||||
}
|
||||
public static Entry mkIntArray(String name, int[] value)
|
||||
{
|
||||
return new Entry<int[]>(value, name);
|
||||
}
|
||||
public static int[] getIntArray(Entry e)
|
||||
{
|
||||
Entry<int[]> eS = (Entry<int[]>) e;
|
||||
return eS.value;
|
||||
}
|
||||
public static Entry mkStringArray(String name, String[] value)
|
||||
{
|
||||
return new Entry<String[]>(value, name);
|
||||
}
|
||||
public static String[] getStringArray(Entry e)
|
||||
{
|
||||
Entry<String[]> eS = (Entry<String[]>) e;
|
||||
return eS.value;
|
||||
}
|
||||
public static Entry mkByteArray(String name, byte[] value)
|
||||
{
|
||||
return new Entry<byte[]>(value, name);
|
||||
}
|
||||
public static byte[] getByteArray(Entry e)
|
||||
{
|
||||
Entry<byte[]> eS = (Entry<byte[]>) e;
|
||||
return eS.value;
|
||||
}
|
||||
public static Entry mkUUID(String name, UUID ID)
|
||||
{
|
||||
long[] uid = new long[2];
|
||||
uid[0] = ID.getLeastSignificantBits();
|
||||
uid[1] = ID.getMostSignificantBits();
|
||||
return new Entry<long[]>(uid, name);
|
||||
}
|
||||
|
||||
public static UUID getUUID(Entry e)
|
||||
{
|
||||
Entry<long[]> uid = (Entry<long[]>) e;
|
||||
return new UUID(uid.value[1], uid.value[0]);
|
||||
}
|
||||
}
|
42
src/main/java/dev/zontreck/ariaslib/file/Folder.java
Normal file
42
src/main/java/dev/zontreck/ariaslib/file/Folder.java
Normal file
|
@ -0,0 +1,42 @@
|
|||
package dev.zontreck.ariaslib.file;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class Folder
|
||||
{
|
||||
|
||||
public static void add(Entry e, Entry item)
|
||||
{
|
||||
((Entry<List<Entry>>)e).value.add(item);
|
||||
}
|
||||
|
||||
public static void remove(Entry e, Entry item)
|
||||
{
|
||||
((Entry<List<Entry>>)e).value.remove(item);
|
||||
}
|
||||
|
||||
public static Entry getEntry(Entry item, String name)
|
||||
{
|
||||
List<Entry> ret = ((Entry<List<Entry>>)item).value;
|
||||
if(ret.size()>0)
|
||||
{
|
||||
for (Entry ent :
|
||||
ret) {
|
||||
if(ent.name.equals(name))return ent;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int size(Entry e)
|
||||
{
|
||||
return ((Entry<List<Entry>>)e).value.size();
|
||||
}
|
||||
|
||||
public static Entry<List<Entry>> getNew(String name)
|
||||
{
|
||||
return new Entry<>(new ArrayList<Entry>(), name);
|
||||
}
|
||||
}
|
283
src/main/java/dev/zontreck/ariaslib/html/Bootstrap.java
Normal file
283
src/main/java/dev/zontreck/ariaslib/html/Bootstrap.java
Normal file
|
@ -0,0 +1,283 @@
|
|||
package dev.zontreck.ariaslib.html;
|
||||
|
||||
import dev.zontreck.ariaslib.html.bootstrap.Color;
|
||||
import dev.zontreck.ariaslib.html.bootstrap.Icons;
|
||||
import dev.zontreck.ariaslib.html.bootstrap.Size;
|
||||
import dev.zontreck.ariaslib.util.Percent;
|
||||
|
||||
public class Bootstrap {
|
||||
public static class Border {
|
||||
public Side side;
|
||||
public int width = 1;
|
||||
public boolean usesSides = false;
|
||||
public Colors colors;
|
||||
public boolean invert;
|
||||
|
||||
public static Border make() {
|
||||
return new Border();
|
||||
}
|
||||
|
||||
public Border withColor(Colors color) {
|
||||
this.colors = color.withPrefix("border");
|
||||
return this;
|
||||
}
|
||||
|
||||
public Border widthSide(Side side) {
|
||||
this.side = side;
|
||||
usesSides = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Border withWidth(int width) {
|
||||
this.width = width;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes borders instead of adding
|
||||
*/
|
||||
public Border setInverted() {
|
||||
invert = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void apply(HTMLElementBuilder elem) {
|
||||
elem.addClass("border");
|
||||
|
||||
colors.apply(elem);
|
||||
|
||||
if (usesSides) {
|
||||
elem.addClass("border-" + side.name().toLowerCase() + (invert ? "-0" : ""));
|
||||
} else {
|
||||
if (invert) elem.addClass("border-0");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public enum Side {
|
||||
Start,
|
||||
End,
|
||||
Top,
|
||||
Bottom
|
||||
}
|
||||
}
|
||||
|
||||
public static class Opacity {
|
||||
public Percent value;
|
||||
public String prefix;
|
||||
|
||||
public static Opacity make() {
|
||||
return new Opacity();
|
||||
}
|
||||
|
||||
public Opacity withPercent(Percent val) {
|
||||
value = val;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Opacity withPrefix(String pref) {
|
||||
this.prefix = pref;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void apply(HTMLElementBuilder builder) {
|
||||
builder.addClass((prefix != "" ? prefix + "-" : "") + "opacity-" + value.get());
|
||||
}
|
||||
}
|
||||
|
||||
public static class Colors {
|
||||
public Color color;
|
||||
public boolean emphasis;
|
||||
public boolean subtle;
|
||||
public String prefix;
|
||||
|
||||
public static Colors make() {
|
||||
return new Colors();
|
||||
}
|
||||
|
||||
public Colors withColor(Color color) {
|
||||
this.color = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Colors setEmphasis() {
|
||||
emphasis = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Colors setSubtle() {
|
||||
subtle = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Colors withPrefix(String prefix) {
|
||||
this.prefix = prefix;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void apply(HTMLElementBuilder builder) {
|
||||
builder.addClass(((prefix != "") ? prefix + "-" : "") + color.name().toLowerCase() + (emphasis ? "-emphasis" : "") + (subtle ? "-subtle" : ""));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Background {
|
||||
public Colors color;
|
||||
public Opacity opacity;
|
||||
public boolean gradient;
|
||||
|
||||
public static Background make() {
|
||||
return new Background();
|
||||
}
|
||||
|
||||
public Background withColor(Colors color) {
|
||||
this.color = color.withPrefix("bg");
|
||||
return this;
|
||||
}
|
||||
|
||||
public Background withOpacity(Opacity op) {
|
||||
this.opacity = op.withPrefix("bg");
|
||||
return this;
|
||||
}
|
||||
|
||||
public Background setGradient() {
|
||||
gradient = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public void apply(HTMLElementBuilder builder) {
|
||||
color.apply(builder);
|
||||
opacity.apply(builder);
|
||||
if (gradient)
|
||||
builder.addClass(".bg-gradient");
|
||||
}
|
||||
}
|
||||
|
||||
public static class Shadow {
|
||||
public Size size;
|
||||
|
||||
public static Shadow make() {
|
||||
return new Shadow();
|
||||
}
|
||||
|
||||
public Shadow withSize(Size size) {
|
||||
this.size = size;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void apply(HTMLElementBuilder builder) {
|
||||
builder.addClass("shadow" + size.sizeText());
|
||||
}
|
||||
}
|
||||
|
||||
public static class FocusRing {
|
||||
public Colors color;
|
||||
|
||||
public static FocusRing make() {
|
||||
return new FocusRing();
|
||||
}
|
||||
|
||||
public FocusRing withColor(Colors color) {
|
||||
this.color = color.withPrefix("focus-ring");
|
||||
return this;
|
||||
}
|
||||
|
||||
public void apply(HTMLElementBuilder builder) {
|
||||
builder.addClass("focus-ring");
|
||||
color.apply(builder);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Link {
|
||||
public Colors color;
|
||||
|
||||
public static Link make() {
|
||||
return new Link();
|
||||
}
|
||||
|
||||
public Link withColor(Colors color) {
|
||||
this.color = color.withPrefix("link");
|
||||
return this;
|
||||
}
|
||||
|
||||
public void apply(HTMLElementBuilder builder) {
|
||||
color.apply(builder);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Toast {
|
||||
public Icons icon;
|
||||
public HTMLElementBuilder toastHeader;
|
||||
public HTMLElementBuilder toastBody;
|
||||
|
||||
public Toast() {
|
||||
toastHeader = new HTMLElementBuilder("div").addClass("toast-header");
|
||||
toastHeader.addChild("svg").addClass("bi").addClass(icon.getClassName()).addClass("rounded");
|
||||
toastHeader.addChild("strong").addClass("me-auto");
|
||||
toastHeader.addChild("small").withText("Text?");
|
||||
toastHeader.addChild("button").withAttribute("type", "button").addClass("btn-close").withAttribute("data-bs-dismiss", "toast").withAttribute("aria-label", "Close");
|
||||
|
||||
toastBody = new HTMLElementBuilder("div").addClass("toast-body");
|
||||
}
|
||||
|
||||
public static Toast make() {
|
||||
return new Toast();
|
||||
}
|
||||
|
||||
public Toast withIcon(Icons icon) {
|
||||
this.icon = icon;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void apply(HTMLElementBuilder builder) {
|
||||
HTMLElementBuilder toast = builder.addChild("div").addClass("toast").withAttribute("role", "alert").withAttribute("aria-live", "assertive").withAttribute("aria-atomic", "true");
|
||||
toast.addChild(toastHeader);
|
||||
toast.addChild(toastBody);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Button {
|
||||
public Colors color;
|
||||
public boolean outline;
|
||||
public Size size;
|
||||
|
||||
public static Button make() {
|
||||
return new Button();
|
||||
}
|
||||
|
||||
public Button withColor(Colors color) {
|
||||
this.color = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Button setOutline() {
|
||||
outline = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Button withSize(Size size) {
|
||||
this.size = size;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public void apply(HTMLElementBuilder builder) {
|
||||
builder.addClass("btn");
|
||||
|
||||
if (outline) {
|
||||
color.withPrefix("btn-outline");
|
||||
} else color.withPrefix("btn");
|
||||
|
||||
color.apply(builder);
|
||||
if (size != Size.Regular)
|
||||
builder.addClass("btn" + size.sizeText());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Disabled {
|
||||
public static void setDisabled(HTMLElementBuilder builder) {
|
||||
builder.withAttribute("disabled");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package dev.zontreck.ariaslib.html;
|
||||
|
||||
// Class attribute class for HTML element classes
|
||||
class ClassAttribute extends HTMLAttribute {
|
||||
public ClassAttribute(String value) {
|
||||
super("class", value);
|
||||
}
|
||||
}
|
55
src/main/java/dev/zontreck/ariaslib/html/DOM.java
Normal file
55
src/main/java/dev/zontreck/ariaslib/html/DOM.java
Normal file
|
@ -0,0 +1,55 @@
|
|||
package dev.zontreck.ariaslib.html;
|
||||
|
||||
public class DOM {
|
||||
|
||||
|
||||
public static HTMLElementBuilder beginBootstrapDOM(String pageTitle) {
|
||||
HTMLElementBuilder builder = new HTMLElementBuilder("!doctype").withText("html");
|
||||
|
||||
HTMLElementBuilder html = builder.getOrCreate("html");
|
||||
|
||||
HTMLElementBuilder head = html.getOrCreate("head");
|
||||
|
||||
head.addChild("meta").withAttribute("charset", "utf-8");
|
||||
|
||||
head.addChild("meta").withAttribute("name", "viewport").withAttribute("content", "width=device-width, initial-scale=1");
|
||||
|
||||
head.getOrCreate("link").withAttribute("href", "https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css").withAttribute("integrity", "sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM").withAttribute("crossorigin", "anonymous").withAttribute("rel", "stylesheet");
|
||||
|
||||
head.addClass("link").withAttribute("rel", "stylesheet").withAttribute("href", "https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css");
|
||||
|
||||
head.getOrCreate("title").withText(pageTitle);
|
||||
|
||||
HTMLElementBuilder body = html.getOrCreate("body");
|
||||
body.addChild("script").withAttribute("src", "https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js").withAttribute("integrity", "sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz").withAttribute("crossorigin", "anonymous").withText(" ");
|
||||
|
||||
body.addChild("script").withAttribute("src", "https://code.jquery.com/jquery-3.7.0.min.js").withAttribute("crossorigin", "anonymous").withText(" ");
|
||||
|
||||
body.addChild("style").withText("\n" +
|
||||
" .command-popover{\n" +
|
||||
" --bs-popover-header-bg: var(--bs-info);\n" +
|
||||
" --bs-popover-header-color: var(--bs-dark);\n" +
|
||||
" --bs-popover-bg: var(--bs-dark);\n" +
|
||||
" --bs-popover-body-color: var(--bs-light);\n" +
|
||||
" }\n");
|
||||
|
||||
|
||||
return builder;
|
||||
|
||||
}
|
||||
|
||||
public static void addPopOverScan(HTMLElementBuilder builder) {
|
||||
builder.getChildByTagName("html").getChildByTagName("body").addChild("script").withText("" +
|
||||
"function scanPopOver()" +
|
||||
"{" +
|
||||
"var popoverTriggerList = document.querySelectorAll('[data-bs-toggle=\"popover\"]');\n" +
|
||||
"var popoverList = [...popoverTriggerList].map(popoverTriggerEl => new bootstrap.Popover(popoverTriggerEl));" +
|
||||
"" +
|
||||
"}");
|
||||
}
|
||||
|
||||
|
||||
public static String closeHTML() {
|
||||
return "</body></html>";
|
||||
}
|
||||
}
|
24
src/main/java/dev/zontreck/ariaslib/html/HTMLAttribute.java
Normal file
24
src/main/java/dev/zontreck/ariaslib/html/HTMLAttribute.java
Normal file
|
@ -0,0 +1,24 @@
|
|||
package dev.zontreck.ariaslib.html;
|
||||
|
||||
// Attribute class for HTML element attributes
|
||||
class HTMLAttribute {
|
||||
private String name;
|
||||
private String value;
|
||||
|
||||
public HTMLAttribute(String name, String value) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public HTMLAttribute(String name) {
|
||||
this(name, null);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
72
src/main/java/dev/zontreck/ariaslib/html/HTMLElement.java
Normal file
72
src/main/java/dev/zontreck/ariaslib/html/HTMLElement.java
Normal file
|
@ -0,0 +1,72 @@
|
|||
package dev.zontreck.ariaslib.html;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
// HTML element class supporting tag attributes
|
||||
public class HTMLElement {
|
||||
private String tagName;
|
||||
private String text;
|
||||
private List<HTMLAttribute> attributes;
|
||||
private List<HTMLElement> children;
|
||||
private boolean isEmptyElement;
|
||||
|
||||
public HTMLElement ( String tagName , String text , List<HTMLAttribute> attributes , List<HTMLElement> children , boolean isEmptyElement ) {
|
||||
this.tagName = tagName;
|
||||
this.text = text;
|
||||
this.attributes = attributes;
|
||||
this.children = children;
|
||||
this.isEmptyElement = isEmptyElement;
|
||||
}
|
||||
|
||||
public String getTagName ( ) {
|
||||
return tagName;
|
||||
}
|
||||
|
||||
public String generateHTML ( ) {
|
||||
StringBuilder builder = new StringBuilder ( );
|
||||
|
||||
if ( "!doctype".equalsIgnoreCase ( tagName ) ) {
|
||||
builder.append ( "<" ).append ( tagName ).append ( " " ).append ( text ).append ( ">\n" );
|
||||
for ( HTMLElement child : children ) {
|
||||
builder.append ( child.generateHTML ( ) );
|
||||
}
|
||||
return builder.toString ( );
|
||||
}
|
||||
|
||||
builder.append ( "<" ).append ( tagName );
|
||||
|
||||
for ( HTMLAttribute attribute : attributes ) {
|
||||
builder.append ( " " )
|
||||
.append ( attribute.getName ( ) );
|
||||
|
||||
String value = attribute.getValue ( );
|
||||
if ( value != null ) {
|
||||
builder.append ( "=\"" ).append ( value ).append ( "\"" );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if ( isEmptyElement ) {
|
||||
builder.append ( " />\n" );
|
||||
return builder.toString ( );
|
||||
}*/
|
||||
|
||||
builder.append ( ">" );
|
||||
|
||||
if ( text != null ) {
|
||||
builder.append ( text );
|
||||
}
|
||||
|
||||
if ( ! isEmptyElement ) {
|
||||
for ( HTMLElement child : children ) {
|
||||
builder.append ( child.generateHTML ( ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
builder.append ( "</" ).append ( tagName ).append ( ">\n" );
|
||||
|
||||
return builder.toString ( );
|
||||
}
|
||||
}
|
118
src/main/java/dev/zontreck/ariaslib/html/HTMLElementBuilder.java
Normal file
118
src/main/java/dev/zontreck/ariaslib/html/HTMLElementBuilder.java
Normal file
|
@ -0,0 +1,118 @@
|
|||
package dev.zontreck.ariaslib.html;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
// Builder class for building HTML elements
|
||||
public class HTMLElementBuilder {
|
||||
private String tagName;
|
||||
private String text;
|
||||
private List<HTMLAttribute> attributes;
|
||||
private List<HTMLElementBuilder> childElementBuilders;
|
||||
|
||||
public HTMLElementBuilder ( String tagName ) {
|
||||
this.tagName = tagName;
|
||||
this.attributes = new ArrayList<> ( );
|
||||
this.childElementBuilders = new ArrayList<> ( );
|
||||
}
|
||||
|
||||
public HTMLElementBuilder withText ( String text ) {
|
||||
this.text = text;
|
||||
return this;
|
||||
}
|
||||
|
||||
public HTMLElementBuilder withAttribute ( String name , String value ) {
|
||||
HTMLAttribute attribute = new HTMLAttribute ( name , value );
|
||||
this.attributes.add ( attribute );
|
||||
return this;
|
||||
}
|
||||
|
||||
public HTMLElementBuilder withAttribute ( String name ) {
|
||||
HTMLAttribute attribute = new HTMLAttribute ( name );
|
||||
this.attributes.add ( attribute );
|
||||
return this;
|
||||
}
|
||||
|
||||
public HTMLElementBuilder addClass ( String className ) {
|
||||
ClassAttribute classAttribute = getClassAttribute ( );
|
||||
if ( classAttribute == null ) {
|
||||
classAttribute = new ClassAttribute ( className );
|
||||
this.attributes.add ( classAttribute );
|
||||
}
|
||||
else {
|
||||
String existingValue = classAttribute.getValue ( );
|
||||
classAttribute = new ClassAttribute ( existingValue + " " + className );
|
||||
this.attributes.removeIf ( attr -> attr.getName ( ).equalsIgnoreCase ( "class" ) );
|
||||
this.attributes.add ( classAttribute );
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private ClassAttribute getClassAttribute ( ) {
|
||||
for ( HTMLAttribute attribute : attributes ) {
|
||||
if ( attribute instanceof ClassAttribute ) {
|
||||
return ( ClassAttribute ) attribute;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public HTMLElementBuilder addChild ( HTMLElementBuilder childBuilder ) {
|
||||
childElementBuilders.add ( childBuilder );
|
||||
return this;
|
||||
}
|
||||
|
||||
public HTMLElementBuilder addChild ( String tagName ) {
|
||||
HTMLElementBuilder childBuilder = new HTMLElementBuilder ( tagName );
|
||||
childElementBuilders.add ( childBuilder );
|
||||
return childBuilder;
|
||||
}
|
||||
|
||||
public HTMLElementBuilder getOrCreate ( String tagName ) {
|
||||
HTMLElementBuilder childBuilder = getChildByTagName ( tagName );
|
||||
if ( childBuilder == null ) {
|
||||
childBuilder = addChild ( tagName );
|
||||
}
|
||||
return childBuilder;
|
||||
}
|
||||
|
||||
public HTMLElementBuilder getChildByTagName ( String tagName ) {
|
||||
return getChildByTagName ( tagName , 0 );
|
||||
}
|
||||
|
||||
public HTMLElementBuilder getChildByTagName ( String tagName , int index ) {
|
||||
List<HTMLElementBuilder> matchingChildBuilders = new ArrayList<> ( );
|
||||
|
||||
for ( HTMLElementBuilder builder : childElementBuilders ) {
|
||||
if ( builder.tagName.equalsIgnoreCase ( tagName ) ) {
|
||||
matchingChildBuilders.add ( builder );
|
||||
}
|
||||
}
|
||||
|
||||
if ( matchingChildBuilders.size ( ) > index ) {
|
||||
return matchingChildBuilders.get ( index );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean hasTextOrChildren ( ) {
|
||||
return text != null || ! childElementBuilders.isEmpty ( );
|
||||
}
|
||||
|
||||
public HTMLElement build ( ) {
|
||||
List<HTMLElement> children = buildChildren ( );
|
||||
boolean isEmptyElement = ! hasTextOrChildren ( );
|
||||
return new HTMLElement ( tagName , text , attributes , children , isEmptyElement );
|
||||
}
|
||||
|
||||
private List<HTMLElement> buildChildren ( ) {
|
||||
List<HTMLElement> children = new ArrayList<> ( );
|
||||
|
||||
for ( HTMLElementBuilder builder : childElementBuilders ) {
|
||||
children.add ( builder.build ( ) );
|
||||
}
|
||||
|
||||
return children;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package dev.zontreck.ariaslib.html.bootstrap;
|
||||
|
||||
public enum Color
|
||||
{
|
||||
/**
|
||||
* Dark Blue
|
||||
*/
|
||||
Primary,
|
||||
|
||||
/**
|
||||
* Dark Gray
|
||||
*/
|
||||
Secondary,
|
||||
|
||||
/**
|
||||
* Dark Green
|
||||
*/
|
||||
Success,
|
||||
|
||||
/**
|
||||
* Dark Red
|
||||
*/
|
||||
Danger,
|
||||
|
||||
/**
|
||||
* Yellow
|
||||
*/
|
||||
Warning,
|
||||
|
||||
/**
|
||||
* Light Blue
|
||||
*/
|
||||
Info,
|
||||
|
||||
/**
|
||||
* Black
|
||||
*/
|
||||
Dark,
|
||||
|
||||
/**
|
||||
* Semi-gray
|
||||
*/
|
||||
Light,
|
||||
Black,
|
||||
White
|
||||
}
|
1969
src/main/java/dev/zontreck/ariaslib/html/bootstrap/Icons.java
Normal file
1969
src/main/java/dev/zontreck/ariaslib/html/bootstrap/Icons.java
Normal file
File diff suppressed because it is too large
Load diff
25
src/main/java/dev/zontreck/ariaslib/html/bootstrap/Size.java
Normal file
25
src/main/java/dev/zontreck/ariaslib/html/bootstrap/Size.java
Normal file
|
@ -0,0 +1,25 @@
|
|||
package dev.zontreck.ariaslib.html.bootstrap;
|
||||
|
||||
public enum Size {
|
||||
Small,
|
||||
Regular,
|
||||
Large,
|
||||
None;
|
||||
|
||||
public String sizeText() {
|
||||
switch (this) {
|
||||
case Small:
|
||||
return "-sm";
|
||||
|
||||
case None:
|
||||
return "-none";
|
||||
|
||||
case Large:
|
||||
return "-lg";
|
||||
|
||||
default:
|
||||
return "";
|
||||
|
||||
}
|
||||
}
|
||||
}
|
9
src/main/java/dev/zontreck/ariaslib/http/HTTPMethod.java
Normal file
9
src/main/java/dev/zontreck/ariaslib/http/HTTPMethod.java
Normal file
|
@ -0,0 +1,9 @@
|
|||
package dev.zontreck.ariaslib.http;
|
||||
|
||||
public enum HTTPMethod
|
||||
{
|
||||
GET,
|
||||
POST,
|
||||
PUT,
|
||||
DELETE
|
||||
}
|
15
src/main/java/dev/zontreck/ariaslib/http/HTTPRequest.java
Normal file
15
src/main/java/dev/zontreck/ariaslib/http/HTTPRequest.java
Normal file
|
@ -0,0 +1,15 @@
|
|||
package dev.zontreck.ariaslib.http;
|
||||
|
||||
public class HTTPRequest
|
||||
{
|
||||
|
||||
public String url;
|
||||
|
||||
public String method;
|
||||
public String body;
|
||||
public String contentType;
|
||||
|
||||
protected HTTPRequest(){
|
||||
|
||||
}
|
||||
}
|
134
src/main/java/dev/zontreck/ariaslib/http/HTTPRequestBuilder.java
Normal file
134
src/main/java/dev/zontreck/ariaslib/http/HTTPRequestBuilder.java
Normal file
|
@ -0,0 +1,134 @@
|
|||
package dev.zontreck.ariaslib.http;
|
||||
|
||||
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
public class HTTPRequestBuilder
|
||||
{
|
||||
|
||||
private HttpURLConnection connection;
|
||||
private URL url;
|
||||
private HTTPRequest request = new HTTPRequest();
|
||||
|
||||
public static HTTPRequestBuilder builder()
|
||||
{
|
||||
return new HTTPRequestBuilder();
|
||||
}
|
||||
|
||||
protected HTTPRequestBuilder()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the url in this request to the one supplied
|
||||
* @param url The url to connect to
|
||||
* @return Builder instance
|
||||
* @throws MalformedURLException If the URL supplied was invalid
|
||||
*/
|
||||
public HTTPRequestBuilder withURL( String url) throws MalformedURLException {
|
||||
request.url = url;
|
||||
this.url = new URL(url);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the HTTP Request method
|
||||
* @param method The method you want to use
|
||||
* @see HTTPMethod
|
||||
* @return Builder instance
|
||||
*/
|
||||
public HTTPRequestBuilder withMethod(HTTPMethod method)
|
||||
{
|
||||
switch(method)
|
||||
{
|
||||
case GET:
|
||||
{
|
||||
request.method = "GET";
|
||||
break;
|
||||
}
|
||||
case POST: {
|
||||
request.method = "POST";
|
||||
if(request.contentType.isEmpty()) request.contentType = "application/x-www-form-urlencoded";
|
||||
break;
|
||||
}
|
||||
case DELETE:{
|
||||
request.method = "DELETE";
|
||||
break;
|
||||
}
|
||||
case PUT:{
|
||||
request.method = "PUT";
|
||||
if(request.contentType.isEmpty()) request.contentType = "application/x-www-form-urlencoded";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the request body. This may only be processed by the server when using POST or PUT, depending on the server's setup
|
||||
* @param body The body to upload
|
||||
* @return Builder Instance
|
||||
*/
|
||||
public HTTPRequestBuilder withBody(String body)
|
||||
{
|
||||
request.body = body;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the content type header
|
||||
* Default: application/x-www-form-urlencoded for POST/PUT, and null/not present for GET
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
public HTTPRequestBuilder withContentType(String type)
|
||||
{
|
||||
request.contentType = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
public HTTPResponse build()
|
||||
{
|
||||
try {
|
||||
connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod(request.method);
|
||||
byte[] array = request.body.getBytes("UTF-8");
|
||||
connection.setRequestProperty("Content-Length" , "" + array.length);
|
||||
connection.setRequestProperty("Content-Type", request.contentType);
|
||||
connection.setDoInput(true);
|
||||
connection.setUseCaches(false);
|
||||
connection.setDoOutput(true);
|
||||
DataOutputStream dos = new DataOutputStream(connection.getOutputStream());
|
||||
dos.write(array);
|
||||
dos.flush();
|
||||
dos.close();
|
||||
|
||||
|
||||
// Get the response body
|
||||
InputStream inputStream = connection.getInputStream();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
StringBuilder response = new StringBuilder();
|
||||
String line;
|
||||
|
||||
while ((line = reader.readLine()) != null) {
|
||||
response.append(line);
|
||||
}
|
||||
reader.close();
|
||||
inputStream.close();
|
||||
|
||||
String responseBody = response.toString();
|
||||
|
||||
return new HTTPResponse(connection.getContentType(), connection.getResponseCode(), responseBody, request);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}finally {
|
||||
connection.disconnect();
|
||||
}
|
||||
}
|
||||
}
|
33
src/main/java/dev/zontreck/ariaslib/http/HTTPResponse.java
Normal file
33
src/main/java/dev/zontreck/ariaslib/http/HTTPResponse.java
Normal file
|
@ -0,0 +1,33 @@
|
|||
package dev.zontreck.ariaslib.http;
|
||||
|
||||
public class HTTPResponse
|
||||
{
|
||||
private String ContentType;
|
||||
private int ResponseCode;
|
||||
private String ResponseBody;
|
||||
private HTTPRequest OriginalRequest;
|
||||
|
||||
protected HTTPResponse(String contentType, int code, String body, HTTPRequest request){
|
||||
this.ContentType = contentType;
|
||||
this.ResponseCode = code;
|
||||
this.ResponseBody = body;
|
||||
this.OriginalRequest = request;
|
||||
|
||||
}
|
||||
|
||||
public String getContentType() {
|
||||
return ContentType;
|
||||
}
|
||||
|
||||
public int getResponseCode() {
|
||||
return ResponseCode;
|
||||
}
|
||||
|
||||
public String getResponseBody() {
|
||||
return ResponseBody;
|
||||
}
|
||||
|
||||
public HTTPRequest getOriginalRequest() {
|
||||
return OriginalRequest;
|
||||
}
|
||||
}
|
15
src/main/java/dev/zontreck/ariaslib/json/Completed.java
Normal file
15
src/main/java/dev/zontreck/ariaslib/json/Completed.java
Normal file
|
@ -0,0 +1,15 @@
|
|||
package dev.zontreck.ariaslib.json;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Serialization or Deserialization has completed.
|
||||
*
|
||||
* The method takes 1 argument.
|
||||
*
|
||||
* Boolean: True for deserialization.
|
||||
*/
|
||||
@Retention ( RetentionPolicy.RUNTIME )
|
||||
public @interface Completed {
|
||||
}
|
11
src/main/java/dev/zontreck/ariaslib/json/DynSerial.java
Normal file
11
src/main/java/dev/zontreck/ariaslib/json/DynSerial.java
Normal file
|
@ -0,0 +1,11 @@
|
|||
package dev.zontreck.ariaslib.json;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Used on a class to indicate that it is serializable by the dynamic serializer.
|
||||
*/
|
||||
@Retention ( RetentionPolicy.RUNTIME )
|
||||
public @interface DynSerial {
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
package dev.zontreck.ariaslib.json;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Deserializes objects!
|
||||
* <p>
|
||||
* YOU MUST HAVE A NO-PARAMETER CONSTRUCTOR
|
||||
*/
|
||||
public class DynamicDeserializer {
|
||||
/**
|
||||
* Constructs and deserializes an object from serialized data
|
||||
*/
|
||||
public static <T> T doDeserialize ( Class<T> clazz , byte[] data ) throws Exception {
|
||||
ByteArrayInputStream BAIS = new ByteArrayInputStream ( data );
|
||||
return deserialize ( ( Map<String, Object> ) JsonObject.parseJSON ( BAIS ).getMap ( ) , clazz );
|
||||
}
|
||||
|
||||
private static <T> T deserialize ( Map<String, Object> map , Class<T> clazz ) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
|
||||
if ( ! clazz.isAnnotationPresent ( DynSerial.class ) )
|
||||
return null;
|
||||
|
||||
T object = clazz.getDeclaredConstructor ( ).newInstance ( );
|
||||
|
||||
Field[] fields = clazz.getDeclaredFields ( );
|
||||
for ( Field field : fields ) {
|
||||
field.setAccessible ( true );
|
||||
|
||||
if ( field.isAnnotationPresent ( IgnoreSerialization.class ) )
|
||||
continue;
|
||||
|
||||
try {
|
||||
if ( List.class.isAssignableFrom ( field.getType ( ) ) ) {
|
||||
Class<?> listType = getListType ( field );
|
||||
List<Object> list = new ArrayList<> ( );
|
||||
List<?> serializedList = ( List<?> ) map.get ( field.getName ( ) );
|
||||
if ( serializedList != null ) {
|
||||
for ( Object listItem : serializedList ) {
|
||||
if ( listType.isAnnotationPresent ( DynSerial.class ) ) {
|
||||
Object deserializedItem = deserialize ( ( Map<String, Object> ) listItem , listType );
|
||||
list.add ( deserializedItem );
|
||||
}
|
||||
else {
|
||||
list.add ( listItem );
|
||||
}
|
||||
}
|
||||
}
|
||||
field.set ( object , list );
|
||||
}
|
||||
else if ( Map.class.isAssignableFrom ( field.getType ( ) ) ) {
|
||||
Class<?> valueType = getMapValueType ( field );
|
||||
Map<String, Object> serializedMap = ( Map<String, Object> ) map.get ( field.getName ( ) );
|
||||
if ( serializedMap != null ) {
|
||||
Map<String, Object> mapValue = new HashMap<> ( );
|
||||
for ( Map.Entry<String, Object> entry : serializedMap.entrySet ( ) ) {
|
||||
Object deserializedValue;
|
||||
if ( valueType.isAnnotationPresent ( DynSerial.class ) ) {
|
||||
deserializedValue = deserialize ( ( Map<String, Object> ) entry.getValue ( ) , valueType );
|
||||
}
|
||||
else {
|
||||
deserializedValue = entry.getValue ( );
|
||||
}
|
||||
mapValue.put ( entry.getKey ( ) , deserializedValue );
|
||||
}
|
||||
field.set ( object , mapValue );
|
||||
}
|
||||
}
|
||||
else if ( ! field.getType ( ).isAnnotationPresent ( DynSerial.class ) ) {
|
||||
field.set ( object , map.get ( field.getName ( ) ) );
|
||||
}
|
||||
else {
|
||||
Object tmp = deserialize ( ( Map<String, Object> ) map.get ( field.getName ( ) ) , field.getType ( ) );
|
||||
field.set ( object , tmp );
|
||||
}
|
||||
} catch ( Exception e ) {
|
||||
// Handle any exceptions during deserialization
|
||||
}
|
||||
}
|
||||
|
||||
Method[] methods = clazz.getDeclaredMethods ( );
|
||||
for ( Method method : methods ) {
|
||||
if ( method.isAnnotationPresent ( Completed.class ) ) {
|
||||
method.invoke ( object , true );
|
||||
}
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
|
||||
private static Class<?> getListType ( Field field ) {
|
||||
Type genericType = field.getGenericType ( );
|
||||
if ( genericType instanceof ParameterizedType ) {
|
||||
ParameterizedType paramType = ( ParameterizedType ) genericType;
|
||||
Type[] actualTypeArgs = paramType.getActualTypeArguments ( );
|
||||
if ( actualTypeArgs.length > 0 ) {
|
||||
return ( Class<?> ) actualTypeArgs[ 0 ];
|
||||
}
|
||||
}
|
||||
return Object.class;
|
||||
}
|
||||
|
||||
private static Class<?> getMapValueType ( Field field ) {
|
||||
Type genericType = field.getGenericType ( );
|
||||
if ( genericType instanceof ParameterizedType ) {
|
||||
ParameterizedType paramType = ( ParameterizedType ) genericType;
|
||||
Type[] actualTypeArgs = paramType.getActualTypeArguments ( );
|
||||
if ( actualTypeArgs.length > 1 ) {
|
||||
return ( Class<?> ) actualTypeArgs[ 1 ];
|
||||
}
|
||||
}
|
||||
return Object.class;
|
||||
}
|
||||
}
|
115
src/main/java/dev/zontreck/ariaslib/json/DynamicSerializer.java
Normal file
115
src/main/java/dev/zontreck/ariaslib/json/DynamicSerializer.java
Normal file
|
@ -0,0 +1,115 @@
|
|||
package dev.zontreck.ariaslib.json;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class DynamicSerializer {
|
||||
/**
|
||||
* Serializes the object instance
|
||||
*
|
||||
* @param inst The class object to serialize
|
||||
* @return A byte array of serialized data
|
||||
*/
|
||||
public static byte[] doSerialize(Object inst) throws InvocationTargetException, IllegalAccessException {
|
||||
Map<String, Object> ret = serialize(inst);
|
||||
|
||||
JsonObject js = new JsonObject(ret);
|
||||
|
||||
return js.toJSONString().getBytes();
|
||||
}
|
||||
|
||||
private static Map<String, Object> serialize(Object inst) throws InvocationTargetException, IllegalAccessException {
|
||||
Class<?> clazz = inst.getClass();
|
||||
if (!clazz.isAnnotationPresent(DynSerial.class))
|
||||
return null;
|
||||
Method[] mth = clazz.getDeclaredMethods();
|
||||
Method onComplete = null;
|
||||
for (
|
||||
Method mt :
|
||||
mth
|
||||
) {
|
||||
if (mt.isAnnotationPresent(PreSerialize.class)) {
|
||||
mt.invoke(inst);
|
||||
}
|
||||
|
||||
if (mt.isAnnotationPresent(Completed.class))
|
||||
onComplete = mt;
|
||||
}
|
||||
|
||||
Field[] fields = clazz.getDeclaredFields();
|
||||
Map<String, Object> ret = new HashMap<>();
|
||||
for (
|
||||
Field field :
|
||||
fields
|
||||
) {
|
||||
field.setAccessible(true);
|
||||
if (field.isAnnotationPresent(IgnoreSerialization.class))
|
||||
continue;
|
||||
|
||||
Object fieldVal = field.get(inst);
|
||||
if (fieldVal == null) continue;
|
||||
|
||||
String fieldName = field.getName();
|
||||
|
||||
if (field.isAnnotationPresent(ListOrMap.class)) {
|
||||
// Special handling for List and Map types
|
||||
ret.put(fieldName, serializeCollectionOrMap(fieldVal));
|
||||
continue;
|
||||
}
|
||||
if (!(fieldVal.getClass().isAnnotationPresent(DynSerial.class))) {
|
||||
// Special handler for List and Map is needed right here.
|
||||
if (fieldVal instanceof List || fieldVal instanceof Map) continue;
|
||||
|
||||
ret.put(fieldName, fieldVal);
|
||||
} else {
|
||||
Map<String, Object> TMP = serialize(fieldVal);
|
||||
ret.put(fieldName, TMP);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (onComplete != null)
|
||||
onComplete.invoke(inst, false);
|
||||
|
||||
return ret;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Object serializeCollectionOrMap(Object collectionOrMap) throws InvocationTargetException, IllegalAccessException {
|
||||
if (collectionOrMap instanceof List<?>) {
|
||||
List<?> list = (List<?>) collectionOrMap;
|
||||
List<Object> serializedList = new ArrayList<>();
|
||||
for (Object item : list) {
|
||||
if (item.getClass().isAnnotationPresent(DynSerial.class)) {
|
||||
serializedList.add(serialize(item));
|
||||
} else {
|
||||
serializedList.add(item);
|
||||
}
|
||||
}
|
||||
return serializedList;
|
||||
} else if (collectionOrMap instanceof Map<?, ?>) {
|
||||
Map<?, ?> mp = (Map<?, ?>) collectionOrMap;
|
||||
Map<String, Object> map = (Map<String, Object>) mp;
|
||||
Map<String, Object> serializedMap = new HashMap<>();
|
||||
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
if (value.getClass().isAnnotationPresent(DynSerial.class)) {
|
||||
value = serialize(value);
|
||||
}
|
||||
serializedMap.put(key, value);
|
||||
}
|
||||
return serializedMap;
|
||||
}
|
||||
return collectionOrMap;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package dev.zontreck.ariaslib.json;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* Marks an element to be ignored completely by the serializer or deserializer.
|
||||
*/
|
||||
@Retention ( RetentionPolicy.RUNTIME )
|
||||
public @interface IgnoreSerialization
|
||||
{
|
||||
}
|
183
src/main/java/dev/zontreck/ariaslib/json/JsonObject.java
Normal file
183
src/main/java/dev/zontreck/ariaslib/json/JsonObject.java
Normal file
|
@ -0,0 +1,183 @@
|
|||
package dev.zontreck.ariaslib.json;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class JsonObject {
|
||||
private Map<String, Object> data;
|
||||
|
||||
public JsonObject() {
|
||||
data = new HashMap<>();
|
||||
}
|
||||
|
||||
public JsonObject(Map<String, Object> dat) {
|
||||
data = new HashMap<>(dat);
|
||||
}
|
||||
|
||||
public static JsonObject parseJSON(InputStream inputStream) throws IOException {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
StringBuilder jsonString = new StringBuilder();
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
jsonString.append(line);
|
||||
}
|
||||
return parseJsonObject(jsonString.toString());
|
||||
}
|
||||
|
||||
private static JsonObject parseJsonObject(String jsonString) {
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
jsonString = jsonString.trim();
|
||||
if (jsonString.startsWith("{") && jsonString.endsWith("}")) {
|
||||
jsonString = jsonString.substring(1, jsonString.length() - 1);
|
||||
String[] keyValuePairs = jsonString.split(",");
|
||||
for (String pair : keyValuePairs) {
|
||||
String[] keyValue = pair.split(":");
|
||||
if (keyValue.length == 2) {
|
||||
String key = keyValue[0].trim().replace("\"", "");
|
||||
String value = keyValue[1].trim();
|
||||
jsonObject.put(key, parseValue(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
private static Object parseValue(String value) {
|
||||
if (value.startsWith("{") && value.endsWith("}")) {
|
||||
return parseJsonObject(value);
|
||||
} else if (value.startsWith("[") && value.endsWith("]")) {
|
||||
return parseJSONArray(value);
|
||||
} else if (value.startsWith("\"") && value.endsWith("\"")) {
|
||||
return value.substring(1, value.length() - 1);
|
||||
} else if (value.equalsIgnoreCase("true")) {
|
||||
return true;
|
||||
} else if (value.equalsIgnoreCase("false")) {
|
||||
return false;
|
||||
} else if (value.equalsIgnoreCase("null")) {
|
||||
return null;
|
||||
} else {
|
||||
try {
|
||||
return Integer.parseInt(value);
|
||||
} catch (NumberFormatException e) {
|
||||
try {
|
||||
return Double.parseDouble(value);
|
||||
} catch (NumberFormatException ex) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Object> parseJSONArray(String jsonArray) {
|
||||
List<Object> list = new ArrayList<>();
|
||||
jsonArray = jsonArray.trim();
|
||||
if (jsonArray.startsWith("[") && jsonArray.endsWith("]")) {
|
||||
jsonArray = jsonArray.substring(1, jsonArray.length() - 1);
|
||||
String[] elements = jsonArray.split(",");
|
||||
for (String element : elements) {
|
||||
list.add(parseValue(element.trim()));
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public void put(String key, Object value) {
|
||||
data.put(key, value);
|
||||
}
|
||||
|
||||
public Object get(String key) {
|
||||
return data.get(key);
|
||||
}
|
||||
|
||||
public void merge(Map<String, Object> ret) {
|
||||
data.putAll(ret);
|
||||
}
|
||||
|
||||
public Map<String, Object> getMap() {
|
||||
return new HashMap<>(data);
|
||||
}
|
||||
|
||||
public void add(String key, Object value) {
|
||||
if (data.containsKey(key)) {
|
||||
Object existingValue = data.get(key);
|
||||
if (existingValue instanceof List) {
|
||||
((List<Object>) existingValue).add(value);
|
||||
} else {
|
||||
List<Object> list = new ArrayList<>();
|
||||
list.add(existingValue);
|
||||
list.add(value);
|
||||
data.put(key, list);
|
||||
}
|
||||
} else {
|
||||
data.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
public String toJSONString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("{");
|
||||
|
||||
boolean first = true;
|
||||
for (Map.Entry<String, Object> entry : data.entrySet()) {
|
||||
if (!first) {
|
||||
sb.append(",");
|
||||
}
|
||||
first = false;
|
||||
|
||||
sb.append("\"");
|
||||
sb.append(escape(entry.getKey()));
|
||||
sb.append("\":");
|
||||
sb.append(toJSONValue(entry.getValue()));
|
||||
}
|
||||
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String escape(String str) {
|
||||
if (str == null) return "";
|
||||
// Add necessary escape characters (e.g., double quotes, backslashes)
|
||||
// You can implement this method based on your specific requirements.
|
||||
// This is a simplified version for demonstration purposes.
|
||||
return str.replace("\"", "\\\"");
|
||||
}
|
||||
|
||||
private String toJSONValue(Object value) {
|
||||
if (value instanceof String) {
|
||||
return "\"" + escape(value.toString()) + "\"";
|
||||
} else if (value instanceof JsonObject) {
|
||||
return ((JsonObject) value).toJSONString();
|
||||
} else if (value instanceof List) {
|
||||
return toJSONList((List<Object>) value);
|
||||
} else if (value instanceof Map<?, ?>) {
|
||||
return new JsonObject((Map<String, Object>) ((Map<?, ?>) value)).toJSONString();
|
||||
} else {
|
||||
return value.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private String toJSONList(List<Object> list) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("[");
|
||||
|
||||
boolean first = true;
|
||||
for (Object item : list) {
|
||||
if (!first) {
|
||||
sb.append(",");
|
||||
}
|
||||
first = false;
|
||||
|
||||
sb.append(toJSONValue(item));
|
||||
}
|
||||
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
8
src/main/java/dev/zontreck/ariaslib/json/ListOrMap.java
Normal file
8
src/main/java/dev/zontreck/ariaslib/json/ListOrMap.java
Normal file
|
@ -0,0 +1,8 @@
|
|||
package dev.zontreck.ariaslib.json;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention ( RetentionPolicy.RUNTIME )
|
||||
public @interface ListOrMap {
|
||||
}
|
13
src/main/java/dev/zontreck/ariaslib/json/PreSerialize.java
Normal file
13
src/main/java/dev/zontreck/ariaslib/json/PreSerialize.java
Normal file
|
@ -0,0 +1,13 @@
|
|||
package dev.zontreck.ariaslib.json;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* To be set on a method, and will invoke that method prior to serialization beginning.
|
||||
*
|
||||
* Preparations should be made here
|
||||
*/
|
||||
@Retention ( RetentionPolicy.RUNTIME )
|
||||
public @interface PreSerialize {
|
||||
}
|
47
src/main/java/dev/zontreck/ariaslib/terminal/Banners.java
Normal file
47
src/main/java/dev/zontreck/ariaslib/terminal/Banners.java
Normal file
|
@ -0,0 +1,47 @@
|
|||
package dev.zontreck.ariaslib.terminal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Banners
|
||||
{
|
||||
|
||||
public static String generateBanner(String text) {
|
||||
int maxLength = calculateMaxLength(text);
|
||||
List<String> bannerLines = new ArrayList<>();
|
||||
StringBuilder border = new StringBuilder();
|
||||
for (int i = 0; i < maxLength + 4; i++) {
|
||||
border.append("*");
|
||||
}
|
||||
bannerLines.add(border.toString());
|
||||
bannerLines.add("* " + centerText(text, maxLength) + " *");
|
||||
bannerLines.add(border.toString());
|
||||
return String.join("\n", bannerLines);
|
||||
}
|
||||
|
||||
private static String centerText(String text, int maxLength) {
|
||||
StringBuilder centeredText = new StringBuilder();
|
||||
int spacesToAdd = (maxLength - text.length()) / 2;
|
||||
for (int i = 0; i < spacesToAdd; i++) {
|
||||
centeredText.append(" ");
|
||||
}
|
||||
centeredText.append(text);
|
||||
for (int i = 0; i < spacesToAdd; i++) {
|
||||
centeredText.append(" ");
|
||||
}
|
||||
if (centeredText.length() < maxLength) {
|
||||
centeredText.append(" ");
|
||||
}
|
||||
return centeredText.toString();
|
||||
}
|
||||
|
||||
private static int calculateMaxLength(String text) {
|
||||
int maxLength = 0;
|
||||
for (String line : text.split("\n")) {
|
||||
if (line.length() > maxLength) {
|
||||
maxLength = line.length();
|
||||
}
|
||||
}
|
||||
return maxLength;
|
||||
}
|
||||
}
|
88
src/main/java/dev/zontreck/ariaslib/terminal/Task.java
Normal file
88
src/main/java/dev/zontreck/ariaslib/terminal/Task.java
Normal file
|
@ -0,0 +1,88 @@
|
|||
package dev.zontreck.ariaslib.terminal;
|
||||
|
||||
import dev.zontreck.ariaslib.util.DelayedExecutorService;
|
||||
import dev.zontreck.ariaslib.util.EnvironmentUtils;
|
||||
import dev.zontreck.ariaslib.util.Progress;
|
||||
|
||||
import java.util.TimerTask;
|
||||
|
||||
public abstract class Task extends TimerTask implements Runnable {
|
||||
public final String TASK_NAME;
|
||||
private TaskCompletionToken token = new TaskCompletionToken ( );
|
||||
|
||||
public static final String CHECK = "P";
|
||||
public static final String FAIL = "F";
|
||||
// Else use the progress spinner from the Progress class
|
||||
private boolean isSilent = false;
|
||||
|
||||
public Task ( String name ) {
|
||||
TASK_NAME = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* This constructor is meant to be used to create silent tasks that do not output to the console. (Example usage: DelayedExecutionService)
|
||||
*
|
||||
* @param name Task name
|
||||
* @param silent Whether to print to the terminal
|
||||
*/
|
||||
public Task ( String name , boolean silent ) {
|
||||
this ( name );
|
||||
isSilent = silent;
|
||||
}
|
||||
|
||||
|
||||
public boolean isComplete ( ) {
|
||||
return token.get ( );
|
||||
}
|
||||
|
||||
public void startTask ( ) {
|
||||
Thread tx = new Thread(this);
|
||||
tx.start();
|
||||
|
||||
if(! isSilent && !EnvironmentUtils.isRunningInsideDocker())
|
||||
{
|
||||
Thread tx2 = new Thread(new SpinnerTask(token, this));
|
||||
tx2.start();
|
||||
}
|
||||
}
|
||||
|
||||
public void stopTask ( ) {
|
||||
if ( token.get ( ) && ! isSilent ) {
|
||||
System.out.printf ( "\r" + TASK_NAME + "\t\t[" + token.status + "]\n" );
|
||||
}
|
||||
}
|
||||
|
||||
public void setSuccess ( ) {
|
||||
token.completed ( CHECK );
|
||||
}
|
||||
|
||||
public void setFail ( ) {
|
||||
token.completed ( FAIL );
|
||||
}
|
||||
|
||||
public class SpinnerTask extends Task {
|
||||
public final Task task;
|
||||
public final TaskCompletionToken token;
|
||||
private final Progress spinner = new Progress ( 100 );
|
||||
|
||||
public SpinnerTask ( TaskCompletionToken token , Task parent ) {
|
||||
super ( "spinner" , true );
|
||||
this.token = token;
|
||||
this.task = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run ( ) {
|
||||
while ( ! task.isComplete ( ) ) {
|
||||
try {
|
||||
Thread.sleep ( 50L );
|
||||
|
||||
if ( ! task.isSilent && ! task.isComplete ( ) && ! EnvironmentUtils.isRunningInsideDocker ( ) )
|
||||
System.out.printf ( "\r" + task.TASK_NAME + "\t\t" + spinner.getSpinnerTick ( ) + "\r" );
|
||||
} catch ( Exception e ) {
|
||||
e.printStackTrace ( );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package dev.zontreck.ariaslib.terminal;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* Should not be re-used for multiple tasks!!!
|
||||
*/
|
||||
public class TaskCompletionToken
|
||||
{
|
||||
private AtomicBoolean complete = new AtomicBoolean(false);
|
||||
public String status = "";
|
||||
public void completed(String reason){
|
||||
status=reason;
|
||||
complete.set(true);
|
||||
}
|
||||
|
||||
public boolean get(){
|
||||
return complete.get();
|
||||
}
|
||||
}
|
35
src/main/java/dev/zontreck/ariaslib/terminal/Terminal.java
Normal file
35
src/main/java/dev/zontreck/ariaslib/terminal/Terminal.java
Normal file
|
@ -0,0 +1,35 @@
|
|||
package dev.zontreck.ariaslib.terminal;
|
||||
|
||||
import dev.zontreck.ariaslib.util.EnvironmentUtils;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class Terminal {
|
||||
private static final AtomicInteger ID = new AtomicInteger ( 0 );
|
||||
private static final AtomicBoolean running = new AtomicBoolean ( true );
|
||||
public static String PREFIX = "";
|
||||
|
||||
/**
|
||||
* This starts a terminal instance
|
||||
*
|
||||
* @return The terminal ID
|
||||
*/
|
||||
public static int startTerminal ( ) {
|
||||
if ( EnvironmentUtils.isRunningInsideDocker ( ) )
|
||||
return 0;
|
||||
running.set ( true );
|
||||
//DelayedExecutorService.getInstance ( ).schedule ( new ConsolePrompt ( ) , 1 );
|
||||
|
||||
|
||||
return ID.getAndIncrement ( );
|
||||
}
|
||||
|
||||
public static boolean isRunning ( ) {
|
||||
return running.get ( );
|
||||
}
|
||||
|
||||
public static void setRunning ( boolean running ) {
|
||||
Terminal.running.set ( running );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package dev.zontreck.ariaslib.util;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import dev.zontreck.ariaslib.terminal.Task;
|
||||
import dev.zontreck.ariaslib.terminal.Terminal;
|
||||
|
||||
@Deprecated
|
||||
public class DelayedExecutorService {
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package dev.zontreck.ariaslib.util;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class EnvironmentUtils {
|
||||
public static boolean isRunningInsideDocker ( ) {
|
||||
if ( Files.exists ( Paths.get ( "/.dockerenv" ) ) )
|
||||
return true;
|
||||
try {
|
||||
Stream<String> str = Files.lines ( Paths.get ( "/proc/1/cgroup" ) );
|
||||
return str.anyMatch ( ln -> ln.contains ( "/docker" ) );
|
||||
} catch ( IOException e ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
51
src/main/java/dev/zontreck/ariaslib/util/FileIO.java
Normal file
51
src/main/java/dev/zontreck/ariaslib/util/FileIO.java
Normal file
|
@ -0,0 +1,51 @@
|
|||
package dev.zontreck.ariaslib.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public class FileIO
|
||||
{
|
||||
|
||||
public static String readFile(String filePath) {
|
||||
try {
|
||||
byte[] fileBytes = Files.readAllBytes(Paths.get(filePath));
|
||||
return new String(fileBytes);
|
||||
} catch (IOException e) {
|
||||
return "An error occurred: " + e.getMessage();
|
||||
}
|
||||
}
|
||||
public static void writeFile(String filePath, String newContent) {
|
||||
try {
|
||||
Files.write(Paths.get(filePath), newContent.getBytes());
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Recursively delete a directory
|
||||
* @param directory The folder to delete
|
||||
*/
|
||||
public static void deleteDirectory(File directory) {
|
||||
if (directory.exists()) {
|
||||
File[] files = directory.listFiles();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
if (file.isDirectory()) {
|
||||
deleteDirectory(file);
|
||||
} else {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Now directory is empty, so delete it
|
||||
directory.delete();
|
||||
System.out.println("Directory deleted: " + directory.getAbsolutePath());
|
||||
} else {
|
||||
System.out.println("Directory does not exist: " + directory.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
120
src/main/java/dev/zontreck/ariaslib/util/Hashing.java
Normal file
120
src/main/java/dev/zontreck/ariaslib/util/Hashing.java
Normal file
|
@ -0,0 +1,120 @@
|
|||
package dev.zontreck.ariaslib.util;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class Hashing
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* A md5 hashing function that is compatible with literally every other hashing function out there
|
||||
* @param input The string to hash
|
||||
* @return The hash
|
||||
*/
|
||||
public static String md5(String input) {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
md.update(input.getBytes());
|
||||
|
||||
byte[] byteData = md.digest();
|
||||
|
||||
// Convert the byte array to a hexadecimal string
|
||||
StringBuilder hexString = new StringBuilder();
|
||||
for (byte aByteData : byteData) {
|
||||
String hex = Integer.toHexString(0xff & aByteData);
|
||||
if (hex.length() == 1) {
|
||||
hexString.append('0');
|
||||
}
|
||||
hexString.append(hex);
|
||||
}
|
||||
return hexString.toString();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* A md5 hashing function that is compatible with literally every other hashing function out there
|
||||
* @param input The bytes to hash
|
||||
* @return The hash
|
||||
*/
|
||||
public static String md5(byte[] input) {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
md.update(input);
|
||||
|
||||
byte[] byteData = md.digest();
|
||||
|
||||
// Convert the byte array to a hexadecimal string
|
||||
StringBuilder hexString = new StringBuilder();
|
||||
for (byte aByteData : byteData) {
|
||||
String hex = Integer.toHexString(0xff & aByteData);
|
||||
if (hex.length() == 1) {
|
||||
hexString.append('0');
|
||||
}
|
||||
hexString.append(hex);
|
||||
}
|
||||
return hexString.toString();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A sha256 hashing function that is compatible with literally every other hashing function out there
|
||||
* @param input The string to hash
|
||||
* @return The hash
|
||||
*/
|
||||
public static String sha256(String input) {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("SHA256");
|
||||
md.update(input.getBytes());
|
||||
|
||||
byte[] byteData = md.digest();
|
||||
|
||||
// Convert the byte array to a hexadecimal string
|
||||
StringBuilder hexString = new StringBuilder();
|
||||
for (byte aByteData : byteData) {
|
||||
String hex = Integer.toHexString(0xff & aByteData);
|
||||
if (hex.length() == 1) {
|
||||
hexString.append('0');
|
||||
}
|
||||
hexString.append(hex);
|
||||
}
|
||||
return hexString.toString();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* A sha256 hashing function that is compatible with literally every other hashing function out there
|
||||
* @param input The bytes to hash
|
||||
* @return The hash
|
||||
*/
|
||||
public static String sha256(byte[] input) {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("SHA256");
|
||||
md.update(input);
|
||||
|
||||
byte[] byteData = md.digest();
|
||||
|
||||
// Convert the byte array to a hexadecimal string
|
||||
StringBuilder hexString = new StringBuilder();
|
||||
for (byte aByteData : byteData) {
|
||||
String hex = Integer.toHexString(0xff & aByteData);
|
||||
if (hex.length() == 1) {
|
||||
hexString.append('0');
|
||||
}
|
||||
hexString.append(hex);
|
||||
}
|
||||
return hexString.toString();
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
94
src/main/java/dev/zontreck/ariaslib/util/Lists.java
Normal file
94
src/main/java/dev/zontreck/ariaslib/util/Lists.java
Normal file
|
@ -0,0 +1,94 @@
|
|||
package dev.zontreck.ariaslib.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class Lists
|
||||
{
|
||||
/**
|
||||
* Programatically constructs a list
|
||||
* @param values The list of values
|
||||
* @return The new list
|
||||
* @param <T> An arbitrary type parameter
|
||||
*/
|
||||
public static <T> List<T> of(T... values)
|
||||
{
|
||||
List<T> arr = new ArrayList<>();
|
||||
for(T value : values)
|
||||
{
|
||||
arr.add(value);
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Splits a string into a list
|
||||
* @param input The string to split
|
||||
* @param delimiters The list of delimiters
|
||||
* @return A non-strided list
|
||||
*/
|
||||
public static List<String> split(String input, String... delimiters) {
|
||||
List<String> result = new ArrayList<>();
|
||||
StringBuilder regex = new StringBuilder("(");
|
||||
|
||||
// Constructing the regular expression pattern with provided delimiters
|
||||
for (String delimiter : delimiters) {
|
||||
regex.append(delimiter).append("|");
|
||||
}
|
||||
regex.deleteCharAt(regex.length() - 1); // Remove the extra '|' character
|
||||
regex.append(")");
|
||||
|
||||
String[] tokens = input.split(regex.toString());
|
||||
|
||||
// Add non-empty tokens to the result list
|
||||
for (String token : tokens) {
|
||||
if (!token.isEmpty()) {
|
||||
result.add(token);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Split a string, and keep the delimiters
|
||||
* @param input The string to be parsed and split
|
||||
* @param delimiters A list of delimiters
|
||||
* @return A strided list containing the parsed options, and the delimiters
|
||||
*/
|
||||
public static List<String> splitWithDelim(String input, String... delimiters) {
|
||||
List<String> result = new ArrayList<>();
|
||||
StringBuilder regex = new StringBuilder("(");
|
||||
|
||||
// Constructing the regular expression pattern with provided delimiters
|
||||
for (String delimiter : delimiters) {
|
||||
regex.append(delimiter).append("|");
|
||||
}
|
||||
regex.deleteCharAt(regex.length() - 1); // Remove the extra '|' character
|
||||
regex.append(")");
|
||||
|
||||
// Splitting the input string using the regex pattern
|
||||
String[] tokens = input.split(regex.toString());
|
||||
|
||||
// Adding tokens and delimiters to the result list in a strided manner
|
||||
for (int i = 0; i < tokens.length; i++) {
|
||||
if (!tokens[i].isEmpty()) {
|
||||
result.add(tokens[i]);
|
||||
}
|
||||
// Adding delimiter if it exists and it's not the last token
|
||||
if (i < tokens.length - 1) {
|
||||
result.add(input.substring(input.indexOf(tokens[i]) + tokens[i].length(), input.indexOf(tokens[i + 1])));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private Lists(){
|
||||
|
||||
}
|
||||
}
|
49
src/main/java/dev/zontreck/ariaslib/util/Maps.java
Normal file
49
src/main/java/dev/zontreck/ariaslib/util/Maps.java
Normal file
|
@ -0,0 +1,49 @@
|
|||
package dev.zontreck.ariaslib.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Utility class to assist in creating a dictionary programmatically in one line of code.
|
||||
*/
|
||||
public class Maps
|
||||
{
|
||||
/**
|
||||
* This takes a list of entries and returns a HashMap
|
||||
* @param entries The entries you want in your hashmap
|
||||
* @return The map itself
|
||||
* @param <A> Any typed parameter
|
||||
* @param <B> Any typed parameter
|
||||
*/
|
||||
public static <A,B> Map<A,B> of(Entry<A,B>... entries) {
|
||||
Map<A,B> map = new HashMap<>();
|
||||
for(Entry<A,B> E : entries)
|
||||
{
|
||||
map.put(E.key, E.value);
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* A virtual entry used only by the Maps#of function.
|
||||
* @see Maps#of(Entry[])
|
||||
* @param <A> Any typed parameter
|
||||
* @param <B> Any typed parameter
|
||||
*/
|
||||
public static class Entry<A,B> {
|
||||
public final A key;
|
||||
public final B value;
|
||||
|
||||
/**
|
||||
* Initializes the readonly entry
|
||||
* @param a The dictionary key
|
||||
* @param b The value
|
||||
*/
|
||||
public Entry(A a, B b)
|
||||
{
|
||||
this.key=a;
|
||||
this.value=b;
|
||||
}
|
||||
}
|
||||
}
|
18
src/main/java/dev/zontreck/ariaslib/util/MathUtil.java
Normal file
18
src/main/java/dev/zontreck/ariaslib/util/MathUtil.java
Normal file
|
@ -0,0 +1,18 @@
|
|||
package dev.zontreck.ariaslib.util;
|
||||
|
||||
/**
|
||||
* This class will be used to house math helper functions
|
||||
*/
|
||||
public class MathUtil
|
||||
{
|
||||
/**
|
||||
* A newer helper function to get the percentage with large number support
|
||||
* @param current Min value
|
||||
* @param max Maximum value for progress
|
||||
* @return Percentage
|
||||
*/
|
||||
public static int getPercent(long current, long max)
|
||||
{
|
||||
return Math.round(current*100/max);
|
||||
}
|
||||
}
|
23
src/main/java/dev/zontreck/ariaslib/util/Percent.java
Normal file
23
src/main/java/dev/zontreck/ariaslib/util/Percent.java
Normal file
|
@ -0,0 +1,23 @@
|
|||
package dev.zontreck.ariaslib.util;
|
||||
|
||||
import java.io.PrintStream;
|
||||
|
||||
public class Percent
|
||||
{
|
||||
int current;
|
||||
int maximum;
|
||||
|
||||
public Percent(int cur, int max)
|
||||
{
|
||||
current=cur;
|
||||
maximum=max;
|
||||
}
|
||||
|
||||
|
||||
public int get()
|
||||
{
|
||||
return ((current * 100) / maximum);
|
||||
}
|
||||
|
||||
|
||||
}
|
56
src/main/java/dev/zontreck/ariaslib/util/Progress.java
Normal file
56
src/main/java/dev/zontreck/ariaslib/util/Progress.java
Normal file
|
@ -0,0 +1,56 @@
|
|||
package dev.zontreck.ariaslib.util;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class Progress
|
||||
{
|
||||
private int maximum;
|
||||
private int current;
|
||||
private AtomicInteger tickNum = new AtomicInteger(0);
|
||||
private static final String TICKS="-\\|/";
|
||||
|
||||
public String getSpinnerTick()
|
||||
{
|
||||
if(tickNum.get()>=TICKS.length()) tickNum.set(0);
|
||||
|
||||
return "[" + TICKS.substring(tickNum.getAndIncrement(), tickNum.get()) + "]";
|
||||
}
|
||||
|
||||
public Progress(int maximum)
|
||||
{
|
||||
current=0;
|
||||
this.maximum=maximum;
|
||||
}
|
||||
|
||||
public int getPercent(){
|
||||
return (current*100/maximum);
|
||||
}
|
||||
|
||||
public String getPercentStr()
|
||||
{
|
||||
return (getPercent()+"%");
|
||||
}
|
||||
|
||||
public static int getPercentOf(int current, int max)
|
||||
{
|
||||
return (current*100/max);
|
||||
}
|
||||
|
||||
public void increment(){
|
||||
current++;
|
||||
sanity();
|
||||
}
|
||||
private void sanity(){
|
||||
if(current > maximum) current = maximum;
|
||||
if(current < 0)current = 0;
|
||||
}
|
||||
public void decrement(){
|
||||
current--;
|
||||
sanity();
|
||||
}
|
||||
|
||||
public void setCurrent(int cur)
|
||||
{
|
||||
current=cur;
|
||||
}
|
||||
}
|
66
src/main/java/dev/zontreck/ariaslib/util/ProgressBar.java
Normal file
66
src/main/java/dev/zontreck/ariaslib/util/ProgressBar.java
Normal file
|
@ -0,0 +1,66 @@
|
|||
package dev.zontreck.ariaslib.util;
|
||||
|
||||
import java.io.PrintStream;
|
||||
|
||||
/**
|
||||
* Utility to create an ascii progress bar
|
||||
*/
|
||||
public class ProgressBar
|
||||
{
|
||||
|
||||
private static final int DEFAULT_BAR_WIDTH = 50;
|
||||
|
||||
/**
|
||||
* Reserved spaces for the brackets, and the carrot, and the percent value.
|
||||
*/
|
||||
private static final int PROGRESS_BAR_RESERVED=5;
|
||||
|
||||
/**
|
||||
* Always will return 80
|
||||
* @return 80
|
||||
*/
|
||||
private static int getConsoleWidth() {
|
||||
return 80; // Default console width, can be adjusted for different consoles
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a progress bar
|
||||
* <br><br>
|
||||
* your text here [========= ] 40% your text here
|
||||
* @param percent The percentage
|
||||
* @param beforeText
|
||||
* @param afterText
|
||||
* @return ProgressBar as a String
|
||||
*/
|
||||
public static String printProgressBar(int percent, String beforeText, String afterText) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int consoleWidth = getConsoleWidth();
|
||||
int barWidth = Math.min(consoleWidth - beforeText.length() - afterText.length() - PROGRESS_BAR_RESERVED, DEFAULT_BAR_WIDTH);
|
||||
|
||||
// Calculate progress
|
||||
int progressBarLength = (int) ((double) percent / 100 * barWidth);
|
||||
|
||||
// Print before text
|
||||
sb.append(beforeText);
|
||||
|
||||
// Print progress bar
|
||||
sb.append("[");
|
||||
for (int i = 0; i < barWidth; i++) {
|
||||
if (i < progressBarLength) {
|
||||
sb.append("=");
|
||||
}else if(i==progressBarLength) sb.append(">");
|
||||
else {
|
||||
sb.append(" ");
|
||||
}
|
||||
}
|
||||
sb.append("]");
|
||||
|
||||
// Print percentage
|
||||
sb.append(" " + percent + "%");
|
||||
|
||||
// Print after text
|
||||
sb.append(afterText);
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
161
src/main/java/dev/zontreck/ariaslib/util/TimeNotation.java
Normal file
161
src/main/java/dev/zontreck/ariaslib/util/TimeNotation.java
Normal file
|
@ -0,0 +1,161 @@
|
|||
package dev.zontreck.ariaslib.util;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Contains useful structures and functions for dealing with, and manipulation of, time.
|
||||
*/
|
||||
public class TimeNotation
|
||||
{
|
||||
public int Years;
|
||||
public int Months;
|
||||
public int Weeks;
|
||||
public int Days;
|
||||
public int Hours;
|
||||
public int Minutes;
|
||||
public int Seconds;
|
||||
|
||||
public TimeNotation(int years, int months, int weeks, int days, int hours, int minutes, int seconds)
|
||||
{
|
||||
Years=years;
|
||||
Months=months;
|
||||
Weeks=weeks;
|
||||
Days=days;
|
||||
Hours=hours;
|
||||
Minutes=minutes;
|
||||
Seconds = seconds;
|
||||
}
|
||||
|
||||
private TimeNotation(){}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String str =
|
||||
someOrNone(Years,Pluralize(Years, "year") + ", ") +
|
||||
someOrNone(Months, Pluralize(Months, "month") + ", ") +
|
||||
someOrNone(Weeks, Pluralize(Weeks, "week") + ", ") +
|
||||
someOrNone(Days, Pluralize(Days, "day") + ", ") +
|
||||
someOrNone(Hours, Pluralize(Hours, "hour") + ", ") +
|
||||
someOrNone(Minutes, Pluralize(Minutes, "minute") + ", ") +
|
||||
someOrNone(Seconds, Pluralize(Seconds, "second"));
|
||||
|
||||
if(str == ""){
|
||||
return "No Seconds";
|
||||
} else return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a plural version for a number
|
||||
* @param num The number to prefix
|
||||
* @param str The singular form of the string
|
||||
* @return Combined string, num + str in plural form if necessary
|
||||
*/
|
||||
private String Pluralize(int num, String str)
|
||||
{
|
||||
return num + " " + ((num > 1) ? str+"s" : str);
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple function to test a number, return a string, or return nothing at all.
|
||||
* @param num The number to check
|
||||
* @param str The string to return if the number is greater than zero
|
||||
* @return Str if num >1, or empty string
|
||||
*/
|
||||
private String someOrNone(int num, String str)
|
||||
{
|
||||
if(num > 0) return str;
|
||||
else return "";
|
||||
}
|
||||
/**
|
||||
* A simple function to test a number, return a string, or return something else.
|
||||
* @param num The number to check
|
||||
* @param str The string to return if the number is greater than zero
|
||||
* @return Str if num >1, or other string
|
||||
*/
|
||||
private String someOrOther(int num, String str, String other)
|
||||
{
|
||||
if(num > 0) return str;
|
||||
else return other;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes time notation!
|
||||
* @return A program readable string that can be decoded back to a time notation
|
||||
*/
|
||||
public String toNotation()
|
||||
{
|
||||
return Years + "Y" + Months + "M" + Weeks + "W" + Days + "d" + Hours + "h" + Minutes + "m" + Seconds + "s";
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a time notation string
|
||||
* @param notation Serialized time notation
|
||||
* @return The deserialized time notation object
|
||||
*/
|
||||
public static TimeNotation fromNotation(String notation)
|
||||
{
|
||||
TimeNotation notationX = new TimeNotation();
|
||||
String[] delims = new String[]{"Y", "M", "W", "d", "h", "m", "s"};
|
||||
List<String> opts = Lists.split(notation, delims);
|
||||
|
||||
|
||||
int index = 0;
|
||||
for(String dlim : delims)
|
||||
{
|
||||
if(notation.contains(dlim))
|
||||
{
|
||||
switch (dlim)
|
||||
{
|
||||
case "Y":
|
||||
{
|
||||
notationX.Years = Integer.parseInt(opts.get(index));
|
||||
|
||||
break;
|
||||
}
|
||||
case "M":
|
||||
{
|
||||
notationX.Months = Integer.parseInt(opts.get(index));
|
||||
|
||||
break;
|
||||
}
|
||||
case "W":
|
||||
{
|
||||
notationX.Weeks = Integer.parseInt(opts.get(index));
|
||||
|
||||
break;
|
||||
}
|
||||
case "d":
|
||||
{
|
||||
notationX.Days = Integer.parseInt(opts.get(index));
|
||||
|
||||
break;
|
||||
}
|
||||
case "h":
|
||||
{
|
||||
notationX.Hours = Integer.parseInt(opts.get(index));
|
||||
|
||||
break;
|
||||
}
|
||||
case "m":
|
||||
{
|
||||
notationX.Minutes = Integer.parseInt(opts.get(index));
|
||||
|
||||
break;
|
||||
}
|
||||
case "s":
|
||||
{
|
||||
notationX.Seconds = Integer.parseInt(opts.get(index));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
return notationX;
|
||||
|
||||
}
|
||||
}
|
96
src/main/java/dev/zontreck/ariaslib/util/TimeUtil.java
Normal file
96
src/main/java/dev/zontreck/ariaslib/util/TimeUtil.java
Normal file
|
@ -0,0 +1,96 @@
|
|||
package dev.zontreck.ariaslib.util;
|
||||
|
||||
/**
|
||||
* This class is a helper with some minecraft specific functions
|
||||
*/
|
||||
public class TimeUtil
|
||||
{
|
||||
/**
|
||||
* Converts seconds to ticks. (seconds*ticks)
|
||||
* @param seconds Number of seconds
|
||||
* @param ticks Number of ticks in a single second
|
||||
* @return Number of ticks
|
||||
*/
|
||||
public static int secondsToTicks(int seconds, int ticks)
|
||||
{
|
||||
return seconds*ticks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the number of ticks to seconds
|
||||
* @param ticks The number of ticks to convert
|
||||
* @param ticksInASecond The number of ticks in a single second
|
||||
* @return Number of seconds
|
||||
*/
|
||||
public static int ticksToSeconds(int ticks, int ticksInASecond)
|
||||
{
|
||||
return ticks / ticksInASecond;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a LibAC Time Notation
|
||||
* @param seconds Number of seconds to convert
|
||||
* @return Time Notation
|
||||
*/
|
||||
public static TimeNotation secondsToTimeNotation(int seconds)
|
||||
{
|
||||
int years = seconds / YEAR;
|
||||
if(years > 0) seconds -= YEAR * years;
|
||||
|
||||
int month = seconds / MONTH;
|
||||
if(month > 0) seconds -= MONTH * month;
|
||||
|
||||
int week = seconds / WEEK;
|
||||
if(week > 0) seconds -= WEEK * week;
|
||||
|
||||
int day = seconds / DAY;
|
||||
if(day > 0) seconds -= DAY * day;
|
||||
|
||||
int hour = seconds / HOUR;
|
||||
if(hour > 0) seconds -= HOUR * hour;
|
||||
|
||||
int minute = seconds / MINUTE;
|
||||
if(minute > 0) seconds -= MINUTE * minute;
|
||||
|
||||
return new TimeNotation(years, month, week, day, hour, minute, seconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a time notation to seconds
|
||||
* @param notation Notation to convert
|
||||
* @return Total seconds
|
||||
*/
|
||||
public static int notationToSeconds(TimeNotation notation)
|
||||
{
|
||||
int seconds = 0;
|
||||
|
||||
seconds += (notation.Years * YEAR);
|
||||
seconds += (notation.Months * MONTH);
|
||||
seconds += (notation.Weeks * WEEK);
|
||||
seconds += (notation.Days * DAY);
|
||||
seconds += (notation.Hours * HOUR);
|
||||
seconds += (notation.Minutes * MINUTE);
|
||||
seconds += (notation.Seconds);
|
||||
|
||||
return seconds;
|
||||
}
|
||||
|
||||
|
||||
public static final int SECOND;
|
||||
public static final int MINUTE;
|
||||
public static final int HOUR;
|
||||
public static final int DAY;
|
||||
public static final int WEEK;
|
||||
public static final int MONTH;
|
||||
public static final int YEAR;
|
||||
|
||||
static {
|
||||
SECOND = 1;
|
||||
MINUTE = SECOND * 60;
|
||||
HOUR = MINUTE * 60;
|
||||
DAY = HOUR*24;
|
||||
WEEK = DAY*7;
|
||||
MONTH = WEEK*4;
|
||||
YEAR = DAY*365;
|
||||
}
|
||||
}
|
32
src/main/java/dev/zontreck/ariaslib/xmlrpc/MethodCall.java
Normal file
32
src/main/java/dev/zontreck/ariaslib/xmlrpc/MethodCall.java
Normal file
|
@ -0,0 +1,32 @@
|
|||
package dev.zontreck.ariaslib.xmlrpc;
|
||||
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class MethodCall {
|
||||
private String methodName;
|
||||
private Object[] params;
|
||||
public Map<String, Object> parameters;
|
||||
|
||||
|
||||
public MethodCall ( String methodName , Object[] params , Map<String, Object> p ) {
|
||||
this.methodName = methodName;
|
||||
this.params = params;
|
||||
this.parameters = p;
|
||||
}
|
||||
|
||||
public String getMethodName ( ) {
|
||||
return methodName;
|
||||
}
|
||||
|
||||
public Object[] getParams ( ) {
|
||||
return params;
|
||||
}
|
||||
|
||||
public static MethodCall fromDeserializer ( XmlRpcDeserializer deserializer ) throws Exception {
|
||||
String methodName = deserializer.readMethodName ( );
|
||||
Object[] params = deserializer.readMethodParams ( );
|
||||
Map<String, Object> parameters = ( Map<String, Object> ) params[ 0 ];
|
||||
return new MethodCall ( methodName , params , parameters );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package dev.zontreck.ariaslib.xmlrpc;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class MethodResponse {
|
||||
public Map<String, Object> parameters = new HashMap<> ( );
|
||||
|
||||
public MethodResponse ( ) {
|
||||
}
|
||||
|
||||
|
||||
public String toXml ( ) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream ( );
|
||||
XmlRpcStreamWriter streamWriter = new XmlRpcStreamWriter ( baos );
|
||||
|
||||
try {
|
||||
streamWriter.writeMethodResponse ( parameters );
|
||||
return new String ( baos.toByteArray ( ) );
|
||||
} catch ( IOException e ) {
|
||||
throw new RuntimeException ( e );
|
||||
}
|
||||
}
|
||||
}
|
7
src/main/java/dev/zontreck/ariaslib/xmlrpc/README.md
Normal file
7
src/main/java/dev/zontreck/ariaslib/xmlrpc/README.md
Normal file
|
@ -0,0 +1,7 @@
|
|||
XMLRPC
|
||||
======
|
||||
-----------
|
||||
|
||||
|
||||
|
||||
This code is heavily auto-generated from ChatGPT, however, it contains a lot of modifications to make it actually work.
|
|
@ -0,0 +1,44 @@
|
|||
package dev.zontreck.ariaslib.xmlrpc;
|
||||
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class XmlRpcDeserializer {
|
||||
private XmlRpcStreamReader xmlStreamReader;
|
||||
|
||||
public XmlRpcDeserializer ( InputStream inputStream ) throws Exception {
|
||||
xmlStreamReader = new XmlRpcStreamReader ( inputStream );
|
||||
}
|
||||
public String skipXmlHeader(String xml) {
|
||||
int startIndex = xml.indexOf("<?xml");
|
||||
if (startIndex >= 0) {
|
||||
int endIndex = xml.indexOf("?>", startIndex);
|
||||
if (endIndex >= 0) {
|
||||
return xml.substring(endIndex + 2);
|
||||
}
|
||||
}
|
||||
return xml;
|
||||
}
|
||||
public XmlRpcDeserializer ( String xml ) throws Exception {
|
||||
byte[] xmlBytes = xml.getBytes ( );
|
||||
ByteArrayInputStream inputStream = new ByteArrayInputStream ( xmlBytes );
|
||||
xmlStreamReader = new XmlRpcStreamReader ( inputStream );
|
||||
}
|
||||
|
||||
public String readMethodName ( ) throws Exception {
|
||||
return xmlStreamReader.readMethodCallMethodName ( );
|
||||
}
|
||||
|
||||
public Object[] readMethodParams ( ) throws Exception {
|
||||
return xmlStreamReader.readMethodCallParams ( );
|
||||
}
|
||||
|
||||
public Object readMethodResponse ( ) throws Exception {
|
||||
return xmlStreamReader.readMethodResponseResult ( );
|
||||
}
|
||||
|
||||
public void close ( ) throws Exception {
|
||||
xmlStreamReader.close ( );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package dev.zontreck.ariaslib.xmlrpc;
|
||||
|
||||
|
||||
public class XmlRpcException extends Exception {
|
||||
public XmlRpcException ( int code , String message ) {
|
||||
super ( message );
|
||||
FaultCode = code;
|
||||
FaultString = message;
|
||||
|
||||
}
|
||||
|
||||
public final String FaultString;
|
||||
public final int FaultCode;
|
||||
|
||||
@Override
|
||||
public String toString ( ) {
|
||||
StringBuilder sb = new StringBuilder ( );
|
||||
sb.append ( "Code: " +FaultCode);
|
||||
sb.append ( "\nMessage: " +FaultString);
|
||||
sb.append ( "\n\n" );
|
||||
|
||||
return sb.toString ();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package dev.zontreck.ariaslib.xmlrpc;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
|
||||
public class XmlRpcSerializer {
|
||||
private XmlRpcStreamWriter writer;
|
||||
|
||||
public XmlRpcSerializer ( OutputStream outputStream ) {
|
||||
this.writer = new XmlRpcStreamWriter ( outputStream );
|
||||
}
|
||||
|
||||
public void serializeMethodCall ( String methodName , List<Object> params ) throws IOException {
|
||||
writer.writeMethodCall ( methodName , params );
|
||||
}
|
||||
|
||||
public void serializeMethodResponse ( Object value ) throws IOException {
|
||||
writer.writeMethodResponse ( value );
|
||||
}
|
||||
|
||||
public void close ( ) throws IOException {
|
||||
writer.close ( );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,206 @@
|
|||
package dev.zontreck.ariaslib.xmlrpc;
|
||||
|
||||
import javax.xml.stream.XMLInputFactory;
|
||||
import javax.xml.stream.XMLStreamConstants;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class XmlRpcStreamReader {
|
||||
private XMLStreamReader xmlStreamReader;
|
||||
|
||||
public XmlRpcStreamReader ( InputStream inputStream ) throws XMLStreamException {
|
||||
XMLInputFactory inputFactory = XMLInputFactory.newInstance ( );
|
||||
xmlStreamReader = inputFactory.createXMLStreamReader ( inputStream );
|
||||
}
|
||||
|
||||
private String CURRENT_TAG_NAME;
|
||||
private int ELEM_TYPE;
|
||||
|
||||
public boolean nextTag ( ) throws XMLStreamException {
|
||||
while ( xmlStreamReader.hasNext ( ) ) {
|
||||
int eventType = xmlStreamReader.next ( );
|
||||
if ( eventType == XMLStreamConstants.START_ELEMENT || eventType == XMLStreamConstants.END_ELEMENT ) {
|
||||
CURRENT_TAG_NAME = getLocalName ( );
|
||||
ELEM_TYPE = xmlStreamReader.getEventType ( );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getLocalName ( ) {
|
||||
return xmlStreamReader.getLocalName ( );
|
||||
}
|
||||
|
||||
public String getElementText ( ) throws XMLStreamException {
|
||||
return xmlStreamReader.getElementText ( );
|
||||
}
|
||||
|
||||
public void require ( int type , String namespaceURI , String localName ) throws XMLStreamException {
|
||||
xmlStreamReader.require ( type , namespaceURI , localName );
|
||||
}
|
||||
|
||||
public String readMethodCallMethodName ( ) throws XMLStreamException {
|
||||
nextTag ( );
|
||||
require ( XMLStreamConstants.START_ELEMENT , null , "methodCall" );
|
||||
nextTag ( );
|
||||
require ( XMLStreamConstants.START_ELEMENT , null , "methodName" );
|
||||
return getElementText ( );
|
||||
}
|
||||
|
||||
public Object[] readMethodCallParams ( ) throws XMLStreamException {
|
||||
nextTag ( );
|
||||
require ( XMLStreamConstants.START_ELEMENT , null , "params" );
|
||||
return deserializeParams ( );
|
||||
}
|
||||
|
||||
private Object[] deserializeParams ( ) throws XMLStreamException {
|
||||
List<Object> paramsList = new ArrayList<> ( );
|
||||
|
||||
while ( xmlStreamReader.hasNext ( ) ) {
|
||||
int event = xmlStreamReader.next ( );
|
||||
if ( event == XMLStreamConstants.START_ELEMENT ) {
|
||||
String elementName = xmlStreamReader.getLocalName ( );
|
||||
if ( elementName.equals ( "param" ) ) {
|
||||
nextTag ( );
|
||||
require ( XMLStreamConstants.START_ELEMENT , null , "value" );
|
||||
|
||||
|
||||
Object value = deserializeValue ( );
|
||||
paramsList.add ( value );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return paramsList.toArray ( );
|
||||
}
|
||||
|
||||
public Object readMethodResponseResult ( ) throws XMLStreamException {
|
||||
nextTag ( );
|
||||
require ( XMLStreamConstants.START_ELEMENT , null , "methodResponse" );
|
||||
nextTag ( );
|
||||
require ( XMLStreamConstants.START_ELEMENT , null , "params" );
|
||||
nextTag ( );
|
||||
require ( XMLStreamConstants.START_ELEMENT , null , "param" );
|
||||
return deserializeValue ( );
|
||||
}
|
||||
|
||||
private Object deserializeValue ( ) throws XMLStreamException {
|
||||
nextTag ( );
|
||||
|
||||
|
||||
int eventType = xmlStreamReader.getEventType ( );
|
||||
if ( eventType == XMLStreamConstants.CHARACTERS || eventType == XMLStreamConstants.CDATA ) {
|
||||
return xmlStreamReader.getText ( );
|
||||
}
|
||||
else if ( eventType == XMLStreamConstants.START_ELEMENT ) {
|
||||
String localName = xmlStreamReader.getLocalName ( );
|
||||
switch ( localName ) {
|
||||
case "string":
|
||||
return deserializeString ( );
|
||||
case "i4":
|
||||
case "int":
|
||||
return deserializeInt ( );
|
||||
case "double":
|
||||
return deserializeDouble ( );
|
||||
case "boolean":
|
||||
return deserializeBoolean ( );
|
||||
case "array":
|
||||
return deserializeArray ( );
|
||||
case "struct":
|
||||
return deserializeStruct ( );
|
||||
case "nil":
|
||||
return null;
|
||||
case "i8":
|
||||
return deserializeLong ( );
|
||||
default:
|
||||
throw new IllegalArgumentException ( "Unsupported element: " + localName );
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException ( "Unexpected event type: " + eventType );
|
||||
}
|
||||
}
|
||||
|
||||
private String deserializeString ( ) throws XMLStreamException {
|
||||
return getElementText ( );
|
||||
}
|
||||
|
||||
private int deserializeInt ( ) throws XMLStreamException {
|
||||
return Integer.parseInt ( getElementText ( ) );
|
||||
}
|
||||
|
||||
private byte deserializeByte ( ) throws XMLStreamException {
|
||||
return Byte.parseByte ( getElementText ( ) );
|
||||
}
|
||||
|
||||
private long deserializeLong ( ) throws XMLStreamException {
|
||||
return Long.parseLong ( getElementText ( ) );
|
||||
}
|
||||
|
||||
private double deserializeDouble ( ) throws XMLStreamException {
|
||||
return Double.parseDouble ( getElementText ( ) );
|
||||
}
|
||||
|
||||
private boolean deserializeBoolean ( ) throws XMLStreamException {
|
||||
return Boolean.parseBoolean ( getElementText ( ) );
|
||||
}
|
||||
|
||||
private Object[] deserializeArray ( ) throws XMLStreamException {
|
||||
List<Object> arr = new ArrayList<> ( );
|
||||
while ( nextTag ( ) ) {
|
||||
if ( CURRENT_TAG_NAME.equals ( "data" ) && ELEM_TYPE == XMLStreamConstants.END_ELEMENT ) {
|
||||
break;
|
||||
}
|
||||
else if ( CURRENT_TAG_NAME.equals ( "value" ) && ELEM_TYPE == XMLStreamConstants.START_ELEMENT ) {
|
||||
arr.add ( deserializeValue ( ) );
|
||||
}
|
||||
}
|
||||
|
||||
return arr.toArray ( );
|
||||
}
|
||||
|
||||
private Map<String, Object> deserializeStruct ( ) throws XMLStreamException {
|
||||
Map<String, Object> struct = new HashMap<> ( );
|
||||
String name = null;
|
||||
while ( nextTag ( ) ) {
|
||||
if ( xmlStreamReader.getLocalName ( ).equals ( "member" ) ) {
|
||||
name = null;
|
||||
}
|
||||
else if ( xmlStreamReader.getLocalName ( ).equals ( "name" ) ) {
|
||||
name = getElementText ( );
|
||||
}
|
||||
else if ( xmlStreamReader.getLocalName ( ).equals ( "value" ) && xmlStreamReader.getEventType ( ) == XMLStreamConstants.START_ELEMENT ) {
|
||||
if ( name != null ) {
|
||||
Object value = deserializeValue ( );
|
||||
struct.put ( name , value );
|
||||
}
|
||||
}
|
||||
else if ( CURRENT_TAG_NAME.equals ( "struct" ) && xmlStreamReader.getEventType ( ) == XMLStreamConstants.END_ELEMENT ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return struct;
|
||||
}
|
||||
|
||||
public static String skipXmlHeader ( String xml ) {
|
||||
int startIndex = xml.indexOf ( "<?xml" );
|
||||
if ( startIndex >= 0 ) {
|
||||
int endIndex = xml.indexOf ( "?>" , startIndex );
|
||||
if ( endIndex >= 0 ) {
|
||||
return xml.substring ( endIndex + 2 );
|
||||
}
|
||||
}
|
||||
return xml;
|
||||
}
|
||||
|
||||
|
||||
public void close ( ) throws XMLStreamException {
|
||||
xmlStreamReader.close ( );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
package dev.zontreck.ariaslib.xmlrpc;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class XmlRpcStreamWriter {
|
||||
private static final String XML_VERSION = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
|
||||
private static final String METHOD_CALL_START_TAG = "<methodCall>";
|
||||
private static final String METHOD_CALL_END_TAG = "</methodCall>\n";
|
||||
private static final String METHOD_NAME_START_TAG = "<methodName>";
|
||||
private static final String METHOD_NAME_END_TAG = "</methodName>\n";
|
||||
private static final String METHOD_RESPONSE_START_TAG = "<methodResponse>";
|
||||
private static final String METHOD_RESPONSE_END_TAG = "</methodResponse>\n";
|
||||
private static final String PARAMS_START_TAG = "<params>";
|
||||
private static final String PARAMS_END_TAG = "</params>\n";
|
||||
private static final String PARAM_START_TAG = "<param>";
|
||||
private static final String PARAM_END_TAG = "</param>\n";
|
||||
private static final String VALUE_START_TAG = "<value>";
|
||||
private static final String VALUE_END_TAG = "</value>\n";
|
||||
private static final String ARRAY_START_TAG = "<array>";
|
||||
private static final String ARRAY_END_TAG = "</array>\n";
|
||||
private static final String DATA_START_TAG = "<data>";
|
||||
private static final String DATA_END_TAG = "</data>\n";
|
||||
private static final String STRUCT_START_TAG = "<struct>";
|
||||
private static final String STRUCT_END_TAG = "</struct>\n";
|
||||
private static final String MEMBER_START_TAG = "<member>";
|
||||
private static final String MEMBER_END_TAG = "</member>\n";
|
||||
private static final String NAME_START_TAG = "<name>";
|
||||
private static final String NAME_END_TAG = "</name>\n";
|
||||
|
||||
private Writer writer;
|
||||
|
||||
public XmlRpcStreamWriter ( OutputStream outputStream ) {
|
||||
this.writer = new OutputStreamWriter ( outputStream );
|
||||
}
|
||||
|
||||
public void writeMethodCall ( String methodName , List<Object> params ) throws IOException {
|
||||
writer.write ( XML_VERSION );
|
||||
writer.write ( METHOD_CALL_START_TAG );
|
||||
writer.write ( METHOD_NAME_START_TAG );
|
||||
writer.write ( methodName );
|
||||
writer.write ( METHOD_NAME_END_TAG );
|
||||
writer.write ( PARAMS_START_TAG );
|
||||
|
||||
if ( params != null ) {
|
||||
for ( Object param : params ) {
|
||||
writer.write ( PARAM_START_TAG );
|
||||
writeValue ( param );
|
||||
writer.write ( PARAM_END_TAG );
|
||||
}
|
||||
}
|
||||
writer.write ( PARAMS_END_TAG );
|
||||
writer.write ( METHOD_CALL_END_TAG );
|
||||
writer.flush ( );
|
||||
}
|
||||
|
||||
public void writeMethodResponse ( Object value ) throws IOException {
|
||||
writer.write ( XML_VERSION );
|
||||
writer.write ( METHOD_RESPONSE_START_TAG );
|
||||
writer.write ( PARAMS_START_TAG );
|
||||
writer.write ( PARAM_START_TAG );
|
||||
writeValue ( value );
|
||||
writer.write ( PARAM_END_TAG );
|
||||
writer.write ( PARAMS_END_TAG );
|
||||
writer.write ( METHOD_RESPONSE_END_TAG );
|
||||
writer.flush ( );
|
||||
}
|
||||
|
||||
private void writeValue ( Object value ) throws IOException {
|
||||
if ( value == null ) {
|
||||
writer.write ( VALUE_START_TAG );
|
||||
writer.write ( "<nil/>" );
|
||||
writer.write ( VALUE_END_TAG );
|
||||
}
|
||||
else if ( value instanceof String ) {
|
||||
writer.write ( VALUE_START_TAG );
|
||||
writer.write ( "<string>" );
|
||||
writer.write ( escapeXml ( ( String ) value ) );
|
||||
writer.write ( "</string>\n" );
|
||||
writer.write ( VALUE_END_TAG );
|
||||
}
|
||||
else if ( value instanceof Integer ) {
|
||||
writer.write ( VALUE_START_TAG );
|
||||
writer.write ( "<i4>" );
|
||||
writer.write ( value.toString ( ) );
|
||||
writer.write ( "</i4>\n" );
|
||||
writer.write ( VALUE_END_TAG );
|
||||
} else if(value instanceof Long)
|
||||
{
|
||||
writer.write ( VALUE_START_TAG );
|
||||
writer.write ( "<i8>" );
|
||||
writer.write ( value.toString () ); // Save it as a int for now due to unclear handling
|
||||
writer.write ( "</i8>\n" );
|
||||
writer.write ( VALUE_END_TAG );
|
||||
}
|
||||
else if ( value instanceof Double ) {
|
||||
writer.write ( VALUE_START_TAG );
|
||||
writer.write ( "<double>" );
|
||||
writer.write ( value.toString ( ) );
|
||||
writer.write ( "</double>\n" );
|
||||
writer.write ( VALUE_END_TAG );
|
||||
}
|
||||
else if ( value instanceof Boolean ) {
|
||||
writer.write ( VALUE_START_TAG );
|
||||
writer.write ( "<string>" );
|
||||
writer.write ( value.toString ( ) );
|
||||
writer.write ( "</string>\n" );
|
||||
writer.write ( VALUE_END_TAG );
|
||||
}
|
||||
else if ( value instanceof List ) {
|
||||
writer.write ( VALUE_START_TAG );
|
||||
writer.write ( ARRAY_START_TAG );
|
||||
writer.write ( DATA_START_TAG );
|
||||
List<?> list = ( List<?> ) value;
|
||||
for ( Object item : list ) {
|
||||
writeValue ( item );
|
||||
}
|
||||
writer.write ( DATA_END_TAG );
|
||||
writer.write ( ARRAY_END_TAG );
|
||||
writer.write ( VALUE_END_TAG );
|
||||
}
|
||||
else if ( value instanceof Map ) {
|
||||
writer.write ( VALUE_START_TAG );
|
||||
writer.write ( STRUCT_START_TAG );
|
||||
Map<?, ?> map = ( Map<?, ?> ) value;
|
||||
for ( Map.Entry<?, ?> entry : map.entrySet ( ) ) {
|
||||
writer.write ( MEMBER_START_TAG );
|
||||
writer.write ( NAME_START_TAG );
|
||||
writer.write ( escapeXml ( entry.getKey ( ).toString ( ) ) );
|
||||
writer.write ( NAME_END_TAG );
|
||||
writeValue ( entry.getValue ( ) );
|
||||
writer.write ( MEMBER_END_TAG );
|
||||
}
|
||||
writer.write ( STRUCT_END_TAG );
|
||||
writer.write ( VALUE_END_TAG );
|
||||
}
|
||||
else if(value instanceof Byte)
|
||||
{
|
||||
writer.write ( VALUE_START_TAG );
|
||||
writer.write ( "<int>" );
|
||||
writer.write ( value.toString () ); // Treat as a integer for now
|
||||
writer.write ( "</int>\n" );
|
||||
writer.write ( VALUE_END_TAG );
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException ( "Unsupported data type: " + value.getClass ( ).getName ( ) );
|
||||
}
|
||||
}
|
||||
|
||||
private String escapeXml ( String value ) {
|
||||
return value
|
||||
.replace ( "&" , "&" )
|
||||
.replace ( "<" , "<" )
|
||||
.replace ( ">" , ">" )
|
||||
.replace ( "\"" , """ )
|
||||
.replace ( "'" , "'" );
|
||||
}
|
||||
|
||||
public void close ( ) throws IOException {
|
||||
writer.close ( );
|
||||
}
|
||||
}
|
48
src/main/java/dev/zontreck/ariaslib/xmlrpc/XmlRpcTokens.java
Normal file
48
src/main/java/dev/zontreck/ariaslib/xmlrpc/XmlRpcTokens.java
Normal file
|
@ -0,0 +1,48 @@
|
|||
package dev.zontreck.ariaslib.xmlrpc;
|
||||
|
||||
public class XmlRpcTokens
|
||||
{
|
||||
public final String ISO_DATETIME = "yyyyMMdd\\THH\\:mm\\:ss";
|
||||
|
||||
public final String BASE64 = "base64";
|
||||
|
||||
public final String STRING = "string";
|
||||
|
||||
public final String INT = "i4";
|
||||
|
||||
public final String ALT_INT = "int";
|
||||
|
||||
public final String DATETIME = "dateTime.iso8601";
|
||||
|
||||
public final String BOOLEAN = "boolean";
|
||||
|
||||
public final String VALUE = "value";
|
||||
|
||||
public final String NAME = "name";
|
||||
|
||||
public final String ARRAY = "array";
|
||||
|
||||
public final String DATA = "data";
|
||||
|
||||
public final String MEMBER = "member";
|
||||
|
||||
public final String STRUCT = "struct";
|
||||
|
||||
public final String DOUBLE = "double";
|
||||
|
||||
public final String PARAM = "param";
|
||||
|
||||
public final String PARAMS = "params";
|
||||
|
||||
public final String METHOD_CALL = "methodCall";
|
||||
|
||||
public final String METHOD_NAME = "methodName";
|
||||
|
||||
public final String METHOD_RESPONSE = "methodResponse";
|
||||
|
||||
public final String FAULT = "fault";
|
||||
|
||||
public final String FAULT_CODE = "faultCode";
|
||||
|
||||
public final String FAULT_STRING = "faultString";
|
||||
}
|
166
src/main/java/dev/zontreck/eventsbus/Bus.java
Normal file
166
src/main/java/dev/zontreck/eventsbus/Bus.java
Normal file
|
@ -0,0 +1,166 @@
|
|||
package dev.zontreck.eventsbus;
|
||||
|
||||
import dev.zontreck.eventsbus.annotations.Priority;
|
||||
import dev.zontreck.eventsbus.annotations.SingleshotEvent;
|
||||
import dev.zontreck.eventsbus.annotations.Subscribe;
|
||||
import dev.zontreck.eventsbus.events.EventBusReadyEvent;
|
||||
import dev.zontreck.eventsbus.events.ResetEventBusEvent;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* To be removed
|
||||
* <br/>
|
||||
* Use {EventDispatcher} instead
|
||||
*/
|
||||
@Deprecated()
|
||||
public class Bus {
|
||||
/**
|
||||
* The main event bus!
|
||||
*/
|
||||
private static Bus Main;
|
||||
|
||||
static {
|
||||
if(Main == null)
|
||||
{
|
||||
Main = new Bus("Main Event Bus", false);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean debug = false;
|
||||
public final String BusName;
|
||||
public final boolean UsesInstances;
|
||||
|
||||
public Bus(String name, boolean useInstances) {
|
||||
BusName = name;
|
||||
UsesInstances = useInstances;
|
||||
|
||||
Post(new EventBusReadyEvent());
|
||||
}
|
||||
|
||||
public Map<Class<?>, List<EventContainer>> static_events = new HashMap<Class<?>, List<EventContainer>>();
|
||||
public Map<Class<?>, List<EventContainer>> instanced_events = new HashMap<Class<?>, List<EventContainer>>();
|
||||
|
||||
public static <T> void Register(Class<T> clazz, T instance) {
|
||||
|
||||
List<Method> nonStaticMethods = Arrays.stream(clazz.getMethods())
|
||||
.filter(x -> x.isAnnotationPresent(Subscribe.class))
|
||||
.filter(x -> (x.getModifiers() & Modifier.STATIC) != Modifier.STATIC)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<Method> staticMethods = Arrays.stream(clazz.getMethods())
|
||||
.filter(x -> x.isAnnotationPresent(Subscribe.class))
|
||||
.filter(x -> (x.getModifiers() & Modifier.STATIC) == Modifier.STATIC)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// Register the non-static methods if applicable
|
||||
if (instance != null) {
|
||||
for (Method m :
|
||||
nonStaticMethods) {
|
||||
EventContainer container = new EventContainer();
|
||||
container.instance = instance;
|
||||
container.method = m;
|
||||
container.clazz = clazz;
|
||||
if (m.isAnnotationPresent(Priority.class))
|
||||
container.Level = m.getAnnotation(Priority.class).Level();
|
||||
else container.Level = PriorityLevel.LOWEST;
|
||||
|
||||
Class<?> clz = m.getParameters()[0].getType();
|
||||
|
||||
container.IsSingleshot = m.isAnnotationPresent(SingleshotEvent.class);
|
||||
|
||||
if (Main.instanced_events.containsKey(clz))
|
||||
Main.instanced_events.get(clz).add(container);
|
||||
else {
|
||||
Main.instanced_events.put(clz, new ArrayList<>());
|
||||
Main.instanced_events.get(clz).add(container);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Method m : staticMethods) {
|
||||
EventContainer container = new EventContainer();
|
||||
container.instance = null;
|
||||
container.method = m;
|
||||
container.clazz = clazz;
|
||||
if (m.isAnnotationPresent((Priority.class)))
|
||||
container.Level = m.getAnnotation(Priority.class).Level();
|
||||
else container.Level = PriorityLevel.LOWEST;
|
||||
|
||||
Class<?> clz = m.getParameters()[0].getType();
|
||||
container.IsSingleshot = m.isAnnotationPresent(SingleshotEvent.class);
|
||||
|
||||
if (Main.static_events.containsKey(clz))
|
||||
Main.static_events.get(clz).add(container);
|
||||
else {
|
||||
Main.static_events.put(clz, new ArrayList<>());
|
||||
Main.static_events.get(clz).add(container);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Posts an event to the bus.
|
||||
*
|
||||
* @param event The event you wish to post
|
||||
* @return True if the event was cancelled.
|
||||
*/
|
||||
public static boolean Post(Event event) {
|
||||
for (PriorityLevel level :
|
||||
PriorityLevel.values()) {
|
||||
// Call each priority level in order of declaration
|
||||
// Static first, then instanced
|
||||
// At the end, this method will return the cancellation result.
|
||||
try {
|
||||
|
||||
if (Main.static_events.containsKey(event.getClass())) {
|
||||
EventContainer[] tempArray = (EventContainer[]) Main.static_events.get(event.getClass()).toArray();
|
||||
|
||||
for (EventContainer container : tempArray) {
|
||||
if (container.invoke(event, level)) {
|
||||
Main.static_events.get(event.getClass()).remove(container);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Main.instanced_events.containsKey(event.getClass())) {
|
||||
EventContainer[] tempArray = (EventContainer[]) Main.instanced_events.get(event.getClass()).toArray();
|
||||
|
||||
for (EventContainer container : tempArray) {
|
||||
if (container.invoke(event, level)) {
|
||||
Main.instanced_events.get(event.getClass()).remove(container);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return event.isCancelled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to reset the Event Bus
|
||||
*
|
||||
* @return True if the bus was successfully reset (If not interrupts!)
|
||||
* @see dev.zontreck.eventsbus.events.ResetEventBusEvent
|
||||
*/
|
||||
public static boolean Reset() {
|
||||
if (!Post(new ResetEventBusEvent())) {
|
||||
|
||||
Main.static_events = new HashMap<>();
|
||||
Main.instanced_events = new HashMap<>();
|
||||
|
||||
Post(new EventBusReadyEvent());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
95
src/main/java/dev/zontreck/eventsbus/ClassScanner.java
Normal file
95
src/main/java/dev/zontreck/eventsbus/ClassScanner.java
Normal file
|
@ -0,0 +1,95 @@
|
|||
package dev.zontreck.eventsbus;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
|
||||
@Deprecated
|
||||
/**
|
||||
* Used internally. Do not directly invoke
|
||||
* <br/>
|
||||
* Accessor is set Protected intentionally!!!!!!!!!
|
||||
*/
|
||||
class ClassScanner {
|
||||
/**
|
||||
* Start the process of scanning the classes and forcing them to load in
|
||||
* <br/>
|
||||
* This is used by the event dispatcher
|
||||
*/
|
||||
protected static void DoScan() {
|
||||
// Scan all classes in the classpath
|
||||
Set<Class<?>> scannedClasses = scanClasses();
|
||||
|
||||
// Force loading of all scanned classes
|
||||
for (Class<?> clazz : scannedClasses) {
|
||||
try {
|
||||
// Load the class
|
||||
Class.forName(clazz.getName());
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Set<Class<?>> scanClasses() {
|
||||
String classpath = System.getProperty("java.class.path");
|
||||
String[] classpathEntries = classpath.split(File.pathSeparator);
|
||||
|
||||
Set<Class<?>> scannedClasses = new HashSet<>();
|
||||
for (String classpathEntry : classpathEntries) {
|
||||
File file = new File(classpathEntry);
|
||||
if (file.isDirectory()) {
|
||||
scanClassesInDirectory(file, "", scannedClasses);
|
||||
} else if (file.isFile() && classpathEntry.endsWith(".jar")) {
|
||||
scanClassesInJar(file, scannedClasses);
|
||||
}
|
||||
}
|
||||
|
||||
return scannedClasses;
|
||||
}
|
||||
|
||||
private static void scanClassesInDirectory(File directory, String packageName, Set<Class<?>> scannedClasses) {
|
||||
File[] files = directory.listFiles();
|
||||
if (files == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (File file : files) {
|
||||
if (file.isDirectory()) {
|
||||
scanClassesInDirectory(file, packageName + "." + file.getName(), scannedClasses);
|
||||
} else if (file.getName().endsWith(".class")) {
|
||||
String className = packageName + "." + file.getName().substring(0, file.getName().length() - 6);
|
||||
try {
|
||||
Class<?> clazz = Class.forName(className);
|
||||
scannedClasses.add(clazz);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void scanClassesInJar(File jarFile, Set<Class<?>> scannedClasses) {
|
||||
try (JarFile jf = new JarFile(jarFile)) {
|
||||
for (JarEntry entry : Collections.list(jf.entries())) {
|
||||
if (entry.getName().endsWith(".class")) {
|
||||
String className = entry.getName().replace("/", ".").substring(0, entry.getName().length() - 6);
|
||||
try {
|
||||
Class<?> clazz = Class.forName(className);
|
||||
scannedClasses.add(clazz);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
46
src/main/java/dev/zontreck/eventsbus/Event.java
Normal file
46
src/main/java/dev/zontreck/eventsbus/Event.java
Normal file
|
@ -0,0 +1,46 @@
|
|||
package dev.zontreck.eventsbus;
|
||||
|
||||
|
||||
import dev.zontreck.eventsbus.annotations.Cancellable;
|
||||
import dev.zontreck.eventsbus.annotations.Priority;
|
||||
|
||||
public class Event {
|
||||
private boolean cancelled = false;
|
||||
|
||||
/**
|
||||
* Checks if the event can be cancelled.
|
||||
*
|
||||
* @return True if the cancellation annotation is present.
|
||||
* @see Cancellable
|
||||
*/
|
||||
public boolean IsCancellable() {
|
||||
Class<?> Current = this.getClass();
|
||||
return Current.isAnnotationPresent(Cancellable.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the event is cancelled.
|
||||
*
|
||||
* @return False if the event cannot be cancelled; or
|
||||
* The current cancellation status for the event
|
||||
*/
|
||||
public boolean isCancelled() {
|
||||
if (!IsCancellable())
|
||||
return false;
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cancelled status for the event
|
||||
*
|
||||
* @param cancel Whether the event should be marked as cancelled or not.
|
||||
*/
|
||||
public void setCancelled(boolean cancel) {
|
||||
cancelled = cancel;
|
||||
}
|
||||
|
||||
public PriorityLevel getPriorityLevel() {
|
||||
Class<?> Current = this.getClass();
|
||||
return Current.getAnnotation(Priority.class).Level();
|
||||
}
|
||||
}
|
45
src/main/java/dev/zontreck/eventsbus/EventContainer.java
Normal file
45
src/main/java/dev/zontreck/eventsbus/EventContainer.java
Normal file
|
@ -0,0 +1,45 @@
|
|||
package dev.zontreck.eventsbus;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class EventContainer {
|
||||
public Class<?> clazz;
|
||||
public Object instance;
|
||||
|
||||
/**
|
||||
* The method that gets invoked, either statically, or via the instance.
|
||||
*/
|
||||
public Method method;
|
||||
|
||||
/**
|
||||
* Indicates whether an event gets removed from the register after being invoked once.
|
||||
*/
|
||||
public boolean IsSingleshot;
|
||||
|
||||
/**
|
||||
* The current method's priority level
|
||||
*/
|
||||
public PriorityLevel Level;
|
||||
|
||||
/**
|
||||
* Invokes the event
|
||||
*
|
||||
* @param EventArg The event instance to pass to the subscribed function
|
||||
* @param level Current priority level on the call loop. Will refuse to invoke if the priority level mismatches.
|
||||
* @return True if the event was single shot and should be deregistered
|
||||
* @throws InvocationTargetException
|
||||
* @throws IllegalAccessException
|
||||
*/
|
||||
public boolean invoke(Event EventArg, PriorityLevel level) throws InvocationTargetException, IllegalAccessException {
|
||||
if (Level != level) return false;
|
||||
|
||||
if (instance == null) {
|
||||
method.invoke(null, EventArg);
|
||||
} else {
|
||||
method.invoke(instance, EventArg);
|
||||
}
|
||||
|
||||
return IsSingleshot;
|
||||
}
|
||||
}
|
124
src/main/java/dev/zontreck/eventsbus/EventDispatcher.java
Normal file
124
src/main/java/dev/zontreck/eventsbus/EventDispatcher.java
Normal file
|
@ -0,0 +1,124 @@
|
|||
package dev.zontreck.eventsbus;
|
||||
|
||||
import dev.zontreck.eventsbus.annotations.EventSubscriber;
|
||||
import dev.zontreck.eventsbus.annotations.Priority;
|
||||
import dev.zontreck.eventsbus.annotations.SingleshotEvent;
|
||||
import dev.zontreck.eventsbus.annotations.Subscribe;
|
||||
import dev.zontreck.eventsbus.events.EventBusReadyEvent;
|
||||
import dev.zontreck.eventsbus.events.ResetEventBusEvent;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class EventDispatcher
|
||||
{
|
||||
private static List<Method> singleshot = new ArrayList<>();
|
||||
private static List<Class<?>> subscribers = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Scans every Java class that is currently loaded. It then checks for Subscribe, and a proper parameter before posting the Event.
|
||||
* The Event will only be posted if not cancelled using {@link Event#setCancelled(boolean)} and that {@link Subscribe#allowCancelled()} allows.
|
||||
* @param event The event to post
|
||||
* @return True if cancelled.
|
||||
*/
|
||||
|
||||
public static boolean Post(Event event)
|
||||
{
|
||||
for(PriorityLevel level : PriorityLevel.values())
|
||||
{
|
||||
|
||||
for(Class<?> clazz : subscribers)
|
||||
{
|
||||
for(Method M :clazz.getMethods())
|
||||
{
|
||||
if(!M.isAnnotationPresent(Subscribe.class)) continue;
|
||||
|
||||
Subscribe subscriber = M.getAnnotation(Subscribe.class);
|
||||
|
||||
|
||||
boolean canPost=true;
|
||||
Class<?> param = M.getParameterTypes()[0];
|
||||
if(param == event.getClass())
|
||||
{
|
||||
if(M.isAnnotationPresent(SingleshotEvent.class))
|
||||
{
|
||||
if(singleshot.contains(M))
|
||||
{
|
||||
canPost=false;
|
||||
}
|
||||
}
|
||||
} else canPost=false;
|
||||
|
||||
PriorityLevel eventPriotityLevel= PriorityLevel.HIGH; // Default
|
||||
|
||||
if(M.isAnnotationPresent(Priority.class))
|
||||
{
|
||||
Priority prio = M.getAnnotation(Priority.class);
|
||||
eventPriotityLevel=prio.Level();
|
||||
}
|
||||
|
||||
if(level != eventPriotityLevel)
|
||||
{
|
||||
canPost=false;
|
||||
}
|
||||
|
||||
|
||||
// Dispatch the event now
|
||||
|
||||
if(!canPost) continue;
|
||||
|
||||
if(!M.canAccess(null))
|
||||
{
|
||||
canPost=false;
|
||||
System.out.println("ERROR: Even subscriber methods must be static and public");
|
||||
}
|
||||
|
||||
try {
|
||||
if(event.isCancelled() && !subscriber.allowCancelled())
|
||||
continue;
|
||||
else
|
||||
M.invoke(null, event);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return event.isCancelled();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register a class
|
||||
*/
|
||||
public static void Register(Class<?> clazz)
|
||||
{
|
||||
if(clazz.isAnnotationPresent(EventSubscriber.class))
|
||||
subscribers.add(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the events system.
|
||||
* <br/>
|
||||
* This action clears the Singleshot list for the events that should only be invoked once. And rescans all classes incase new classes were dynamically loaded.
|
||||
*/
|
||||
public static void Reset()
|
||||
{
|
||||
Post(new ResetEventBusEvent());
|
||||
|
||||
subscribers.clear();
|
||||
singleshot.clear();
|
||||
|
||||
Post(new EventBusReadyEvent());
|
||||
}
|
||||
}
|
15
src/main/java/dev/zontreck/eventsbus/PriorityLevel.java
Normal file
15
src/main/java/dev/zontreck/eventsbus/PriorityLevel.java
Normal file
|
@ -0,0 +1,15 @@
|
|||
package dev.zontreck.eventsbus;
|
||||
|
||||
/**
|
||||
* Event priority level.
|
||||
* <p>
|
||||
* The higher the priority, the sooner it gets executed. High is executed after
|
||||
* Highest.
|
||||
*/
|
||||
public enum PriorityLevel {
|
||||
HIGHEST,
|
||||
HIGH,
|
||||
MEDIUM,
|
||||
LOW,
|
||||
LOWEST
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package dev.zontreck.eventsbus.annotations;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(value = RetentionPolicy.RUNTIME)
|
||||
@Target(value = ElementType.TYPE)
|
||||
public @interface Cancellable {
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package dev.zontreck.eventsbus.annotations;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(value = RetentionPolicy.RUNTIME)
|
||||
@Target(value = ElementType.TYPE)
|
||||
public @interface EventSubscriber {
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package dev.zontreck.eventsbus.annotations;
|
||||
|
||||
import dev.zontreck.eventsbus.PriorityLevel;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(value = RetentionPolicy.RUNTIME)
|
||||
@Target(value = ElementType.METHOD)
|
||||
public @interface Priority {
|
||||
PriorityLevel Level();
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package dev.zontreck.eventsbus.annotations;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(value = RetentionPolicy.RUNTIME)
|
||||
@Target(value = ElementType.METHOD)
|
||||
public @interface SingleshotEvent {
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package dev.zontreck.eventsbus.annotations;
|
||||
|
||||
import dev.zontreck.eventsbus.Event;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(value = RetentionPolicy.RUNTIME)
|
||||
@Target(value = ElementType.METHOD)
|
||||
|
||||
public @interface Subscribe {
|
||||
/**
|
||||
* Marks that the subscribed method will not receive the signal if the event was cancelled with {@link Event#setCancelled(boolean)}
|
||||
*/
|
||||
boolean allowCancelled();
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package dev.zontreck.eventsbus.events;
|
||||
|
||||
import dev.zontreck.eventsbus.Event;
|
||||
|
||||
/**
|
||||
* This event is sent out when the Event Bus is ready.
|
||||
* <p>
|
||||
* This is also dispatched when a reset occurs, prior to clearing the lists.
|
||||
*/
|
||||
public class EventBusReadyEvent extends Event {
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package dev.zontreck.eventsbus.events;
|
||||
|
||||
import dev.zontreck.eventsbus.annotations.Cancellable;
|
||||
import dev.zontreck.eventsbus.Event;
|
||||
|
||||
/**
|
||||
* Posted when the event bus is about to be reset.
|
||||
* <p>
|
||||
* This event can be cancelled to prevent the reset.
|
||||
* <p>
|
||||
* The default behavior is: Allow Reset.
|
||||
* <p>
|
||||
* Recommended that handlers be implemented to re-register instances, and classes when a reset occurs.
|
||||
*/
|
||||
@Cancellable
|
||||
public class ResetEventBusEvent extends Event {
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package dev.zontreck.eventsbus.events;
|
||||
|
||||
import dev.zontreck.eventsbus.Event;
|
||||
|
||||
public class TickEvent extends Event {
|
||||
}
|
|
@ -3,34 +3,39 @@ package dev.zontreck.libzontreck;
|
|||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
import dev.zontreck.ariaslib.util.DelayedExecutorService;
|
||||
import dev.zontreck.eventsbus.Bus;
|
||||
import dev.zontreck.libzontreck.chestgui.ChestGUIRegistry;
|
||||
import dev.zontreck.libzontreck.config.ServerConfig;
|
||||
import dev.zontreck.libzontreck.currency.Bank;
|
||||
import dev.zontreck.libzontreck.currency.CurrencyHelper;
|
||||
import dev.zontreck.libzontreck.items.CreativeModeTabs;
|
||||
import dev.zontreck.libzontreck.events.BlockRestoreQueueRegistrationEvent;
|
||||
import dev.zontreck.libzontreck.items.ModItems;
|
||||
import dev.zontreck.libzontreck.memory.world.BlockRestoreQueue;
|
||||
import dev.zontreck.libzontreck.memory.world.BlockRestoreQueueRegistry;
|
||||
import dev.zontreck.libzontreck.memory.world.DatabaseMigrations;
|
||||
import dev.zontreck.libzontreck.memory.world.DatabaseWrapper;
|
||||
import dev.zontreck.libzontreck.menus.ChestGUIScreen;
|
||||
import dev.zontreck.libzontreck.types.ModMenuTypes;
|
||||
import dev.zontreck.libzontreck.networking.NetworkEvents;
|
||||
import net.minecraft.client.gui.screens.MenuScreens;
|
||||
import net.minecraftforge.registries.RegisterEvent;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
|
||||
import dev.zontreck.libzontreck.commands.Commands;
|
||||
import dev.zontreck.libzontreck.events.ForgeEventHandlers;
|
||||
import dev.zontreck.libzontreck.memory.VolatilePlayerStorage;
|
||||
import dev.zontreck.libzontreck.memory.player.VolatilePlayerStorage;
|
||||
import dev.zontreck.libzontreck.networking.ModMessages;
|
||||
import dev.zontreck.libzontreck.profiles.Profile;
|
||||
import dev.zontreck.libzontreck.util.FileTreeDatastore;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.server.ServerStartedEvent;
|
||||
import net.minecraftforge.event.server.ServerStoppingEvent;
|
||||
|
@ -47,7 +52,6 @@ public class LibZontreck {
|
|||
public static final Logger LOGGER = LogUtils.getLogger();
|
||||
public static final String MOD_ID = "libzontreck";
|
||||
public static final Map<String, Profile> PROFILES;
|
||||
public static MinecraftServer THE_SERVER;
|
||||
public static VolatilePlayerStorage playerStorage;
|
||||
public static boolean ALIVE=true;
|
||||
public static final String FILESTORE = FileTreeDatastore.get();
|
||||
|
@ -57,6 +61,7 @@ public class LibZontreck {
|
|||
public static final UUID NULL_ID;
|
||||
|
||||
public static boolean LIBZONTRECK_SERVER_AVAILABLE=false;
|
||||
public static ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
|
||||
|
||||
|
||||
public static LogicalSide CURRENT_SIDE;
|
||||
|
@ -83,6 +88,8 @@ public class LibZontreck {
|
|||
IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||
// Register the setup method for modloading
|
||||
bus.addListener(this::setup);
|
||||
|
||||
ServerConfig.init();
|
||||
|
||||
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
|
@ -91,14 +98,14 @@ public class LibZontreck {
|
|||
MinecraftForge.EVENT_BUS.register(new NetworkEvents());
|
||||
MinecraftForge.EVENT_BUS.register(ChestGUIRegistry.class);
|
||||
|
||||
Bus.Reset();
|
||||
|
||||
ModMenuTypes.REGISTRY.register(bus);
|
||||
//CreativeModeTabs.register(bus);
|
||||
ModItems.register(bus);
|
||||
|
||||
Bus.Register(CurrencyHelper.class, null);
|
||||
Bus.Register(Bank.class, null);
|
||||
MinecraftForge.EVENT_BUS.register(CurrencyHelper.class);
|
||||
MinecraftForge.EVENT_BUS.register(Bank.class);
|
||||
|
||||
}
|
||||
|
||||
private void setup(final FMLCommonSetupEvent event)
|
||||
|
@ -110,16 +117,39 @@ public class LibZontreck {
|
|||
@SubscribeEvent
|
||||
public void onServerStarted(final ServerStartedEvent event)
|
||||
{
|
||||
THE_SERVER = event.getServer();
|
||||
ALIVE=true;
|
||||
|
||||
ServerConfig.init();
|
||||
try {
|
||||
DatabaseWrapper.start();
|
||||
}catch(RuntimeException e) {
|
||||
LOGGER.warn("Database not configured properly, it will not be available.");
|
||||
DatabaseWrapper.invalidate();
|
||||
}
|
||||
|
||||
CURRENT_SIDE = LogicalSide.SERVER;
|
||||
|
||||
MinecraftForge.EVENT_BUS.post(new BlockRestoreQueueRegistrationEvent());
|
||||
|
||||
for(ServerLevel level : event.getServer().getAllLevels())
|
||||
{
|
||||
// Queues have been registered, but we now need to initialize the queue's data from saveddata
|
||||
BlockRestoreQueueRegistry.init(level);
|
||||
}
|
||||
|
||||
if(!DatabaseWrapper.hasDB)return;
|
||||
|
||||
try {
|
||||
DatabaseMigrations.initMigrations();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onServerStopping(final ServerStoppingEvent ev)
|
||||
{
|
||||
ALIVE=false;
|
||||
DelayedExecutorService.stop();
|
||||
|
||||
Iterator<Profile> iProfile = PROFILES.values().iterator();
|
||||
while(iProfile.hasNext())
|
||||
|
|
138
src/main/java/dev/zontreck/libzontreck/api/Vector2.java
Normal file
138
src/main/java/dev/zontreck/libzontreck/api/Vector2.java
Normal file
|
@ -0,0 +1,138 @@
|
|||
package dev.zontreck.libzontreck.api;
|
||||
|
||||
import dev.zontreck.libzontreck.vectors.Vector2f;
|
||||
import dev.zontreck.libzontreck.vectors.Vector2i;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.phys.Vec2;
|
||||
|
||||
public interface Vector2<T> extends Cloneable, Comparable<Vector2<T>>
|
||||
{
|
||||
/**
|
||||
* Converts the current Vector2 representation into a minecraft Vec2
|
||||
* @return Minecraft equivalent Vec2
|
||||
*/
|
||||
Vec2 asMinecraftVector();
|
||||
|
||||
/**
|
||||
* Parses a string in serialized format.
|
||||
* @param vector2 Expects it in the same format returned by Vector2#toString
|
||||
* @return New Vector2, or a null Vector2 initialized with zeros if invalid data
|
||||
*/
|
||||
static Vector2 parseString(String vector2){
|
||||
throw new UnsupportedOperationException("This method is not implemented by this implementation");
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the values to a new and detached instance
|
||||
* @return New Vector2
|
||||
*/
|
||||
Vector2 Clone();
|
||||
|
||||
/**
|
||||
* Saves the X and Y positions to a NBT tag
|
||||
* @return NBT compound tag
|
||||
*/
|
||||
CompoundTag serialize();
|
||||
|
||||
/**
|
||||
* Loads a Vector2 from a NBT tag
|
||||
* @param tag The NBT tag to load
|
||||
*/
|
||||
static Vector2 deserialize(CompoundTag tag)
|
||||
{
|
||||
throw new UnsupportedOperationException("This method is not implemented by this implementation");
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the two vector2 instances
|
||||
* @param other The position to check
|
||||
* @return True if same position
|
||||
*/
|
||||
boolean Same(Vector2 other);
|
||||
|
||||
/**
|
||||
* True if the current position is inside the two points
|
||||
* @param point1 Lowest point
|
||||
* @param point2 Hightest Point
|
||||
* @return True if inside
|
||||
*/
|
||||
boolean Inside(Vector2 point1, Vector2 point2);
|
||||
|
||||
/**
|
||||
* Converts, if necessary, to Vector2d
|
||||
* @return A vector2d instance
|
||||
*/
|
||||
Vector2f asVector2f();
|
||||
|
||||
/**
|
||||
* Converts, if necessary, to Vector2i
|
||||
* @return A vector2i instance
|
||||
*/
|
||||
Vector2i asVector2i();
|
||||
|
||||
/**
|
||||
* Checks if the current vector is greater than the provided one
|
||||
* @param other The other vector to check
|
||||
* @return True if greater
|
||||
*/
|
||||
boolean greater(Vector2 other);
|
||||
|
||||
/**
|
||||
* Checks if the current vector is less than the provided one
|
||||
* @param other The vector to check
|
||||
* @return True if less than other
|
||||
*/
|
||||
boolean less(Vector2 other);
|
||||
|
||||
/**
|
||||
* Alias for Vector2#same
|
||||
* @param other Vector to check
|
||||
* @return True if same position
|
||||
*/
|
||||
boolean equal(Vector2 other);
|
||||
|
||||
/**
|
||||
* Adds the two vectors together
|
||||
* @param other Vector to add
|
||||
* @return New instance after adding the other vector
|
||||
*/
|
||||
Vector2 add(Vector2 other);
|
||||
|
||||
/**
|
||||
* Subtracts the other vector from this one
|
||||
* @param other Vector to subtract
|
||||
* @return New instance after subtracting
|
||||
*/
|
||||
Vector2 subtract(Vector2 other);
|
||||
|
||||
/**
|
||||
* Calculates the distance between the two vectors
|
||||
* @param other
|
||||
* @return The distance
|
||||
*/
|
||||
double distance(Vector2 other);
|
||||
|
||||
/**
|
||||
* Increments the Y axis by 1
|
||||
* @return New instance
|
||||
*/
|
||||
Vector2 moveUp();
|
||||
|
||||
/**
|
||||
* Decrements the Y axis by 1
|
||||
* @return New instance
|
||||
*/
|
||||
Vector2 moveDown();
|
||||
|
||||
/**
|
||||
* Gets the X value
|
||||
* @return X
|
||||
*/
|
||||
T getX();
|
||||
|
||||
/**
|
||||
* Gets the Y value
|
||||
* @return Y
|
||||
*/
|
||||
T getY();
|
||||
}
|
158
src/main/java/dev/zontreck/libzontreck/api/Vector3.java
Normal file
158
src/main/java/dev/zontreck/libzontreck/api/Vector3.java
Normal file
|
@ -0,0 +1,158 @@
|
|||
package dev.zontreck.libzontreck.api;
|
||||
|
||||
import dev.zontreck.libzontreck.vectors.Vector3d;
|
||||
import dev.zontreck.libzontreck.vectors.Vector3i;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public interface Vector3<T> extends Cloneable, Comparable<Vector3<T>>
|
||||
{
|
||||
/**
|
||||
* Converts the current Vector3 representation into a minecraft Vec3
|
||||
* @return Minecraft equivalent Vec3
|
||||
*/
|
||||
Vec3 asMinecraftVector();
|
||||
|
||||
/**
|
||||
* Converts to a vec3i position
|
||||
* @return Equivalent vec3i
|
||||
*/
|
||||
Vec3i asVec3i();
|
||||
|
||||
/**
|
||||
* Converts to a block position
|
||||
* @return Equivalent block position
|
||||
*/
|
||||
BlockPos asBlockPos();
|
||||
|
||||
/**
|
||||
* Parses a string in serialized format.
|
||||
* @param vector3 Expects it in the same format returned by Vector3#toString
|
||||
* @return New Vector3, or a null Vector3 initialized with zeros if invalid data
|
||||
*/
|
||||
static Vector3 parseString(String vector3){
|
||||
throw new UnsupportedOperationException("This method is not implemented by this implementation");
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the values to a new and detached instance
|
||||
* @return New Vector3
|
||||
*/
|
||||
Vector3 Clone();
|
||||
|
||||
/**
|
||||
* Saves the X, Y, and Z positions to a NBT tag
|
||||
* @return NBT compound tag
|
||||
*/
|
||||
CompoundTag serialize();
|
||||
|
||||
/**
|
||||
* Loads a Vector3 from a NBT tag
|
||||
* @param tag The NBT tag to load
|
||||
*/
|
||||
static Vector3 deserialize(CompoundTag tag)
|
||||
{
|
||||
throw new UnsupportedOperationException("This method is not implemented by this implementation");
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the two vector3 instances
|
||||
* @param other The position to check
|
||||
* @return True if same position
|
||||
*/
|
||||
boolean Same(Vector3 other);
|
||||
|
||||
/**
|
||||
* True if the current position is inside the two points
|
||||
* @param point1 Lowest point
|
||||
* @param point2 Hightest Point
|
||||
* @return True if inside
|
||||
*/
|
||||
boolean Inside(Vector3 point1, Vector3 point2);
|
||||
|
||||
/**
|
||||
* Converts, if necessary, to Vector3d
|
||||
* @return A vector2d instance
|
||||
*/
|
||||
Vector3d asVector3d();
|
||||
|
||||
/**
|
||||
* Converts, if necessary, to Vector3i
|
||||
* @return A vector3i instance
|
||||
*/
|
||||
Vector3i asVector3i();
|
||||
|
||||
/**
|
||||
* Checks if the current vector is greater than the provided one
|
||||
* @param other The other vector to check
|
||||
* @return True if greater
|
||||
*/
|
||||
boolean greater(Vector3 other);
|
||||
|
||||
/**
|
||||
* Checks if the current vector is less than the provided one
|
||||
* @param other The vector to check
|
||||
* @return True if less than other
|
||||
*/
|
||||
boolean less(Vector3 other);
|
||||
|
||||
/**
|
||||
* Alias for Vector3#same
|
||||
* @param other Vector to check
|
||||
* @return True if same position
|
||||
*/
|
||||
boolean equal(Vector3 other);
|
||||
|
||||
/**
|
||||
* Adds the two vectors together
|
||||
* @param other Vector to add
|
||||
* @return New instance after adding the other vector
|
||||
*/
|
||||
Vector3 add(Vector3 other);
|
||||
|
||||
/**
|
||||
* Subtracts the other vector from this one
|
||||
* @param other Vector to subtract
|
||||
* @return New instance after subtracting
|
||||
*/
|
||||
Vector3 subtract(Vector3 other);
|
||||
|
||||
/**
|
||||
* Calculates the distance between the two vectors
|
||||
* @param other
|
||||
* @return The distance
|
||||
*/
|
||||
double distance(Vector3 other);
|
||||
|
||||
/**
|
||||
* Increments the Y axis by 1
|
||||
* @return New instance
|
||||
*/
|
||||
Vector3 moveUp();
|
||||
|
||||
/**
|
||||
* Decrements the Y axis by 1
|
||||
* @return New instance
|
||||
*/
|
||||
Vector3 moveDown();
|
||||
|
||||
/**
|
||||
* Gets the X value
|
||||
* @return X
|
||||
*/
|
||||
T getX();
|
||||
|
||||
/**
|
||||
* Gets the Y value
|
||||
* @return Y
|
||||
*/
|
||||
T getY();
|
||||
|
||||
/**
|
||||
* Gets the Z value
|
||||
* @return Z
|
||||
*/
|
||||
T getZ();
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package dev.zontreck.libzontreck.blocks;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
|
||||
public class BlockCustomVoxels extends PartialTransparentBlock
|
||||
{
|
||||
private VoxelShape superShape;
|
||||
public BlockCustomVoxels(Properties p_54120_, VoxelShape shape) {
|
||||
super(p_54120_);
|
||||
this.superShape = shape;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState p_60555_, BlockGetter p_60556_, BlockPos p_60557_, CollisionContext p_60558_) {
|
||||
return superShape;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package dev.zontreck.libzontreck.blocks;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.block.AbstractGlassBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class PartialTransparentBlock extends AbstractGlassBlock
|
||||
{
|
||||
public PartialTransparentBlock(Properties p_48729_) {
|
||||
super(p_48729_);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean propagatesSkylightDown(BlockState p_48740_, BlockGetter p_48741_, BlockPos p_48742_) {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package dev.zontreck.libzontreck.blocks;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.block.AbstractGlassBlock;
|
||||
import net.minecraft.world.level.block.SlabBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class PartialTransparentSlabBlock extends SlabBlock
|
||||
{
|
||||
public PartialTransparentSlabBlock(Properties p_48729_) {
|
||||
super(p_48729_);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean propagatesSkylightDown(BlockState p_48740_, BlockGetter p_48741_, BlockPos p_48742_) {
|
||||
return true;
|
||||
}
|
||||
}
|
100
src/main/java/dev/zontreck/libzontreck/blocks/RedstoneBlock.java
Normal file
100
src/main/java/dev/zontreck/libzontreck/blocks/RedstoneBlock.java
Normal file
|
@ -0,0 +1,100 @@
|
|||
package dev.zontreck.libzontreck.blocks;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public abstract class RedstoneBlock extends RotatableBlock
|
||||
{
|
||||
public static final BooleanProperty INPUT_POWER = BooleanProperty.create("inputpower");
|
||||
public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
|
||||
private List<Direction> sides;
|
||||
|
||||
protected RedstoneBlock(Properties pProperties, Direction... validSides) {
|
||||
super(pProperties);
|
||||
sides=List.of(validSides);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockPlaceContext pContext) {
|
||||
return super.getStateForPlacement(pContext).setValue(INPUT_POWER, false).setValue(POWERED, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> pBuilder) {
|
||||
super.createBlockStateDefinition(pBuilder);
|
||||
pBuilder.add(INPUT_POWER, POWERED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canConnectRedstone(BlockState state, BlockGetter level, BlockPos pos, @Nullable Direction direction) {
|
||||
if(sides.contains(direction)) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
private boolean redstoneIsActivated(LevelReader level, BlockPos pos)
|
||||
{
|
||||
ServerLevel srv = (ServerLevel)level;
|
||||
if(srv.hasNeighborSignal(pos))
|
||||
return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSignal(BlockState p_60483_, BlockGetter p_60484_, BlockPos p_60485_, Direction p_60486_) {
|
||||
if(!sides.contains(p_60486_)) return 0;
|
||||
|
||||
if(p_60483_.getValue(POWERED))
|
||||
return 15;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
protected abstract void onRedstone(LevelReader level, BlockPos pos, boolean on);
|
||||
protected abstract void onRedstoneInputChanged(LevelReader level, BlockPos pos, boolean on);
|
||||
|
||||
@Override
|
||||
public void onNeighborChange(BlockState state, LevelReader level, BlockPos pos, BlockPos neighbor) {
|
||||
boolean rs = redstoneIsActivated(level, pos);
|
||||
onRedstone(level, pos, rs);
|
||||
boolean inp = state.getValue(INPUT_POWER);
|
||||
state.setValue(INPUT_POWER, rs);
|
||||
|
||||
if(inp != rs)
|
||||
onRedstoneInputChanged(level, pos, rs);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, Level level, BlockPos pos, Block block, BlockPos other, boolean unknown) {
|
||||
boolean rs = redstoneIsActivated(level, pos);
|
||||
onRedstone(level, pos, rs);
|
||||
boolean inp = state.getValue(INPUT_POWER);
|
||||
state.setValue(INPUT_POWER, rs);
|
||||
|
||||
if(inp != rs)
|
||||
onRedstoneInputChanged(level, pos, rs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlace(BlockState state, Level level, BlockPos pos, BlockState p_60569_, boolean p_60570_) {
|
||||
boolean rs = redstoneIsActivated(level, pos);
|
||||
onRedstone(level, pos, rs);
|
||||
boolean inp = state.getValue(INPUT_POWER);
|
||||
state.setValue(INPUT_POWER, rs);
|
||||
|
||||
if(inp != rs)
|
||||
onRedstoneInputChanged(level, pos, rs);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package dev.zontreck.libzontreck.blocks;
|
||||
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.HorizontalDirectionalBlock;
|
||||
import net.minecraft.world.level.block.Mirror;
|
||||
import net.minecraft.world.level.block.Rotation;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
|
||||
public class RotatableBlock extends HorizontalDirectionalBlock
|
||||
{
|
||||
public RotatableBlock(Properties pProperties) {
|
||||
super(pProperties);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> pBuilder) {
|
||||
super.createBlockStateDefinition(pBuilder);
|
||||
pBuilder.add(FACING);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BlockState rotate(BlockState p_55115_, Rotation p_55116_) {
|
||||
return p_55115_.setValue(FACING, p_55116_.rotate(p_55115_.getValue(FACING)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState mirror(BlockState p_55112_, Mirror p_55113_) {
|
||||
return p_55112_.rotate(p_55113_.getRotation(p_55112_.getValue(FACING)));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockPlaceContext pContext) {
|
||||
return defaultBlockState().setValue(FACING, pContext.getHorizontalDirection());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package dev.zontreck.libzontreck.blocks;
|
||||
|
||||
import dev.zontreck.ariaslib.util.Maps;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class RotatableBlockCustomVoxels extends RotatableBlock
|
||||
{
|
||||
private Map<Direction, VoxelShape> rotatedShapes = new HashMap<>();
|
||||
|
||||
public RotatableBlockCustomVoxels(Properties properties, VoxelShape north, VoxelShape south, VoxelShape east, VoxelShape west) {
|
||||
super(properties);
|
||||
rotatedShapes = Maps.of(new Maps.Entry<>(Direction.NORTH, north), new Maps.Entry<>(Direction.SOUTH, south), new Maps.Entry<>(Direction.WEST, west), new Maps.Entry<>(Direction.EAST, east), new Maps.Entry<>(Direction.NORTH, north), new Maps.Entry<>(Direction.DOWN, north));
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) {
|
||||
Direction facing = state.getValue(FACING);
|
||||
return rotatedShapes.get(facing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean propagatesSkylightDown(BlockState p_49928_, BlockGetter p_49929_, BlockPos p_49930_) {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -10,6 +10,10 @@ public class ChatColorFactory {
|
|||
public String build(){
|
||||
return built;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the color builder
|
||||
*/
|
||||
public void reset()
|
||||
{
|
||||
built="";
|
||||
|
@ -18,6 +22,11 @@ public class ChatColorFactory {
|
|||
public ColorBuilder(){}
|
||||
}
|
||||
private ColorBuilder instance;
|
||||
|
||||
/**
|
||||
* Resets the chat color builder
|
||||
* @return The current builder
|
||||
*/
|
||||
public ChatColorFactory reset()
|
||||
{
|
||||
instance.reset();
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package dev.zontreck.libzontreck.chat;
|
||||
|
||||
import dev.zontreck.libzontreck.util.ChatHelpers;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.HoverEvent;
|
||||
import net.minecraft.network.chat.HoverEvent.Action;
|
||||
|
@ -17,7 +18,7 @@ public class HoverTip {
|
|||
*/
|
||||
public static HoverEvent get(String text)
|
||||
{
|
||||
return new HoverEvent(Action.SHOW_TEXT, Component.literal(text));
|
||||
return new HoverEvent(Action.SHOW_TEXT, ChatHelpers.macro(text));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,11 +7,10 @@ import dev.zontreck.libzontreck.items.ModItems;
|
|||
import dev.zontreck.libzontreck.menus.ChestGUIMenu;
|
||||
import dev.zontreck.libzontreck.networking.ModMessages;
|
||||
import dev.zontreck.libzontreck.networking.packets.S2CCloseChestGUI;
|
||||
import dev.zontreck.libzontreck.util.ChatHelpers;
|
||||
import dev.zontreck.libzontreck.util.ServerUtilities;
|
||||
import dev.zontreck.libzontreck.vectors.Vector2;
|
||||
import dev.zontreck.libzontreck.vectors.Vector2f;
|
||||
import dev.zontreck.libzontreck.vectors.Vector2i;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.SimpleMenuProvider;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
@ -23,8 +22,6 @@ import net.minecraftforge.network.NetworkHooks;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Zontreck's ChestGUI Interface
|
||||
|
@ -198,7 +195,7 @@ public class ChestGUI
|
|||
{
|
||||
updateUtilityButtons();
|
||||
MinecraftForge.EVENT_BUS.post(new OpenGUIEvent(id, player, this));
|
||||
NetworkHooks.openScreen(ServerUtilities.getPlayerByID(player.toString()), new SimpleMenuProvider(ChestGUIMenu.getServerMenu(this), Component.literal((MenuTitle != "") ? MenuTitle : "No Title")));
|
||||
NetworkHooks.openScreen(ServerUtilities.getPlayerByID(player.toString()), new SimpleMenuProvider(ChestGUIMenu.getServerMenu(this), ChatHelpers.macro((MenuTitle != "") ? MenuTitle : "No Title")));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -231,7 +228,7 @@ public class ChestGUI
|
|||
return this.id.equals(id);
|
||||
}
|
||||
|
||||
public void handleButtonClicked(int slot, Vector2 pos, Item item) {
|
||||
public void handleButtonClicked(int slot, Vector2f pos, Item item) {
|
||||
for(ChestGUIButton button : buttons)
|
||||
{
|
||||
if(button.getSlotNum() == slot)
|
||||
|
|
|
@ -3,10 +3,8 @@ package dev.zontreck.libzontreck.chestgui;
|
|||
import dev.zontreck.libzontreck.lore.LoreContainer;
|
||||
import dev.zontreck.libzontreck.lore.LoreEntry;
|
||||
import dev.zontreck.libzontreck.util.ChatHelpers;
|
||||
import dev.zontreck.libzontreck.vectors.Vector2;
|
||||
import dev.zontreck.libzontreck.vectors.Vector2i;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtUtils;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraftforge.items.ItemStackHandler;
|
||||
|
@ -144,7 +142,7 @@ public class ChestGUIButton
|
|||
*/
|
||||
public boolean matchesSlot(Vector2i slot)
|
||||
{
|
||||
return position.same(slot);
|
||||
return position.Same(slot);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
package dev.zontreck.libzontreck.config;
|
||||
|
||||
import dev.zontreck.libzontreck.LibZontreck;
|
||||
import dev.zontreck.libzontreck.config.sections.DatabaseSection;
|
||||
import dev.zontreck.libzontreck.util.SNbtIo;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class ServerConfig
|
||||
{
|
||||
public static final Path BASE = LibZontreck.BASE_CONFIG.resolve("server.snbt");
|
||||
|
||||
public static DatabaseSection database;
|
||||
|
||||
public static void init()
|
||||
{
|
||||
if(BASE.toFile().exists())
|
||||
{
|
||||
var config = SNbtIo.loadSnbt(BASE);
|
||||
|
||||
database = DatabaseSection.deserialize(config.getCompound(DatabaseSection.TAG_NAME));
|
||||
|
||||
commit();
|
||||
} else {
|
||||
database = new DatabaseSection();
|
||||
|
||||
commit();
|
||||
}
|
||||
}
|
||||
|
||||
public static void commit()
|
||||
{
|
||||
CompoundTag tag = new CompoundTag();
|
||||
tag.put(DatabaseSection.TAG_NAME, database.serialize());
|
||||
|
||||
SNbtIo.writeSnbt(BASE, tag);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue