diff --git a/pom.xml b/pom.xml
index 9304f7310..54a3846d7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -20,10 +20,50 @@
0.1
+
+ org.jetbrains.kotlin
+ kotlin-maven-plugin
+ ${kotlin.version}
+
+
+ compile
+ compile
+
+ compile
+
+
+
+ test-compile
+ test-compile
+
+ test-compile
+
+
+
+
+ 1.8
+
+ org.apache.maven.pluginsmaven-compiler-plugin3.8.1
+
+
+ compile
+ compile
+
+ compile
+
+
+
+ testCompile
+ test-compile
+
+ testCompile
+
+
+ 1515
@@ -38,6 +78,7 @@
15de.bixilon.minosoft.Minosoft16-ea+5
+ 1.4.21
@@ -93,5 +134,16 @@
jline3.17.1
+
+ org.jetbrains.kotlin
+ kotlin-stdlib-jdk8
+ ${kotlin.version}
+
+
+ org.jetbrains.kotlin
+ kotlin-test
+ ${kotlin.version}
+ test
+
diff --git a/src/main/java/de/bixilon/minosoft/data/EntityClassMappings.java b/src/main/java/de/bixilon/minosoft/data/EntityClassMappings.java
deleted file mode 100644
index 593e3d804..000000000
--- a/src/main/java/de/bixilon/minosoft/data/EntityClassMappings.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Minosoft
- * Copyright (C) 2020 Moritz Zwerger
- *
- * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with this program.If not, see .
- *
- * This software is not affiliated with Mojang AB, the original developer of Minecraft.
- */
-
-package de.bixilon.minosoft.data;
-
-import com.google.common.collect.HashBiMap;
-import de.bixilon.minosoft.data.entities.EvokerFangs;
-import de.bixilon.minosoft.data.entities.entities.AreaEffectCloud;
-import de.bixilon.minosoft.data.entities.entities.Entity;
-import de.bixilon.minosoft.data.entities.entities.ExperienceOrb;
-import de.bixilon.minosoft.data.entities.entities.LightningBolt;
-import de.bixilon.minosoft.data.entities.entities.ambient.Bat;
-import de.bixilon.minosoft.data.entities.entities.animal.*;
-import de.bixilon.minosoft.data.entities.entities.animal.hoglin.Hoglin;
-import de.bixilon.minosoft.data.entities.entities.animal.horse.*;
-import de.bixilon.minosoft.data.entities.entities.animal.water.*;
-import de.bixilon.minosoft.data.entities.entities.boss.enderdragon.EndCrystal;
-import de.bixilon.minosoft.data.entities.entities.boss.enderdragon.EnderDragon;
-import de.bixilon.minosoft.data.entities.entities.boss.wither.WitherBoss;
-import de.bixilon.minosoft.data.entities.entities.decoration.ArmorStand;
-import de.bixilon.minosoft.data.entities.entities.decoration.ItemFrame;
-import de.bixilon.minosoft.data.entities.entities.decoration.LeashFenceKnotEntity;
-import de.bixilon.minosoft.data.entities.entities.decoration.Painting;
-import de.bixilon.minosoft.data.entities.entities.item.FallingBlock;
-import de.bixilon.minosoft.data.entities.entities.item.ItemEntity;
-import de.bixilon.minosoft.data.entities.entities.item.PrimedTNT;
-import de.bixilon.minosoft.data.entities.entities.monster.*;
-import de.bixilon.minosoft.data.entities.entities.monster.piglin.Piglin;
-import de.bixilon.minosoft.data.entities.entities.monster.piglin.PiglinBrute;
-import de.bixilon.minosoft.data.entities.entities.monster.raid.*;
-import de.bixilon.minosoft.data.entities.entities.npc.Villager;
-import de.bixilon.minosoft.data.entities.entities.npc.WanderingTrader;
-import de.bixilon.minosoft.data.entities.entities.player.PlayerEntity;
-import de.bixilon.minosoft.data.entities.entities.projectile.*;
-import de.bixilon.minosoft.data.entities.entities.vehicle.*;
-import de.bixilon.minosoft.data.mappings.ModIdentifier;
-
-public final class EntityClassMappings {
- public static final HashBiMap, ModIdentifier> ENTITY_CLASS_MAPPINGS = HashBiMap.create();
-
- static {
- ENTITY_CLASS_MAPPINGS.put(AreaEffectCloud.class, new ModIdentifier("area_effect_cloud"));
- ENTITY_CLASS_MAPPINGS.put(ArmorStand.class, new ModIdentifier("armor_stand"));
- ENTITY_CLASS_MAPPINGS.put(Arrow.class, new ModIdentifier("arrow"));
- ENTITY_CLASS_MAPPINGS.put(Bat.class, new ModIdentifier("bat"));
- ENTITY_CLASS_MAPPINGS.put(Bee.class, new ModIdentifier("bee"));
- ENTITY_CLASS_MAPPINGS.put(Blaze.class, new ModIdentifier("blaze"));
- ENTITY_CLASS_MAPPINGS.put(Boat.class, new ModIdentifier("boat"));
- ENTITY_CLASS_MAPPINGS.put(Cat.class, new ModIdentifier("cat"));
- ENTITY_CLASS_MAPPINGS.put(CaveSpider.class, new ModIdentifier("cave_spider"));
- ENTITY_CLASS_MAPPINGS.put(Chicken.class, new ModIdentifier("chicken"));
- ENTITY_CLASS_MAPPINGS.put(Cod.class, new ModIdentifier("cod"));
- ENTITY_CLASS_MAPPINGS.put(Cow.class, new ModIdentifier("cow"));
- ENTITY_CLASS_MAPPINGS.put(Creeper.class, new ModIdentifier("creeper"));
- ENTITY_CLASS_MAPPINGS.put(Dolphin.class, new ModIdentifier("dolphin"));
- ENTITY_CLASS_MAPPINGS.put(Donkey.class, new ModIdentifier("donkey"));
- ENTITY_CLASS_MAPPINGS.put(DragonFireball.class, new ModIdentifier("dragon_fireball"));
- ENTITY_CLASS_MAPPINGS.put(Drowned.class, new ModIdentifier("drowned"));
- ENTITY_CLASS_MAPPINGS.put(ElderGuardian.class, new ModIdentifier("elder_guardian"));
- ENTITY_CLASS_MAPPINGS.put(EndCrystal.class, new ModIdentifier("end_crystal"));
- ENTITY_CLASS_MAPPINGS.put(EnderDragon.class, new ModIdentifier("ender_dragon"));
- ENTITY_CLASS_MAPPINGS.put(Enderman.class, new ModIdentifier("enderman"));
- ENTITY_CLASS_MAPPINGS.put(Endermite.class, new ModIdentifier("endermite"));
- ENTITY_CLASS_MAPPINGS.put(Evoker.class, new ModIdentifier("evoker"));
- ENTITY_CLASS_MAPPINGS.put(EvokerFangs.class, new ModIdentifier("evoker_fangs"));
- ENTITY_CLASS_MAPPINGS.put(ExperienceOrb.class, new ModIdentifier("experience_orb"));
- ENTITY_CLASS_MAPPINGS.put(ThrownEyeOfEnder.class, new ModIdentifier("eye_of_ender"));
- ENTITY_CLASS_MAPPINGS.put(FallingBlock.class, new ModIdentifier("falling_block"));
- ENTITY_CLASS_MAPPINGS.put(FireworkRocketEntity.class, new ModIdentifier("firework_rocket"));
- ENTITY_CLASS_MAPPINGS.put(Fox.class, new ModIdentifier("fox"));
- ENTITY_CLASS_MAPPINGS.put(Ghast.class, new ModIdentifier("ghast"));
- ENTITY_CLASS_MAPPINGS.put(Giant.class, new ModIdentifier("giant"));
- ENTITY_CLASS_MAPPINGS.put(Guardian.class, new ModIdentifier("guardian"));
- ENTITY_CLASS_MAPPINGS.put(Hoglin.class, new ModIdentifier("hoglin"));
- ENTITY_CLASS_MAPPINGS.put(Horse.class, new ModIdentifier("horse"));
- ENTITY_CLASS_MAPPINGS.put(Husk.class, new ModIdentifier("husk"));
- ENTITY_CLASS_MAPPINGS.put(Illusioner.class, new ModIdentifier("illusioner"));
- ENTITY_CLASS_MAPPINGS.put(IronGolem.class, new ModIdentifier("iron_golem"));
- ENTITY_CLASS_MAPPINGS.put(ItemEntity.class, new ModIdentifier("item"));
- ENTITY_CLASS_MAPPINGS.put(ItemFrame.class, new ModIdentifier("item_frame"));
- ENTITY_CLASS_MAPPINGS.put(LargeFireball.class, new ModIdentifier("fireball"));
- ENTITY_CLASS_MAPPINGS.put(LeashFenceKnotEntity.class, new ModIdentifier("leash_knot"));
- ENTITY_CLASS_MAPPINGS.put(LightningBolt.class, new ModIdentifier("lightning_bolt"));
- ENTITY_CLASS_MAPPINGS.put(Llama.class, new ModIdentifier("llama"));
- ENTITY_CLASS_MAPPINGS.put(LlamaSpit.class, new ModIdentifier("llama_spit"));
- ENTITY_CLASS_MAPPINGS.put(MagmaCube.class, new ModIdentifier("magma_cube"));
- ENTITY_CLASS_MAPPINGS.put(Minecart.class, new ModIdentifier("minecart"));
- ENTITY_CLASS_MAPPINGS.put(MinecartChest.class, new ModIdentifier("chest_minecart"));
- ENTITY_CLASS_MAPPINGS.put(MinecartCommandBlock.class, new ModIdentifier("command_block_minecart"));
- ENTITY_CLASS_MAPPINGS.put(MinecartFurnace.class, new ModIdentifier("furnace_minecart"));
- ENTITY_CLASS_MAPPINGS.put(MinecartHopper.class, new ModIdentifier("hopper_minecart"));
- ENTITY_CLASS_MAPPINGS.put(MinecartSpawner.class, new ModIdentifier("spawner_minecart"));
- ENTITY_CLASS_MAPPINGS.put(MinecartTNT.class, new ModIdentifier("tnt_minecart"));
- ENTITY_CLASS_MAPPINGS.put(Mule.class, new ModIdentifier("mule"));
- ENTITY_CLASS_MAPPINGS.put(Mooshroom.class, new ModIdentifier("mooshroom"));
- ENTITY_CLASS_MAPPINGS.put(Ocelot.class, new ModIdentifier("ocelot"));
- ENTITY_CLASS_MAPPINGS.put(Painting.class, new ModIdentifier("painting"));
- ENTITY_CLASS_MAPPINGS.put(Panda.class, new ModIdentifier("panda"));
- ENTITY_CLASS_MAPPINGS.put(Parrot.class, new ModIdentifier("parrot"));
- ENTITY_CLASS_MAPPINGS.put(Phantom.class, new ModIdentifier("phantom"));
- ENTITY_CLASS_MAPPINGS.put(Pig.class, new ModIdentifier("pig"));
- ENTITY_CLASS_MAPPINGS.put(Piglin.class, new ModIdentifier("piglin"));
- ENTITY_CLASS_MAPPINGS.put(PiglinBrute.class, new ModIdentifier("piglin_brute"));
- ENTITY_CLASS_MAPPINGS.put(Pillager.class, new ModIdentifier("pillager"));
- ENTITY_CLASS_MAPPINGS.put(PolarBear.class, new ModIdentifier("polar_bear"));
- ENTITY_CLASS_MAPPINGS.put(PrimedTNT.class, new ModIdentifier("tnt"));
- ENTITY_CLASS_MAPPINGS.put(PufferFish.class, new ModIdentifier("pufferfish"));
- ENTITY_CLASS_MAPPINGS.put(Rabbit.class, new ModIdentifier("rabbit"));
- ENTITY_CLASS_MAPPINGS.put(Ravenger.class, new ModIdentifier("ravager"));
- ENTITY_CLASS_MAPPINGS.put(Salmon.class, new ModIdentifier("salmon"));
- ENTITY_CLASS_MAPPINGS.put(Sheep.class, new ModIdentifier("sheep"));
- ENTITY_CLASS_MAPPINGS.put(Shulker.class, new ModIdentifier("shulker"));
- ENTITY_CLASS_MAPPINGS.put(ShulkerBullet.class, new ModIdentifier("shulker_bullet"));
- ENTITY_CLASS_MAPPINGS.put(Silverfish.class, new ModIdentifier("silverfish"));
- ENTITY_CLASS_MAPPINGS.put(Skeleton.class, new ModIdentifier("skeleton"));
- ENTITY_CLASS_MAPPINGS.put(SkeletonHorse.class, new ModIdentifier("skeleton_horse"));
- ENTITY_CLASS_MAPPINGS.put(Slime.class, new ModIdentifier("slime"));
- ENTITY_CLASS_MAPPINGS.put(SmallFireball.class, new ModIdentifier("small_fireball"));
- ENTITY_CLASS_MAPPINGS.put(SnowGolem.class, new ModIdentifier("snow_golem"));
- ENTITY_CLASS_MAPPINGS.put(ThrownSnowball.class, new ModIdentifier("snowball"));
- ENTITY_CLASS_MAPPINGS.put(SpectralArrow.class, new ModIdentifier("spectral_arrow"));
- ENTITY_CLASS_MAPPINGS.put(Spider.class, new ModIdentifier("spider"));
- ENTITY_CLASS_MAPPINGS.put(Squid.class, new ModIdentifier("squid"));
- ENTITY_CLASS_MAPPINGS.put(Stray.class, new ModIdentifier("stray"));
- ENTITY_CLASS_MAPPINGS.put(Strider.class, new ModIdentifier("strider"));
- ENTITY_CLASS_MAPPINGS.put(ThrownEgg.class, new ModIdentifier("egg"));
- ENTITY_CLASS_MAPPINGS.put(ThrownEnderPearl.class, new ModIdentifier("ender_pearl"));
- ENTITY_CLASS_MAPPINGS.put(ThrownExperienceBottle.class, new ModIdentifier("experience_bottle"));
- ENTITY_CLASS_MAPPINGS.put(ThrownPotion.class, new ModIdentifier("potion"));
- ENTITY_CLASS_MAPPINGS.put(ThrownTrident.class, new ModIdentifier("trident"));
- ENTITY_CLASS_MAPPINGS.put(TraderLlama.class, new ModIdentifier("trader_llama"));
- ENTITY_CLASS_MAPPINGS.put(TropicalFish.class, new ModIdentifier("tropical_fish"));
- ENTITY_CLASS_MAPPINGS.put(Turtle.class, new ModIdentifier("turtle"));
- ENTITY_CLASS_MAPPINGS.put(Vex.class, new ModIdentifier("vex"));
- ENTITY_CLASS_MAPPINGS.put(Villager.class, new ModIdentifier("villager"));
- ENTITY_CLASS_MAPPINGS.put(Vindicator.class, new ModIdentifier("vindicator"));
- ENTITY_CLASS_MAPPINGS.put(WanderingTrader.class, new ModIdentifier("wandering_trader"));
- ENTITY_CLASS_MAPPINGS.put(Witch.class, new ModIdentifier("witch"));
- ENTITY_CLASS_MAPPINGS.put(WitherBoss.class, new ModIdentifier("wither"));
- ENTITY_CLASS_MAPPINGS.put(WitherSkeleton.class, new ModIdentifier("wither_skeleton"));
- ENTITY_CLASS_MAPPINGS.put(WitherSkull.class, new ModIdentifier("wither_skull"));
- ENTITY_CLASS_MAPPINGS.put(Wolf.class, new ModIdentifier("wolf"));
- ENTITY_CLASS_MAPPINGS.put(Zoglin.class, new ModIdentifier("zoglin"));
- ENTITY_CLASS_MAPPINGS.put(Zombie.class, new ModIdentifier("zombie"));
- ENTITY_CLASS_MAPPINGS.put(ZombieHorse.class, new ModIdentifier("zombie_horse"));
- ENTITY_CLASS_MAPPINGS.put(ZombieVillager.class, new ModIdentifier("zombie_villager"));
- ENTITY_CLASS_MAPPINGS.put(ZombiePigman.class, new ModIdentifier("zombie_pigman"));
- ENTITY_CLASS_MAPPINGS.put(ZombifiedPiglin.class, new ModIdentifier("zombified_piglin"));
- ENTITY_CLASS_MAPPINGS.put(PlayerEntity.class, new ModIdentifier("player"));
- ENTITY_CLASS_MAPPINGS.put(FishingHook.class, new ModIdentifier("fishing_bobber"));
- }
-
- public static Class extends Entity> getByIdentifier(String mod, String identifier) {
- return ENTITY_CLASS_MAPPINGS.inverse().get(new ModIdentifier(mod, identifier));
- }
-
-}
diff --git a/src/main/java/de/bixilon/minosoft/data/EntityClassMappings.kt b/src/main/java/de/bixilon/minosoft/data/EntityClassMappings.kt
new file mode 100644
index 000000000..0f01e0c90
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/data/EntityClassMappings.kt
@@ -0,0 +1,167 @@
+/*
+ * Minosoft
+ * Copyright (C) 2020 Moritz Zwerger
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program.If not, see .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+package de.bixilon.minosoft.data
+
+import com.google.common.collect.HashBiMap
+import de.bixilon.minosoft.data.entities.EvokerFangs
+import de.bixilon.minosoft.data.entities.entities.AreaEffectCloud
+import de.bixilon.minosoft.data.entities.entities.Entity
+import de.bixilon.minosoft.data.entities.entities.ExperienceOrb
+import de.bixilon.minosoft.data.entities.entities.LightningBolt
+import de.bixilon.minosoft.data.entities.entities.ambient.Bat
+import de.bixilon.minosoft.data.entities.entities.animal.*
+import de.bixilon.minosoft.data.entities.entities.animal.hoglin.Hoglin
+import de.bixilon.minosoft.data.entities.entities.animal.horse.*
+import de.bixilon.minosoft.data.entities.entities.animal.water.*
+import de.bixilon.minosoft.data.entities.entities.boss.enderdragon.EndCrystal
+import de.bixilon.minosoft.data.entities.entities.boss.enderdragon.EnderDragon
+import de.bixilon.minosoft.data.entities.entities.boss.wither.WitherBoss
+import de.bixilon.minosoft.data.entities.entities.decoration.ArmorStand
+import de.bixilon.minosoft.data.entities.entities.decoration.ItemFrame
+import de.bixilon.minosoft.data.entities.entities.decoration.LeashFenceKnotEntity
+import de.bixilon.minosoft.data.entities.entities.decoration.Painting
+import de.bixilon.minosoft.data.entities.entities.item.FallingBlock
+import de.bixilon.minosoft.data.entities.entities.item.ItemEntity
+import de.bixilon.minosoft.data.entities.entities.item.PrimedTNT
+import de.bixilon.minosoft.data.entities.entities.monster.*
+import de.bixilon.minosoft.data.entities.entities.monster.piglin.Piglin
+import de.bixilon.minosoft.data.entities.entities.monster.piglin.PiglinBrute
+import de.bixilon.minosoft.data.entities.entities.monster.raid.*
+import de.bixilon.minosoft.data.entities.entities.npc.Villager
+import de.bixilon.minosoft.data.entities.entities.npc.WanderingTrader
+import de.bixilon.minosoft.data.entities.entities.player.PlayerEntity
+import de.bixilon.minosoft.data.entities.entities.projectile.*
+import de.bixilon.minosoft.data.entities.entities.vehicle.*
+import de.bixilon.minosoft.data.mappings.ModIdentifier
+
+object EntityClassMappings {
+ private val ENTITY_CLASS_MAPPINGS: HashBiMap, ModIdentifier> = HashBiMap.create(mapOf(
+ AreaEffectCloud::class.java to ModIdentifier("area_effect_cloud"),
+ ArmorStand::class.java to ModIdentifier("armor_stand"),
+ Arrow::class.java to ModIdentifier("arrow"),
+ Bat::class.java to ModIdentifier("bat"),
+ Bee::class.java to ModIdentifier("bee"),
+ Blaze::class.java to ModIdentifier("blaze"),
+ Boat::class.java to ModIdentifier("boat"),
+ Cat::class.java to ModIdentifier("cat"),
+ CaveSpider::class.java to ModIdentifier("cave_spider"),
+ Chicken::class.java to ModIdentifier("chicken"),
+ Cod::class.java to ModIdentifier("cod"),
+ Cow::class.java to ModIdentifier("cow"),
+ Creeper::class.java to ModIdentifier("creeper"),
+ Dolphin::class.java to ModIdentifier("dolphin"),
+ Donkey::class.java to ModIdentifier("donkey"),
+ DragonFireball::class.java to ModIdentifier("dragon_fireball"),
+ Drowned::class.java to ModIdentifier("drowned"),
+ ElderGuardian::class.java to ModIdentifier("elder_guardian"),
+ EndCrystal::class.java to ModIdentifier("end_crystal"),
+ EnderDragon::class.java to ModIdentifier("ender_dragon"),
+ Enderman::class.java to ModIdentifier("enderman"),
+ Endermite::class.java to ModIdentifier("endermite"),
+ Evoker::class.java to ModIdentifier("evoker"),
+ EvokerFangs::class.java to ModIdentifier("evoker_fangs"),
+ ExperienceOrb::class.java to ModIdentifier("experience_orb"),
+ ThrownEyeOfEnder::class.java to ModIdentifier("eye_of_ender"),
+ FallingBlock::class.java to ModIdentifier("falling_block"),
+ FireworkRocketEntity::class.java to ModIdentifier("firework_rocket"),
+ Fox::class.java to ModIdentifier("fox"),
+ Ghast::class.java to ModIdentifier("ghast"),
+ Giant::class.java to ModIdentifier("giant"),
+ Guardian::class.java to ModIdentifier("guardian"),
+ Hoglin::class.java to ModIdentifier("hoglin"),
+ Horse::class.java to ModIdentifier("horse"),
+ Husk::class.java to ModIdentifier("husk"),
+ Illusioner::class.java to ModIdentifier("illusioner"),
+ IronGolem::class.java to ModIdentifier("iron_golem"),
+ ItemEntity::class.java to ModIdentifier("item"),
+ ItemFrame::class.java to ModIdentifier("item_frame"),
+ LargeFireball::class.java to ModIdentifier("fireball"),
+ LeashFenceKnotEntity::class.java to ModIdentifier("leash_knot"),
+ LightningBolt::class.java to ModIdentifier("lightning_bolt"),
+ Llama::class.java to ModIdentifier("llama"),
+ LlamaSpit::class.java to ModIdentifier("llama_spit"),
+ MagmaCube::class.java to ModIdentifier("magma_cube"),
+ Minecart::class.java to ModIdentifier("minecart"),
+ MinecartChest::class.java to ModIdentifier("chest_minecart"),
+ MinecartCommandBlock::class.java to ModIdentifier("command_block_minecart"),
+ MinecartFurnace::class.java to ModIdentifier("furnace_minecart"),
+ MinecartHopper::class.java to ModIdentifier("hopper_minecart"),
+ MinecartSpawner::class.java to ModIdentifier("spawner_minecart"),
+ MinecartTNT::class.java to ModIdentifier("tnt_minecart"),
+ Mule::class.java to ModIdentifier("mule"),
+ Mooshroom::class.java to ModIdentifier("mooshroom"),
+ Ocelot::class.java to ModIdentifier("ocelot"),
+ Painting::class.java to ModIdentifier("painting"),
+ Panda::class.java to ModIdentifier("panda"),
+ Parrot::class.java to ModIdentifier("parrot"),
+ Phantom::class.java to ModIdentifier("phantom"),
+ Pig::class.java to ModIdentifier("pig"),
+ Piglin::class.java to ModIdentifier("piglin"),
+ PiglinBrute::class.java to ModIdentifier("piglin_brute"),
+ Pillager::class.java to ModIdentifier("pillager"),
+ PolarBear::class.java to ModIdentifier("polar_bear"),
+ PrimedTNT::class.java to ModIdentifier("tnt"),
+ PufferFish::class.java to ModIdentifier("pufferfish"),
+ Rabbit::class.java to ModIdentifier("rabbit"),
+ Ravenger::class.java to ModIdentifier("ravager"),
+ Salmon::class.java to ModIdentifier("salmon"),
+ Sheep::class.java to ModIdentifier("sheep"),
+ Shulker::class.java to ModIdentifier("shulker"),
+ ShulkerBullet::class.java to ModIdentifier("shulker_bullet"),
+ Silverfish::class.java to ModIdentifier("silverfish"),
+ Skeleton::class.java to ModIdentifier("skeleton"),
+ SkeletonHorse::class.java to ModIdentifier("skeleton_horse"),
+ Slime::class.java to ModIdentifier("slime"),
+ SmallFireball::class.java to ModIdentifier("small_fireball"),
+ SnowGolem::class.java to ModIdentifier("snow_golem"),
+ ThrownSnowball::class.java to ModIdentifier("snowball"),
+ SpectralArrow::class.java to ModIdentifier("spectral_arrow"),
+ Spider::class.java to ModIdentifier("spider"),
+ Squid::class.java to ModIdentifier("squid"),
+ Stray::class.java to ModIdentifier("stray"),
+ Strider::class.java to ModIdentifier("strider"),
+ ThrownEgg::class.java to ModIdentifier("egg"),
+ ThrownEnderPearl::class.java to ModIdentifier("ender_pearl"),
+ ThrownExperienceBottle::class.java to ModIdentifier("experience_bottle"),
+ ThrownPotion::class.java to ModIdentifier("potion"),
+ ThrownTrident::class.java to ModIdentifier("trident"),
+ TraderLlama::class.java to ModIdentifier("trader_llama"),
+ TropicalFish::class.java to ModIdentifier("tropical_fish"),
+ Turtle::class.java to ModIdentifier("turtle"),
+ Vex::class.java to ModIdentifier("vex"),
+ Villager::class.java to ModIdentifier("villager"),
+ Vindicator::class.java to ModIdentifier("vindicator"),
+ WanderingTrader::class.java to ModIdentifier("wandering_trader"),
+ Witch::class.java to ModIdentifier("witch"),
+ WitherBoss::class.java to ModIdentifier("wither"),
+ WitherSkeleton::class.java to ModIdentifier("wither_skeleton"),
+ WitherSkull::class.java to ModIdentifier("wither_skull"),
+ Wolf::class.java to ModIdentifier("wolf"),
+ Zoglin::class.java to ModIdentifier("zoglin"),
+ Zombie::class.java to ModIdentifier("zombie"),
+ ZombieHorse::class.java to ModIdentifier("zombie_horse"),
+ ZombieVillager::class.java to ModIdentifier("zombie_villager"),
+ ZombiePigman::class.java to ModIdentifier("zombie_pigman"),
+ ZombifiedPiglin::class.java to ModIdentifier("zombified_piglin"),
+ PlayerEntity::class.java to ModIdentifier("player"),
+ FishingHook::class.java to ModIdentifier("fishing_bobber")
+ ))
+
+ fun getByIdentifier(mod: String, identifier: String): Class? {
+ return ENTITY_CLASS_MAPPINGS.inverse()[ModIdentifier(mod, identifier)]
+ }
+
+ fun getByIdentifier(identifier: ModIdentifier): Class? {
+ return ENTITY_CLASS_MAPPINGS.inverse()[identifier]
+ }
+}
diff --git a/src/main/java/de/bixilon/minosoft/data/commands/CommandArgumentNode.java b/src/main/java/de/bixilon/minosoft/data/commands/CommandArgumentNode.java
index 411ad3661..81fa9eb19 100644
--- a/src/main/java/de/bixilon/minosoft/data/commands/CommandArgumentNode.java
+++ b/src/main/java/de/bixilon/minosoft/data/commands/CommandArgumentNode.java
@@ -14,6 +14,7 @@
package de.bixilon.minosoft.data.commands;
import de.bixilon.minosoft.data.commands.parser.CommandParser;
+import de.bixilon.minosoft.data.commands.parser.CommandParsers;
import de.bixilon.minosoft.data.commands.parser.exceptions.CommandParseException;
import de.bixilon.minosoft.data.commands.parser.properties.ParserProperties;
import de.bixilon.minosoft.protocol.network.Connection;
@@ -30,7 +31,7 @@ public class CommandArgumentNode extends CommandLiteralNode {
public CommandArgumentNode(byte flags, InByteBuffer buffer) {
super(flags, buffer);
- parser = CommandParser.createInstance(buffer.readIdentifier());
+ parser = CommandParsers.INSTANCE.getParserInstance(buffer.readIdentifier());
properties = parser.readParserProperties(buffer);
if (BitByte.isBitMask(flags, 0x10)) {
String fullIdentifier = buffer.readIdentifier().getFullIdentifier();
diff --git a/src/main/java/de/bixilon/minosoft/data/commands/parser/CommandParser.java b/src/main/java/de/bixilon/minosoft/data/commands/parser/CommandParser.java
index 78da1df18..158817368 100644
--- a/src/main/java/de/bixilon/minosoft/data/commands/parser/CommandParser.java
+++ b/src/main/java/de/bixilon/minosoft/data/commands/parser/CommandParser.java
@@ -13,35 +13,16 @@
package de.bixilon.minosoft.data.commands.parser;
-import com.google.common.collect.HashBiMap;
import de.bixilon.minosoft.data.commands.parser.exceptions.CommandParseException;
import de.bixilon.minosoft.data.commands.parser.properties.ParserProperties;
-import de.bixilon.minosoft.data.mappings.ModIdentifier;
import de.bixilon.minosoft.protocol.network.Connection;
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
import de.bixilon.minosoft.util.buffers.ImprovedStringReader;
import javax.annotation.Nullable;
-import java.util.Map;
public abstract class CommandParser {
- public static HashBiMap COMMAND_PARSERS = HashBiMap.create(Map.of(
- new ModIdentifier("brigadier:bool"), BooleanParser.BOOLEAN_PARSER,
- new ModIdentifier("brigadier:double"), DoubleParser.DOUBLE_PARSER,
- new ModIdentifier("brigadier:float"), FloatParser.FLOAT_PARSER,
- new ModIdentifier("brigadier:integer"), IntegerParser.INTEGER_PARSER,
- new ModIdentifier("brigadier:string"), StringParser.STRING_PARSER,
- new ModIdentifier("entity"), EntityParser.ENTITY_PARSER,
- new ModIdentifier("score_holder"), ScoreHolderParser.SCORE_HOLDER_PARSER,
- new ModIdentifier("range"), RangeParser.RANGE_PARSER,
- new ModIdentifier("message"), MessageParser.MESSAGE_PARSER
- ));
-
- public static CommandParser createInstance(ModIdentifier identifier) {
- return COMMAND_PARSERS.getOrDefault(identifier, DummyParser.DUMMY_PARSER);
- }
-
@Nullable
public ParserProperties readParserProperties(InByteBuffer buffer) {
return null;
diff --git a/src/main/java/de/bixilon/minosoft/data/commands/parser/CommandParsers.kt b/src/main/java/de/bixilon/minosoft/data/commands/parser/CommandParsers.kt
new file mode 100644
index 000000000..abe369e24
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/data/commands/parser/CommandParsers.kt
@@ -0,0 +1,37 @@
+/*
+ * Minosoft
+ * Copyright (C) 2020 Moritz Zwerger
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program.If not, see .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+
+package de.bixilon.minosoft.data.commands.parser
+
+import com.google.common.collect.HashBiMap
+import de.bixilon.minosoft.data.mappings.ModIdentifier
+
+object CommandParsers {
+ private val COMMAND_PARSERS: HashBiMap = HashBiMap.create(mapOf(
+ ModIdentifier("brigadier:bool") to BooleanParser.BOOLEAN_PARSER,
+ ModIdentifier("brigadier:double") to DoubleParser.DOUBLE_PARSER,
+ ModIdentifier("brigadier:float") to FloatParser.FLOAT_PARSER,
+ ModIdentifier("brigadier:integer") to IntegerParser.INTEGER_PARSER,
+ ModIdentifier("brigadier:string") to StringParser.STRING_PARSER,
+ ModIdentifier("entity") to EntityParser.ENTITY_PARSER,
+ ModIdentifier("score_holder") to ScoreHolderParser.SCORE_HOLDER_PARSER,
+ ModIdentifier("range") to RangeParser.RANGE_PARSER,
+ ModIdentifier("message") to MessageParser.MESSAGE_PARSER,
+ ModIdentifier("item_stack") to ItemStackParser.ITEM_STACK_PARSER
+ ))
+
+ fun getParserInstance(identifier: ModIdentifier): CommandParser {
+ return COMMAND_PARSERS.getOrDefault(identifier, DummyParser.DUMMY_PARSER)
+ }
+}
+
diff --git a/src/main/java/de/bixilon/minosoft/data/commands/parser/EntityParser.java b/src/main/java/de/bixilon/minosoft/data/commands/parser/EntityParser.java
index 21a9f9d4f..cf2a4efbf 100644
--- a/src/main/java/de/bixilon/minosoft/data/commands/parser/EntityParser.java
+++ b/src/main/java/de/bixilon/minosoft/data/commands/parser/EntityParser.java
@@ -63,16 +63,16 @@ public class EntityParser extends CommandParser {
@Override
public void isParsable(Connection connection, ParserProperties properties, ImprovedStringReader stringReader) throws CommandParseException {
EntityParserProperties entityParserProperties = (EntityParserProperties) properties;
- if (stringReader.getChar().equals("@")) {
+ if (stringReader.getNextChar().equals("@")) {
// selector
if (entityParserProperties.isOnlySingleEntity()) {
- throw new SingleEntityOnlyEntityCommandParseException(stringReader, stringReader.getChar());
+ throw new SingleEntityOnlyEntityCommandParseException(stringReader, stringReader.getNextChar());
}
stringReader.skip(1); // skip @
String selectorChar = stringReader.readChar();
if (!selectorChar.equals("a") && !selectorChar.equals("e") && !selectorChar.equals("p") && !selectorChar.equals("r") && !selectorChar.equals("s")) {
// only @a, @e, @p, @r and @s possible
- throw new UnknownMassSelectorEntityCommandParseException(stringReader, stringReader.getChar());
+ throw new UnknownMassSelectorEntityCommandParseException(stringReader, stringReader.getNextChar());
}
if (selectorChar.equals("e") && entityParserProperties.isOnlyPlayers()) {
throw new PlayerOnlyEntityCommandParseException(stringReader, selectorChar);
@@ -81,7 +81,7 @@ public class EntityParser extends CommandParser {
// parse entity selector
// example: /msg @a[ name = "Bixilon" ] asd
- if (!stringReader.getChar().equals("[")) {
+ if (!stringReader.getNextChar().equals("[")) {
// no meta data given, valid
return;
}
@@ -106,7 +106,7 @@ public class EntityParser extends CommandParser {
stringReader.skipSpaces();
parameters.add(parameterName);
- String nextChar = stringReader.getChar();
+ String nextChar = stringReader.getNextChar();
if (nextChar.equals("]")) {
stringReader.skip(1);
break;
diff --git a/src/main/java/de/bixilon/minosoft/data/commands/parser/ItemStackParser.kt b/src/main/java/de/bixilon/minosoft/data/commands/parser/ItemStackParser.kt
new file mode 100644
index 000000000..20fe85f49
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/data/commands/parser/ItemStackParser.kt
@@ -0,0 +1,38 @@
+/*
+ * Minosoft
+ * Copyright (C) 2020 Moritz Zwerger
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program.If not, see .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+package de.bixilon.minosoft.data.commands.parser
+
+import de.bixilon.minosoft.data.commands.parser.exceptions.CommandParseException
+import de.bixilon.minosoft.data.commands.parser.exceptions.ItemNotFoundCommandParseException
+import de.bixilon.minosoft.data.commands.parser.properties.ParserProperties
+import de.bixilon.minosoft.data.mappings.ModIdentifier
+import de.bixilon.minosoft.protocol.network.Connection
+import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
+import de.bixilon.minosoft.util.buffers.ImprovedStringReader
+
+class ItemStackParser : CommandParser() {
+ @Throws(CommandParseException::class)
+ override fun isParsable(connection: Connection, properties: ParserProperties?, stringReader: ImprovedStringReader) {
+ val argument = stringReader.readUntil(ProtocolDefinition.COMMAND_SEPARATOR, "{")
+ if (!connection.mapping.doesItemExist(ModIdentifier(argument.key))) {
+ throw ItemNotFoundCommandParseException(stringReader, argument.key)
+ }
+ if (argument.value == "{" || stringReader.nextChar == "{") {
+ throw TODO("NBT Data needs to be implemented")
+ }
+ }
+
+ companion object {
+ val ITEM_STACK_PARSER = ItemStackParser()
+ }
+}
diff --git a/src/main/java/de/bixilon/minosoft/data/commands/parser/entity/IdentifierSelectorArgumentParser.java b/src/main/java/de/bixilon/minosoft/data/commands/parser/entity/IdentifierSelectorArgumentParser.java
index a69f5d89a..187f03e15 100644
--- a/src/main/java/de/bixilon/minosoft/data/commands/parser/entity/IdentifierSelectorArgumentParser.java
+++ b/src/main/java/de/bixilon/minosoft/data/commands/parser/entity/IdentifierSelectorArgumentParser.java
@@ -34,7 +34,7 @@ public class IdentifierSelectorArgumentParser extends EntitySelectorArgumentPars
}
ModIdentifier identifier = new ModIdentifier(value);
if (this == ENTITY_TYPE_IDENTIFIER_SELECTOR_ARGUMENT_PARSER) {
- if (!EntityClassMappings.ENTITY_CLASS_MAPPINGS.containsValue(identifier)) {
+ if (EntityClassMappings.INSTANCE.getByIdentifier(identifier) == null) {
throw new UnknownEntityCommandParseException(stringReader, match.key);
}
return;
diff --git a/src/main/java/de/bixilon/minosoft/data/commands/parser/exceptions/ItemNotFoundCommandParseException.kt b/src/main/java/de/bixilon/minosoft/data/commands/parser/exceptions/ItemNotFoundCommandParseException.kt
new file mode 100644
index 000000000..83933f9c5
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/data/commands/parser/exceptions/ItemNotFoundCommandParseException.kt
@@ -0,0 +1,25 @@
+/*
+ * Minosoft
+ * Copyright (C) 2020 Moritz Zwerger
+ *
+ * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with this program.If not, see .
+ *
+ * This software is not affiliated with Mojang AB, the original developer of Minecraft.
+ */
+package de.bixilon.minosoft.data.commands.parser.exceptions
+
+import de.bixilon.minosoft.util.buffers.ImprovedStringReader
+
+class ItemNotFoundCommandParseException : CommandParseException {
+ constructor(command: ImprovedStringReader, currentArgument: String) : super(ERROR_MESSAGE, command, currentArgument)
+
+ constructor(command: ImprovedStringReader, currentArgument: String, cause: Throwable) : super(ERROR_MESSAGE, command, currentArgument, cause)
+
+ companion object {
+ private const val ERROR_MESSAGE = "Wrong argument given!"
+ }
+}
diff --git a/src/main/java/de/bixilon/minosoft/data/mappings/versions/VersionMapping.java b/src/main/java/de/bixilon/minosoft/data/mappings/versions/VersionMapping.java
index 176b34111..a249393f5 100644
--- a/src/main/java/de/bixilon/minosoft/data/mappings/versions/VersionMapping.java
+++ b/src/main/java/de/bixilon/minosoft/data/mappings/versions/VersionMapping.java
@@ -393,7 +393,7 @@ public class VersionMapping {
private void loadEntityMapping(String mod, String identifier, JsonObject fullModData) {
JsonObject data = fullModData.getAsJsonObject(identifier);
- Class extends Entity> clazz = EntityClassMappings.getByIdentifier(mod, identifier);
+ Class extends Entity> clazz = EntityClassMappings.INSTANCE.getByIdentifier(mod, identifier);
EntityInformation information = EntityInformation.deserialize(mod, identifier, data);
if (information != null) {
// not abstract, has id and attributes
@@ -486,4 +486,13 @@ public class VersionMapping {
public HashSet getAvailableFeatures() {
return loaded;
}
+
+ public boolean doesItemExist(ModIdentifier identifier) {
+ if (parentMapping != null) {
+ if (parentMapping.doesItemExist(identifier)) {
+ return true;
+ }
+ }
+ return itemMap.containsValue(new Item(identifier.getFullIdentifier()));
+ }
}
diff --git a/src/main/java/de/bixilon/minosoft/logging/Log.java b/src/main/java/de/bixilon/minosoft/logging/Log.java
index f91196994..a8e0bda71 100644
--- a/src/main/java/de/bixilon/minosoft/logging/Log.java
+++ b/src/main/java/de/bixilon/minosoft/logging/Log.java
@@ -175,7 +175,7 @@ public class Log {
Log.level = level;
}
- public static boolean printException(Exception exception, LogLevels minimumLogLevel) {
+ public static boolean printException(Throwable exception, LogLevels minimumLogLevel) {
// ToDo: log to file, print also exceptions that are not printed with this method
if (Log.getLevel().ordinal() >= minimumLogLevel.ordinal()) {
exception.printStackTrace();
diff --git a/src/main/java/de/bixilon/minosoft/protocol/network/Connection.java b/src/main/java/de/bixilon/minosoft/protocol/network/Connection.java
index f5b1ba110..d1c347ff3 100644
--- a/src/main/java/de/bixilon/minosoft/protocol/network/Connection.java
+++ b/src/main/java/de/bixilon/minosoft/protocol/network/Connection.java
@@ -213,7 +213,7 @@ public class Connection {
continue;
}
packet.handle(getHandler());
- } catch (Exception e) {
+ } catch (Throwable e) {
Log.printException(e, LogLevels.PROTOCOL);
}
}
@@ -378,7 +378,7 @@ public class Connection {
}
}
- public Exception getLastConnectionException() {
+ public Throwable getLastConnectionException() {
return (lastException != null) ? lastException : network.getLastException();
}
diff --git a/src/main/java/de/bixilon/minosoft/protocol/network/Network.java b/src/main/java/de/bixilon/minosoft/protocol/network/Network.java
index 698aa63c3..87edd726e 100644
--- a/src/main/java/de/bixilon/minosoft/protocol/network/Network.java
+++ b/src/main/java/de/bixilon/minosoft/protocol/network/Network.java
@@ -28,5 +28,5 @@ public interface Network {
void disconnect();
- Exception getLastException();
+ Throwable getLastException();
}
diff --git a/src/main/java/de/bixilon/minosoft/protocol/network/socket/SocketNetwork.java b/src/main/java/de/bixilon/minosoft/protocol/network/socket/SocketNetwork.java
index 385b79508..8d1196e7e 100644
--- a/src/main/java/de/bixilon/minosoft/protocol/network/socket/SocketNetwork.java
+++ b/src/main/java/de/bixilon/minosoft/protocol/network/socket/SocketNetwork.java
@@ -49,7 +49,7 @@ public class SocketNetwork implements Network {
Socket socket;
OutputStream outputStream;
InputStream inputStream;
- Exception lastException;
+ Throwable lastException;
public SocketNetwork(Connection connection) {
this.connection = connection;
@@ -226,7 +226,7 @@ public class SocketNetwork implements Network {
// safety first, but will not occur
e.printStackTrace();
}
- } catch (Exception e) {
+ } catch (Throwable e) {
Log.protocol(String.format("An error occurred while parsing a packet (%s): %s", packet, e));
if (connection.getConnectionState() == ConnectionStates.PLAY) {
Log.printException(e, LogLevels.PROTOCOL);
@@ -274,7 +274,7 @@ public class SocketNetwork implements Network {
}
@Override
- public Exception getLastException() {
+ public Throwable getLastException() {
return lastException;
}
diff --git a/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketHandler.java b/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketHandler.java
index d0cafc60b..3f9110d0c 100644
--- a/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketHandler.java
+++ b/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketHandler.java
@@ -16,6 +16,7 @@ package de.bixilon.minosoft.protocol.protocol;
import de.bixilon.minosoft.Minosoft;
import de.bixilon.minosoft.config.ConfigurationPaths;
import de.bixilon.minosoft.data.GameModes;
+import de.bixilon.minosoft.data.commands.parser.exceptions.CommandParseException;
import de.bixilon.minosoft.data.entities.entities.Entity;
import de.bixilon.minosoft.data.entities.entities.player.PlayerEntity;
import de.bixilon.minosoft.data.mappings.recipes.Recipes;
@@ -803,5 +804,28 @@ public class PacketHandler {
public void handle(PacketDeclareCommands pkg) {
connection.setCommandRootNode(pkg.getRootNode());
+ // ToDo: Remove these dummy commands
+ String[] commands = {
+ "msg Bixilon TestReason 2Paramter 3 4 asd asd",
+ "msg @a[name=Bixilon, level=23, gamemode=!survival] trest asd 12312 sad123123213",
+ "help",
+ "team list",
+ "tasdasda",
+ "msg @a[ name = \"Bixilon\" ] asd",
+ "msg @a[ name = Bixilon ] asd asdsadasd",
+ "msg @a[ name = Bixilon ,team= ] asd asdsadasd",
+ "msg @a[ name = Bixilon , team =!] asd asdsadasd",
+ "give Bixilon minecraft:acacia_boat",
+ "give Bixilon minecraft:acacia_boat{asd:12}",
+ };
+ for (String command : commands) {
+ try {
+ pkg.getRootNode().isSyntaxCorrect(connection, command);
+ Log.game("Command \"%s\" is valid", command);
+ } catch (CommandParseException e) {
+ Log.game("Command \"%s\" is invalid, %s: %s", command, e.getClass().getSimpleName(), e.getErrorMessage());
+ e.printStackTrace();
+ }
+ }
}
}
diff --git a/src/main/java/de/bixilon/minosoft/util/buffers/ImprovedStringReader.java b/src/main/java/de/bixilon/minosoft/util/buffers/ImprovedStringReader.java
index c1d3ac28c..8ec016cbc 100644
--- a/src/main/java/de/bixilon/minosoft/util/buffers/ImprovedStringReader.java
+++ b/src/main/java/de/bixilon/minosoft/util/buffers/ImprovedStringReader.java
@@ -16,6 +16,8 @@ package de.bixilon.minosoft.util.buffers;
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition;
import de.bixilon.minosoft.util.Pair;
+import javax.annotation.Nullable;
+
public class ImprovedStringReader {
private final String string;
private int position;
@@ -79,10 +81,17 @@ public class ImprovedStringReader {
}
public String readChar() {
+ if (getRemainingChars() == 0) {
+ return null;
+ }
return String.valueOf(string.charAt(position++));
}
- public String getChar() {
+ @Nullable
+ public String getNextChar() {
+ if (getRemainingChars() == 0) {
+ return null;
+ }
return String.valueOf(string.charAt(position));
}
@@ -119,13 +128,19 @@ public class ImprovedStringReader {
public int skipSpaces() {
int skipped = 0;
- while (getChar().equals(" ")) {
+ String nextChar = getNextChar();
+ while (nextChar != null && getNextChar().equals(" ")) {
skip(1);
skipped++;
}
return skipped;
}
+ public int getRemainingChars() {
+ int difference = string.length() - position;
+ return Math.max(difference, 0);
+ }
+
@Override
public String toString() {
return String.format("position=%d/%d: \"%s\"", position, string.length(), getRest());