Merge branch 'master' into future
This commit is contained in:
commit
6594c2c07f
63 files changed
+711
-849
No files matched your search
@@ -815,22 +815,25 @@ In case you want to pass an event handler that is not defined in your module, pl
|
||||
|
||||
### `entity_load_handler(descriptor / descriptors, function)`, `entity_load_handler(descriptor / descriptors, call_name, ... args?)`
|
||||
|
||||
Attaches a callback to when any entity matching the following type / types is loaded in the game, allowing to grab a handle
|
||||
Attaches a callback to trigger when any entity matching the following type / types is loaded in the game, allowing to grab a handle
|
||||
to an entity right when it is loaded to the world without querying them every tick. Callback expects two parameters - the entity,
|
||||
and a boolean indicating if the entity was newly created(`true`) or just loaded from disk. Single argument functions accepting
|
||||
and a boolean value indicating if the entity was newly created(`true`) or just loaded from disk. Single argument functions accepting
|
||||
only entities are allowed, but deprecated and will be removed at some point.
|
||||
|
||||
If callback is `null`, then the current entity handler, if present, is removed. Consecutive calls to `entity_load_handler` will add / subtract
|
||||
of the currently targeted entity types pool.
|
||||
|
||||
Like other global events, calls to `entity_load_handler` can only be attached in apps with global scope. Player scope makes so
|
||||
that it is not clear which player to use run the load call.
|
||||
Like other global events, calls to `entity_load_handler` should only be attached in apps with global scope. For player scope apps,
|
||||
it will be called multiple times, once for each player. That's likely not what you want to do.
|
||||
|
||||
```
|
||||
// veryfast method of getting rid of all the zombies. Callback is so early, its packets haven't reached yet the clients
|
||||
// so to save on log errors, removal of mobs needs to be scheduled for later.
|
||||
entity_load_handler('zombie', _(e, new) -> schedule(0, _(outer(e)) -> modify(e, 'remove')))
|
||||
|
||||
// another way to do it is to remove the entity when it starts ticking
|
||||
entity_load_handler('zombie', _(e, new) -> entity_event(e, 'on_tick', _(e) -> modify(e, 'remove')))
|
||||
|
||||
// making all zombies immediately faster and less susceptible to friction of any sort
|
||||
entity_load_handler('zombie', _(e, new) -> entity_event(e, 'on_tick', _(e) -> modify(e, 'motion', 1.2*e~'motion')))
|
||||
```
|
||||
|
||||
+38
-17
@@ -6,11 +6,14 @@ events occur, but app designers can create their own events and trigger them acr
|
||||
|
||||
When loading the app, each function that starts
|
||||
with `__on_<event>` and has the required arguments, will be bound automatically to a corresponding built-in event. '`undef`'ying
|
||||
of such function would result in unbinding the app from this event.
|
||||
of such function would result in unbinding the app from this event. Defining event hanlder via `__on_<event>(... args) -> expr` is
|
||||
equivalent of defining it via `handle_event('<event>', _(... args) -> expr)`
|
||||
|
||||
In case of `player` scoped apps,
|
||||
all player action events will be directed to the appropriate player hosts. Global events, like `'tick'`, that don't have a specific
|
||||
player target will be executed multiple times, once for each player, and once in `'global'` scoped apps.
|
||||
player target will be executed multiple times, once for each player app instance. While each player app instance is independent,
|
||||
statically defined event handlers will be copied to each players app, but if you want to apply them in more controlled way,
|
||||
defining event handlers for each player in `__on_start()` function is preferred.
|
||||
|
||||
Most built-in events strive to report right before they take an effect in the game. The purpose of that is that this give a choice
|
||||
for the programmer to handle them right away (as it happens, potentially affect the course of action by changing the
|
||||
@@ -21,24 +24,43 @@ more control over these events.
|
||||
|
||||
Programmers can also define their own events and signal other events, including built-in events, and across all loaded apps.
|
||||
|
||||
## Event list
|
||||
## App scopes and event distribution
|
||||
|
||||
Here is a list of events that are handled by default in scarpet. This list includes prefixes for function names, allowing apps
|
||||
to autoload them, but you can always add any function to any event (using `/script event` command)
|
||||
if it accepts required number of parameters.
|
||||
Events triggered in an app can result in zero, one, or multiple executions, depending on the type of the event, and the app scope.
|
||||
* player targeted events (like `player_breaks_block`) target each app once:
|
||||
* for global scoped apps - targets a single app instance and provides `player` as the first argument.
|
||||
* for player scoped apps - targets only a given player instance, providing player argument for API consistency,
|
||||
since active player in player scoped apps can always be retrived using `player()`.
|
||||
* global events could be handled by multiple players multiple times (like `explosion`, or `tick`):
|
||||
* for global scoped apps - triggered once for the single app instance.
|
||||
* for player scoped apps - triggered N times for each player separately, so they can do something with that information
|
||||
* custom player targeted events (using `signal_event(<event>, <player>, data)`):
|
||||
* for global scoped apps - doesn't trigger at all, since there is no way to pass the required player.
|
||||
To target global apps with player information, use `null` for player target, and add player information to the `data`
|
||||
* for player scoped apps - triggers once for the specified player and its app instance
|
||||
* custom general events (using `signal_event(<event>, null, data)`) behave same like built-in global events:
|
||||
* for global scoped apps - triggers once for the only global instance
|
||||
* for player scoped apps - triggers N times, once for each player app instance
|
||||
|
||||
## Built-in events
|
||||
|
||||
Here is the list of events that are handled by default in scarpet. This list includes prefixes for function names, allowing apps
|
||||
to register them when the app starts, but you can always add any handler function to any event using `/script event` command,
|
||||
if it accepts the required number of parameters for the event.
|
||||
|
||||
## Meta-events
|
||||
|
||||
These events are not controlled / triggered by the game per se, but are important for the flow of the apps, however for all
|
||||
intent and purpose can be treated as regular events. Unlike regular events, they cannot be hooked up to with 'handle_event',
|
||||
but the apps themselves need to have them defined as distinct function definitions, same they cannot be signalled.
|
||||
intent and purpose can be treated as regular events. Unlike regular events, they cannot be hooked up to with `handle_event()`,
|
||||
and the apps themselves need to have them defined as distinct function definitions. They also cannot be triggered via `signal_event()`.
|
||||
|
||||
### `__on_start()`
|
||||
Called once per app in its logical execution run. For `'global'` scope apps its executed right after the app is loaded. For
|
||||
`'player'` scope apps, it is triggered once per player before the app can be used by that player. Since each player app acts
|
||||
independently from other player apps, this is probably the best location to include some player specific initializations. Static
|
||||
code (i.e. code typed directly in the app code that executes immediately, outside of function definitions), will only execute once
|
||||
per app, regardless of scope, `'__on_start()'` allows to reliably call player specific initializations.
|
||||
per app, regardless of scope, `'__on_start()'` allows to reliably call player specific initializations. However, most event handlers
|
||||
defined in the static body of the app will be copied over to each player scoped instance when they join.
|
||||
|
||||
### `__on_close()`
|
||||
|
||||
@@ -50,8 +72,7 @@ the system is closing down exceptionally.
|
||||
## Built-in global events
|
||||
|
||||
Global events will be handled once per app that is with `'global'` scope. With `player` scoped apps, each player instance
|
||||
is responsible independently from handling their events, so a global event may be executed multiple times for each player.
|
||||
|
||||
will be triggerd once for each player, so a global event may be executed multiple times for such apps.
|
||||
|
||||
### `__on_server_starts()`
|
||||
Event triggers after world is loaded and after all startup apps have started. It won't be triggered with `/reload`.
|
||||
@@ -73,13 +94,13 @@ Duplicate of `tick`, just automatically located in the end. Use `__on_tick() ->
|
||||
### `__on_chunk_generated(x, z)`
|
||||
Called right after a chunk at a given coordinate is full generated. `x` and `z` correspond
|
||||
to the lowest x and z coords in the chunk. Handling of this event is scheduled as an off-tick task happening after the
|
||||
chunk is confirmed to be generated and loaded to the game, so
|
||||
handling of this event is not technically guaranteed, if the game crashes while players are moving for example, and can
|
||||
be missed on the next start, if the game successfully saves it and fails to execute all remaining tasks. In normal operation
|
||||
this should not happen, but be warned.
|
||||
chunk is confirmed to be generated and loaded to the game, due to the off-thread chunk loading in the game. So
|
||||
handling of this event is not technically guaranteed if the game crashes while players are moving for example, and the game
|
||||
decides to shut down after chunk is fully loaded and before its handler is processed in between ticks. In normal operation
|
||||
this should not happen, but let you be warned.
|
||||
|
||||
### `__on_chunk_loaded(x, z)`
|
||||
Called right after a chunk at a given coordinate is loaded. All newly generated chunks are loaded as well.
|
||||
Called right after a chunk at a given coordinate is loaded. All newly generated chunks are considered loaded as well.
|
||||
`x` and `z` correspond to the lowest x and z coordinates in the chunk.
|
||||
|
||||
### `__on_lightning(block, mode)`
|
||||
@@ -103,7 +124,7 @@ The parameter `entities` contains the list of entities that have been affected b
|
||||
Triggered when a carpet mod rule is changed. It includes extension rules, not using default `/carpet` command,
|
||||
which will then be namespaced as `namespace:rule`.
|
||||
|
||||
### entity load event -> check `entity_load_handler()`
|
||||
### Entity load event -> check in details on `entity_load_handler()`
|
||||
|
||||
These will trigger every time an entity of a given type is loaded into the game: spawned, added with a chunks,
|
||||
spawned from commands, anything really. Check `entity_load_handler()` in the entity section for details.
|
||||
|
||||
@@ -18,9 +18,7 @@ import net.minecraft.server.dedicated.DedicatedServer;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Box;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.world.World;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
@@ -607,9 +605,6 @@ public class CarpetSettings
|
||||
public static boolean waterFlow = true;
|
||||
*/
|
||||
|
||||
//@Rule(desc = "One player is required on the server to cause night to pass", category = SURVIVAL)
|
||||
//public static boolean onePlayerSleeping = false;
|
||||
|
||||
@Rule(
|
||||
desc = "Sets a different motd message on client trying to connect to the server",
|
||||
extra = "use '_' to use the startup setting from server.properties",
|
||||
@@ -762,9 +757,18 @@ public class CarpetSettings
|
||||
validate = LightBatchValidator.class
|
||||
)
|
||||
public static int lightEngineMaxBatchSize = 5;
|
||||
|
||||
@Rule(desc = "Coral structures will grow with bonemeal from coral plants", category = FEATURE)
|
||||
public static boolean renewableCoral = false;
|
||||
|
||||
public enum RenewableCoralMode {
|
||||
FALSE,
|
||||
EXPANDED,
|
||||
TRUE;
|
||||
}
|
||||
@Rule(
|
||||
desc = "Coral structures will grow with bonemeal from coral plants",
|
||||
extra = "Expanded also allows growing from coral fans for sustainable farming outside of warm oceans",
|
||||
category = FEATURE
|
||||
)
|
||||
public static RenewableCoralMode renewableCoral = RenewableCoralMode.FALSE;
|
||||
|
||||
@Rule(
|
||||
desc = "Nether basalt generator without soul sand below ",
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
package carpet.fakes;
|
||||
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
|
||||
public interface CustomPayloadC2SPacketInterface
|
||||
{
|
||||
Identifier getPacketChannel();
|
||||
PacketByteBuf getPacketData();
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package carpet.fakes;
|
||||
|
||||
public interface HungerManagerInterface {
|
||||
float getExhaustionCM();
|
||||
void setExhaustionCM(float exhaust);
|
||||
void setSaturationCM(float saturn);
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
package carpet.fakes;
|
||||
|
||||
public interface StatTypeInterface<T>
|
||||
{
|
||||
boolean hasStatCreated(T key);
|
||||
}
|
||||
@@ -5,12 +5,18 @@ import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Box;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public interface WorldInterface
|
||||
{
|
||||
Map<EntityType, Entity> getPrecookedMobs();
|
||||
Map<EntityType<?>, Entity> getPrecookedMobs();
|
||||
|
||||
boolean setBlockStateWithBlockEntity(BlockPos blockPos, BlockState blockState, BlockEntity newBlockEntity, int int1);
|
||||
|
||||
List<Entity> getOtherEntitiesLimited(@Nullable Entity except, Box box, Predicate<? super Entity> predicate, int limit);
|
||||
}
|
||||
@@ -2,7 +2,6 @@ package carpet.helpers;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import carpet.fakes.StructureFeatureInterface;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.structure.StructureManager;
|
||||
@@ -36,6 +35,7 @@ import net.minecraft.world.gen.feature.StructurePoolFeatureConfig;
|
||||
import net.minecraft.world.gen.feature.TreeFeatureConfig;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class FeatureGenerator
|
||||
@@ -175,13 +175,13 @@ public class FeatureGenerator
|
||||
}
|
||||
|
||||
public static final Map<String, Thing> featureMap = new HashMap<String, Thing>() {{
|
||||
put("oak_bees", simpleTree(ConfiguredFeatures.OAK.getConfig().setTreeDecorators(ImmutableList.of(new BeehiveTreeDecorator(1.0F)))));
|
||||
put("fancy_oak_bees", simpleTree(ConfiguredFeatures.FANCY_OAK.getConfig().setTreeDecorators(ImmutableList.of(new BeehiveTreeDecorator(1.0F)))));
|
||||
put("birch_bees", simpleTree(ConfiguredFeatures.BIRCH.getConfig().setTreeDecorators(ImmutableList.of(new BeehiveTreeDecorator(1.0F)))));
|
||||
put("oak_bees", simpleTree(ConfiguredFeatures.OAK.getConfig().setTreeDecorators(List.of(new BeehiveTreeDecorator(1.0F)))));
|
||||
put("fancy_oak_bees", simpleTree(ConfiguredFeatures.FANCY_OAK.getConfig().setTreeDecorators(List.of(new BeehiveTreeDecorator(1.0F)))));
|
||||
put("birch_bees", simpleTree(ConfiguredFeatures.BIRCH.getConfig().setTreeDecorators(List.of(new BeehiveTreeDecorator(1.0F)))));
|
||||
put("coral_tree", simplePlop(Feature.CORAL_TREE.configure(FeatureConfig.DEFAULT)));
|
||||
put("coral_claw", simplePlop(Feature.CORAL_CLAW.configure(FeatureConfig.DEFAULT)));
|
||||
put("coral_mushroom", simplePlop(Feature.CORAL_MUSHROOM.configure(FeatureConfig.DEFAULT)));
|
||||
put("coral", simplePlop(Feature.SIMPLE_RANDOM_SELECTOR.configure(new SimpleRandomFeatureConfig(ImmutableList.of(
|
||||
put("coral", simplePlop(Feature.SIMPLE_RANDOM_SELECTOR.configure(new SimpleRandomFeatureConfig(List.of(
|
||||
() -> Feature.CORAL_TREE.configure(FeatureConfig.DEFAULT),
|
||||
() -> Feature.CORAL_CLAW.configure(FeatureConfig.DEFAULT),
|
||||
() -> Feature.CORAL_MUSHROOM.configure(FeatureConfig.DEFAULT)
|
||||
@@ -191,7 +191,7 @@ public class FeatureGenerator
|
||||
new StructurePoolFeatureConfig(() -> new StructurePool(
|
||||
new Identifier("bastion/starts"),
|
||||
new Identifier("empty"),
|
||||
ImmutableList.of(
|
||||
List.of(
|
||||
Pair.of(StructurePoolElement.ofProcessedSingle("bastion/units/air_base", StructureProcessorLists.BASTION_GENERIC_DEGRADATION), 1)
|
||||
),
|
||||
StructurePool.Projection.RIGID
|
||||
@@ -203,7 +203,7 @@ public class FeatureGenerator
|
||||
new StructurePoolFeatureConfig(() -> new StructurePool(
|
||||
new Identifier("bastion/starts"),
|
||||
new Identifier("empty"),
|
||||
ImmutableList.of(
|
||||
List.of(
|
||||
Pair.of(StructurePoolElement.ofProcessedSingle("bastion/hoglin_stable/air_base", StructureProcessorLists.BASTION_GENERIC_DEGRADATION), 1)
|
||||
),
|
||||
StructurePool.Projection.RIGID
|
||||
@@ -215,7 +215,7 @@ public class FeatureGenerator
|
||||
new StructurePoolFeatureConfig(() -> new StructurePool(
|
||||
new Identifier("bastion/starts"),
|
||||
new Identifier("empty"),
|
||||
ImmutableList.of(
|
||||
List.of(
|
||||
Pair.of(StructurePoolElement.ofProcessedSingle("bastion/treasure/big_air_full", StructureProcessorLists.BASTION_GENERIC_DEGRADATION), 1)
|
||||
),
|
||||
StructurePool.Projection.RIGID
|
||||
@@ -227,7 +227,7 @@ public class FeatureGenerator
|
||||
new StructurePoolFeatureConfig(() -> new StructurePool(
|
||||
new Identifier("bastion/starts"),
|
||||
new Identifier("empty"),
|
||||
ImmutableList.of(
|
||||
List.of(
|
||||
Pair.of(StructurePoolElement.ofProcessedSingle("bastion/bridge/starting_pieces/entrance_base", StructureProcessorLists.BASTION_GENERIC_DEGRADATION), 1)
|
||||
),
|
||||
StructurePool.Projection.RIGID
|
||||
|
||||
@@ -5,8 +5,6 @@ import carpet.fakes.IngredientInterface;
|
||||
import carpet.fakes.RecipeManagerInterface;
|
||||
import carpet.utils.WoolTool;
|
||||
import carpet.utils.Messenger;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Maps;
|
||||
import it.unimi.dsi.fastutil.objects.Object2LongLinkedOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2LongMap;
|
||||
import net.minecraft.block.AbstractBannerBlock;
|
||||
@@ -42,6 +40,8 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.Map.entry;
|
||||
|
||||
/**
|
||||
* The actual object residing in each hopper counter which makes them count the items and saves them. There is one for each
|
||||
* colour in MC.
|
||||
@@ -67,7 +67,7 @@ public class HopperCounter
|
||||
{
|
||||
counterMap.put(color, new HopperCounter(color));
|
||||
}
|
||||
COUNTERS = Maps.immutableEnumMap(counterMap);
|
||||
COUNTERS = Collections.unmodifiableMap(counterMap);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -243,92 +243,91 @@ public class HopperCounter
|
||||
* Maps items that don't get a good block to reference for colour, or those that colour is wrong to a number of blocks, so we can get their colours easily with the
|
||||
* {@link Block#getDefaultMaterialColor()} method as these items have those same colours.
|
||||
*/
|
||||
private static final ImmutableMap<Item, Block> DEFAULTS = new ImmutableMap.Builder<Item, Block>()
|
||||
.put(Items.DANDELION, Blocks.YELLOW_WOOL)
|
||||
.put(Items.POPPY, Blocks.RED_WOOL)
|
||||
.put(Items.BLUE_ORCHID, Blocks.LIGHT_BLUE_WOOL)
|
||||
.put(Items.ALLIUM, Blocks.MAGENTA_WOOL)
|
||||
.put(Items.AZURE_BLUET, Blocks.SNOW_BLOCK)
|
||||
.put(Items.RED_TULIP, Blocks.RED_WOOL)
|
||||
.put(Items.ORANGE_TULIP, Blocks.ORANGE_WOOL)
|
||||
.put(Items.WHITE_TULIP, Blocks.SNOW_BLOCK)
|
||||
.put(Items.PINK_TULIP, Blocks.PINK_WOOL)
|
||||
.put(Items.OXEYE_DAISY, Blocks.SNOW_BLOCK)
|
||||
.put(Items.CORNFLOWER, Blocks.BLUE_WOOL)
|
||||
.put(Items.WITHER_ROSE, Blocks.BLACK_WOOL)
|
||||
.put(Items.LILY_OF_THE_VALLEY, Blocks.WHITE_WOOL)
|
||||
.put(Items.BROWN_MUSHROOM, Blocks.BROWN_MUSHROOM_BLOCK)
|
||||
.put(Items.RED_MUSHROOM, Blocks.RED_MUSHROOM_BLOCK)
|
||||
.put(Items.STICK, Blocks.OAK_PLANKS)
|
||||
.put(Items.GOLD_INGOT, Blocks.GOLD_BLOCK)
|
||||
.put(Items.IRON_INGOT, Blocks.IRON_BLOCK)
|
||||
.put(Items.DIAMOND, Blocks.DIAMOND_BLOCK)
|
||||
.put(Items.NETHERITE_INGOT, Blocks.NETHERITE_BLOCK)
|
||||
.put(Items.SUNFLOWER, Blocks.YELLOW_WOOL)
|
||||
.put(Items.LILAC, Blocks.MAGENTA_WOOL)
|
||||
.put(Items.ROSE_BUSH, Blocks.RED_WOOL)
|
||||
.put(Items.PEONY, Blocks.PINK_WOOL)
|
||||
.put(Items.CARROT, Blocks.ORANGE_WOOL)
|
||||
.put(Items.APPLE,Blocks.RED_WOOL)
|
||||
.put(Items.WHEAT,Blocks.HAY_BLOCK)
|
||||
.put(Items.PORKCHOP, Blocks.PINK_WOOL)
|
||||
.put(Items.RABBIT,Blocks.PINK_WOOL)
|
||||
.put(Items.CHICKEN,Blocks.WHITE_TERRACOTTA)
|
||||
.put(Items.BEEF,Blocks.NETHERRACK)
|
||||
.put(Items.ENCHANTED_GOLDEN_APPLE,Blocks.GOLD_BLOCK)
|
||||
.put(Items.COD,Blocks.WHITE_TERRACOTTA)
|
||||
.put(Items.SALMON,Blocks.ACACIA_PLANKS)
|
||||
.put(Items.ROTTEN_FLESH,Blocks.BROWN_WOOL)
|
||||
.put(Items.PUFFERFISH,Blocks.YELLOW_TERRACOTTA)
|
||||
.put(Items.TROPICAL_FISH,Blocks.ORANGE_WOOL)
|
||||
.put(Items.POTATO,Blocks.WHITE_TERRACOTTA)
|
||||
.put(Items.MUTTON, Blocks.RED_WOOL)
|
||||
.put(Items.BEETROOT,Blocks.NETHERRACK)
|
||||
.put(Items.MELON_SLICE,Blocks.MELON)
|
||||
.put(Items.POISONOUS_POTATO,Blocks.SLIME_BLOCK)
|
||||
.put(Items.SPIDER_EYE,Blocks.NETHERRACK)
|
||||
.put(Items.GUNPOWDER,Blocks.GRAY_WOOL)
|
||||
.put(Items.SCUTE,Blocks.LIME_WOOL)
|
||||
.put(Items.FEATHER,Blocks.WHITE_WOOL)
|
||||
.put(Items.FLINT,Blocks.BLACK_WOOL)
|
||||
.put(Items.LEATHER,Blocks.SPRUCE_PLANKS)
|
||||
.put(Items.GLOWSTONE_DUST,Blocks.GLOWSTONE)
|
||||
.put(Items.PAPER,Blocks.WHITE_WOOL)
|
||||
.put(Items.BRICK,Blocks.BRICKS)
|
||||
.put(Items.INK_SAC,Blocks.BLACK_WOOL)
|
||||
.put(Items.SNOWBALL,Blocks.SNOW_BLOCK)
|
||||
.put(Items.WATER_BUCKET,Blocks.WATER)
|
||||
.put(Items.LAVA_BUCKET,Blocks.LAVA)
|
||||
.put(Items.MILK_BUCKET,Blocks.WHITE_WOOL)
|
||||
.put(Items.CLAY_BALL, Blocks.CLAY)
|
||||
.put(Items.COCOA_BEANS,Blocks.COCOA)
|
||||
.put(Items.BONE,Blocks.BONE_BLOCK)
|
||||
.put(Items.COD_BUCKET,Blocks.BROWN_TERRACOTTA)
|
||||
.put(Items.PUFFERFISH_BUCKET,Blocks.YELLOW_TERRACOTTA)
|
||||
.put(Items.SALMON_BUCKET,Blocks.PINK_TERRACOTTA)
|
||||
.put(Items.TROPICAL_FISH_BUCKET,Blocks.ORANGE_TERRACOTTA)
|
||||
.put(Items.SUGAR,Blocks.WHITE_WOOL)
|
||||
.put(Items.BLAZE_POWDER,Blocks.GOLD_BLOCK)
|
||||
.put(Items.ENDER_PEARL,Blocks.WARPED_PLANKS)
|
||||
.put(Items.NETHER_STAR,Blocks.DIAMOND_BLOCK)
|
||||
.put(Items.PRISMARINE_CRYSTALS,Blocks.SEA_LANTERN)
|
||||
.put(Items.PRISMARINE_SHARD,Blocks.PRISMARINE)
|
||||
.put(Items.RABBIT_HIDE,Blocks.OAK_PLANKS)
|
||||
.put(Items.CHORUS_FRUIT,Blocks.PURPUR_BLOCK)
|
||||
.put(Items.SHULKER_SHELL,Blocks.SHULKER_BOX)
|
||||
.put(Items.NAUTILUS_SHELL,Blocks.BONE_BLOCK)
|
||||
.put(Items.HEART_OF_THE_SEA,Blocks.CONDUIT)
|
||||
.put(Items.HONEYCOMB,Blocks.HONEYCOMB_BLOCK)
|
||||
.put(Items.NAME_TAG,Blocks.BONE_BLOCK)
|
||||
.put(Items.TOTEM_OF_UNDYING,Blocks.YELLOW_TERRACOTTA)
|
||||
.put(Items.TRIDENT,Blocks.PRISMARINE)
|
||||
.put(Items.GHAST_TEAR,Blocks.WHITE_WOOL)
|
||||
.put(Items.PHANTOM_MEMBRANE,Blocks.BONE_BLOCK)
|
||||
.put(Items.EGG,Blocks.BONE_BLOCK)
|
||||
//.put(Items.,Blocks.)
|
||||
.put(Items.COPPER_INGOT,Blocks.COPPER_BLOCK)
|
||||
.put(Items.AMETHYST_SHARD, Blocks.AMETHYST_BLOCK)
|
||||
.build();
|
||||
private static final Map<Item, Block> DEFAULTS = Map.ofEntries(
|
||||
entry(Items.DANDELION, Blocks.YELLOW_WOOL),
|
||||
entry(Items.POPPY, Blocks.RED_WOOL),
|
||||
entry(Items.BLUE_ORCHID, Blocks.LIGHT_BLUE_WOOL),
|
||||
entry(Items.ALLIUM, Blocks.MAGENTA_WOOL),
|
||||
entry(Items.AZURE_BLUET, Blocks.SNOW_BLOCK),
|
||||
entry(Items.RED_TULIP, Blocks.RED_WOOL),
|
||||
entry(Items.ORANGE_TULIP, Blocks.ORANGE_WOOL),
|
||||
entry(Items.WHITE_TULIP, Blocks.SNOW_BLOCK),
|
||||
entry(Items.PINK_TULIP, Blocks.PINK_WOOL),
|
||||
entry(Items.OXEYE_DAISY, Blocks.SNOW_BLOCK),
|
||||
entry(Items.CORNFLOWER, Blocks.BLUE_WOOL),
|
||||
entry(Items.WITHER_ROSE, Blocks.BLACK_WOOL),
|
||||
entry(Items.LILY_OF_THE_VALLEY, Blocks.WHITE_WOOL),
|
||||
entry(Items.BROWN_MUSHROOM, Blocks.BROWN_MUSHROOM_BLOCK),
|
||||
entry(Items.RED_MUSHROOM, Blocks.RED_MUSHROOM_BLOCK),
|
||||
entry(Items.STICK, Blocks.OAK_PLANKS),
|
||||
entry(Items.GOLD_INGOT, Blocks.GOLD_BLOCK),
|
||||
entry(Items.IRON_INGOT, Blocks.IRON_BLOCK),
|
||||
entry(Items.DIAMOND, Blocks.DIAMOND_BLOCK),
|
||||
entry(Items.NETHERITE_INGOT, Blocks.NETHERITE_BLOCK),
|
||||
entry(Items.SUNFLOWER, Blocks.YELLOW_WOOL),
|
||||
entry(Items.LILAC, Blocks.MAGENTA_WOOL),
|
||||
entry(Items.ROSE_BUSH, Blocks.RED_WOOL),
|
||||
entry(Items.PEONY, Blocks.PINK_WOOL),
|
||||
entry(Items.CARROT, Blocks.ORANGE_WOOL),
|
||||
entry(Items.APPLE,Blocks.RED_WOOL),
|
||||
entry(Items.WHEAT,Blocks.HAY_BLOCK),
|
||||
entry(Items.PORKCHOP, Blocks.PINK_WOOL),
|
||||
entry(Items.RABBIT,Blocks.PINK_WOOL),
|
||||
entry(Items.CHICKEN,Blocks.WHITE_TERRACOTTA),
|
||||
entry(Items.BEEF,Blocks.NETHERRACK),
|
||||
entry(Items.ENCHANTED_GOLDEN_APPLE,Blocks.GOLD_BLOCK),
|
||||
entry(Items.COD,Blocks.WHITE_TERRACOTTA),
|
||||
entry(Items.SALMON,Blocks.ACACIA_PLANKS),
|
||||
entry(Items.ROTTEN_FLESH,Blocks.BROWN_WOOL),
|
||||
entry(Items.PUFFERFISH,Blocks.YELLOW_TERRACOTTA),
|
||||
entry(Items.TROPICAL_FISH,Blocks.ORANGE_WOOL),
|
||||
entry(Items.POTATO,Blocks.WHITE_TERRACOTTA),
|
||||
entry(Items.MUTTON, Blocks.RED_WOOL),
|
||||
entry(Items.BEETROOT,Blocks.NETHERRACK),
|
||||
entry(Items.MELON_SLICE,Blocks.MELON),
|
||||
entry(Items.POISONOUS_POTATO,Blocks.SLIME_BLOCK),
|
||||
entry(Items.SPIDER_EYE,Blocks.NETHERRACK),
|
||||
entry(Items.GUNPOWDER,Blocks.GRAY_WOOL),
|
||||
entry(Items.SCUTE,Blocks.LIME_WOOL),
|
||||
entry(Items.FEATHER,Blocks.WHITE_WOOL),
|
||||
entry(Items.FLINT,Blocks.BLACK_WOOL),
|
||||
entry(Items.LEATHER,Blocks.SPRUCE_PLANKS),
|
||||
entry(Items.GLOWSTONE_DUST,Blocks.GLOWSTONE),
|
||||
entry(Items.PAPER,Blocks.WHITE_WOOL),
|
||||
entry(Items.BRICK,Blocks.BRICKS),
|
||||
entry(Items.INK_SAC,Blocks.BLACK_WOOL),
|
||||
entry(Items.SNOWBALL,Blocks.SNOW_BLOCK),
|
||||
entry(Items.WATER_BUCKET,Blocks.WATER),
|
||||
entry(Items.LAVA_BUCKET,Blocks.LAVA),
|
||||
entry(Items.MILK_BUCKET,Blocks.WHITE_WOOL),
|
||||
entry(Items.CLAY_BALL, Blocks.CLAY),
|
||||
entry(Items.COCOA_BEANS,Blocks.COCOA),
|
||||
entry(Items.BONE,Blocks.BONE_BLOCK),
|
||||
entry(Items.COD_BUCKET,Blocks.BROWN_TERRACOTTA),
|
||||
entry(Items.PUFFERFISH_BUCKET,Blocks.YELLOW_TERRACOTTA),
|
||||
entry(Items.SALMON_BUCKET,Blocks.PINK_TERRACOTTA),
|
||||
entry(Items.TROPICAL_FISH_BUCKET,Blocks.ORANGE_TERRACOTTA),
|
||||
entry(Items.SUGAR,Blocks.WHITE_WOOL),
|
||||
entry(Items.BLAZE_POWDER,Blocks.GOLD_BLOCK),
|
||||
entry(Items.ENDER_PEARL,Blocks.WARPED_PLANKS),
|
||||
entry(Items.NETHER_STAR,Blocks.DIAMOND_BLOCK),
|
||||
entry(Items.PRISMARINE_CRYSTALS,Blocks.SEA_LANTERN),
|
||||
entry(Items.PRISMARINE_SHARD,Blocks.PRISMARINE),
|
||||
entry(Items.RABBIT_HIDE,Blocks.OAK_PLANKS),
|
||||
entry(Items.CHORUS_FRUIT,Blocks.PURPUR_BLOCK),
|
||||
entry(Items.SHULKER_SHELL,Blocks.SHULKER_BOX),
|
||||
entry(Items.NAUTILUS_SHELL,Blocks.BONE_BLOCK),
|
||||
entry(Items.HEART_OF_THE_SEA,Blocks.CONDUIT),
|
||||
entry(Items.HONEYCOMB,Blocks.HONEYCOMB_BLOCK),
|
||||
entry(Items.NAME_TAG,Blocks.BONE_BLOCK),
|
||||
entry(Items.TOTEM_OF_UNDYING,Blocks.YELLOW_TERRACOTTA),
|
||||
entry(Items.TRIDENT,Blocks.PRISMARINE),
|
||||
entry(Items.GHAST_TEAR,Blocks.WHITE_WOOL),
|
||||
entry(Items.PHANTOM_MEMBRANE,Blocks.BONE_BLOCK),
|
||||
entry(Items.EGG,Blocks.BONE_BLOCK),
|
||||
//entry(Items.,Blocks.),
|
||||
entry(Items.COPPER_INGOT,Blocks.COPPER_BLOCK),
|
||||
entry(Items.AMETHYST_SHARD, Blocks.AMETHYST_BLOCK));
|
||||
|
||||
/**
|
||||
* Gets the colour to print an item in when printing its count in a hopper counter.
|
||||
|
||||
@@ -180,8 +180,7 @@ public class OptimizedExplosion
|
||||
|
||||
entity.setVelocity(entity.getVelocity().add(d5 * d11, d7 * d11, d9 * d11));
|
||||
|
||||
if (entity instanceof PlayerEntity) {
|
||||
PlayerEntity player = (PlayerEntity) entity;
|
||||
if (entity instanceof PlayerEntity player) {
|
||||
|
||||
if (!player.isSpectator()
|
||||
&& (!player.isCreative() || !player.getAbilities().flying)) { //getAbilities
|
||||
|
||||
@@ -92,34 +92,11 @@ public class ExplosionLogHelper
|
||||
}
|
||||
|
||||
|
||||
public static class EntityChangedStatusWithCount
|
||||
public static record EntityChangedStatusWithCount(Vec3d pos, EntityType type, Vec3d accel)
|
||||
{
|
||||
public final Vec3d pos;
|
||||
public final EntityType type;
|
||||
public final Vec3d accel;
|
||||
|
||||
public EntityChangedStatusWithCount(Entity e, Vec3d accel)
|
||||
{
|
||||
this.pos = e.getPos();
|
||||
this.type = e.getType();
|
||||
this.accel = accel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (obj instanceof EntityChangedStatusWithCount)
|
||||
{
|
||||
EntityChangedStatusWithCount other = (EntityChangedStatusWithCount) obj;
|
||||
return other.pos.equals(pos) && other.accel.equals(accel) && other.type.equals(type);
|
||||
}
|
||||
return super.equals(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return pos.hashCode()+ type.hashCode()+accel.hashCode();
|
||||
this(e.getPos(), e.getType(), accel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,7 @@ public abstract class ArmorStandEntity_scarpetMarkerMixin extends LivingEntity
|
||||
if (owner.isPresent())
|
||||
{
|
||||
String hostName = StringUtils.removeStart(owner.get(),prefix);
|
||||
if (!hostName.isEmpty() && CarpetServer.scriptServer.getHostByName(hostName) == null)
|
||||
if (!hostName.isEmpty() && CarpetServer.scriptServer.getAppHostByName(hostName) == null)
|
||||
{
|
||||
discard(); //discard
|
||||
}
|
||||
|
||||
@@ -29,7 +29,10 @@ public abstract class CoralBlockMixin implements Fertilizable
|
||||
{
|
||||
public boolean isFertilizable(BlockView var1, BlockPos var2, BlockState var3, boolean var4)
|
||||
{
|
||||
return CarpetSettings.renewableCoral && var3.get(CoralParentBlock.WATERLOGGED) && var1.getFluidState(var2.up()).isIn(FluidTags.WATER);
|
||||
return CarpetSettings.renewableCoral == CarpetSettings.RenewableCoralMode.EXPANDED
|
||||
|| CarpetSettings.renewableCoral == CarpetSettings.RenewableCoralMode.TRUE
|
||||
&& var3.get(CoralParentBlock.WATERLOGGED)
|
||||
&& var1.getFluidState(var2.up()).isIn(FluidTags.WATER);
|
||||
}
|
||||
|
||||
public boolean canGrow(World var1, Random var2, BlockPos var3, BlockState var4)
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import carpet.fakes.CoralFeatureInterface;
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.tag.BlockTags;
|
||||
import net.minecraft.tag.FluidTags;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.BlockView;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.gen.feature.*;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@Mixin(CoralFanBlock.class)
|
||||
public abstract class CoralFanBlockMixin implements Fertilizable
|
||||
{
|
||||
public boolean isFertilizable(BlockView var1, BlockPos var2, BlockState var3, boolean var4)
|
||||
{
|
||||
return CarpetSettings.renewableCoral == CarpetSettings.RenewableCoralMode.EXPANDED
|
||||
&& var3.get(CoralParentBlock.WATERLOGGED)
|
||||
&& var1.getFluidState(var2.up()).isIn(FluidTags.WATER);
|
||||
}
|
||||
|
||||
public boolean canGrow(World var1, Random var2, BlockPos var3, BlockState var4)
|
||||
{
|
||||
return (double)var1.random.nextFloat() < 0.15D;
|
||||
}
|
||||
|
||||
public void grow(ServerWorld worldIn, Random random, BlockPos pos, BlockState blockUnder)
|
||||
{
|
||||
|
||||
CoralFeature coral;
|
||||
int variant = random.nextInt(3);
|
||||
if (variant == 0)
|
||||
coral = new CoralClawFeature(DefaultFeatureConfig.CODEC);
|
||||
else if (variant == 1)
|
||||
coral = new CoralTreeFeature(DefaultFeatureConfig.CODEC);
|
||||
else
|
||||
coral = new CoralMushroomFeature(DefaultFeatureConfig.CODEC);
|
||||
|
||||
MapColor color = blockUnder.getMapColor(worldIn, pos);
|
||||
BlockState proper_block = blockUnder;
|
||||
for (Block block: BlockTags.CORAL_BLOCKS.values())
|
||||
{
|
||||
proper_block = block.getDefaultState();
|
||||
if (proper_block.getMapColor(worldIn,pos) == color)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
worldIn.setBlockState(pos, Blocks.WATER.getDefaultState(), 4);
|
||||
|
||||
if (!((CoralFeatureInterface)coral).growSpecific(worldIn, random, pos, proper_block))
|
||||
{
|
||||
worldIn.setBlockState(pos, blockUnder, 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (worldIn.random.nextInt(10)==0)
|
||||
{
|
||||
BlockPos randomPos = pos.add(worldIn.random.nextInt(16)-8,worldIn.random.nextInt(8),worldIn.random.nextInt(16)-8 );
|
||||
if (BlockTags.CORAL_BLOCKS.contains(worldIn.getBlockState(randomPos).getBlock()))
|
||||
{
|
||||
worldIn.setBlockState(randomPos, Blocks.WET_SPONGE.getDefaultState(), 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.CustomPayloadC2SPacketInterface;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.network.packet.c2s.play.CustomPayloadC2SPacket;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
@Mixin(CustomPayloadC2SPacket.class)
|
||||
public class CustomPayloadC2SPacketMixin implements CustomPayloadC2SPacketInterface
|
||||
{
|
||||
@Shadow
|
||||
private Identifier channel;
|
||||
@Shadow
|
||||
private PacketByteBuf data;
|
||||
|
||||
@Override
|
||||
public Identifier getPacketChannel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PacketByteBuf getPacketData() {
|
||||
return new PacketByteBuf(this.data.copy());
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.HungerManagerInterface;
|
||||
import net.minecraft.entity.player.HungerManager;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
@Mixin(HungerManager.class)
|
||||
public class HungerManagerMixin_scarpetEventsMixin implements HungerManagerInterface {
|
||||
@Shadow private float exhaustion;
|
||||
@Shadow private float foodSaturationLevel;
|
||||
@Override
|
||||
public float getExhaustionCM(){ return exhaustion; }
|
||||
@Override
|
||||
public void setExhaustionCM(float exhaust) { exhaustion = exhaust; }
|
||||
@Override
|
||||
public void setSaturationCM(float saturn) { foodSaturationLevel = saturn; }
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import carpet.fakes.WorldInterface;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
@@ -28,33 +29,35 @@ public abstract class LivingEntity_maxCollisionsMixin extends Entity
|
||||
@Shadow protected abstract void pushAway(Entity entity_1);
|
||||
|
||||
@Inject(method = "tickCramming", cancellable = true, at = @At("HEAD"))
|
||||
private void tickPushingReplacement(CallbackInfo ci)
|
||||
{
|
||||
List<Entity> list_1 = this.world.getOtherEntities(this, this.getBoundingBox(), EntityPredicates.canBePushedBy(this));
|
||||
if (!list_1.isEmpty()) {
|
||||
int int_1 = this.world.getGameRules().getInt(GameRules.MAX_ENTITY_CRAMMING);
|
||||
int int_2;
|
||||
if (int_1 > 0 && list_1.size() > int_1 - 1 && this.random.nextInt(4) == 0) {
|
||||
int_2 = 0;
|
||||
private void tickPushingReplacement(CallbackInfo ci) {
|
||||
List<Entity> entities;
|
||||
if (CarpetSettings.maxEntityCollisions > 0)
|
||||
entities = ((WorldInterface) this.world).getOtherEntitiesLimited(
|
||||
this,
|
||||
this.getBoundingBox(),
|
||||
EntityPredicates.canBePushedBy(this),
|
||||
CarpetSettings.maxEntityCollisions);
|
||||
else
|
||||
entities = this.world.getOtherEntities(this, this.getBoundingBox(), EntityPredicates.canBePushedBy(this));
|
||||
|
||||
for(int int_3 = 0; int_3 < list_1.size(); ++int_3) {
|
||||
if (!((Entity)list_1.get(int_3)).hasVehicle()) {
|
||||
++int_2;
|
||||
if (!entities.isEmpty()) {
|
||||
int maxEntityCramming = this.world.getGameRules().getInt(GameRules.MAX_ENTITY_CRAMMING);
|
||||
if (maxEntityCramming > 0 && entities.size() > maxEntityCramming - 1 && this.random.nextInt(4) == 0) {
|
||||
int candidates = 0;
|
||||
|
||||
for (Entity entity : entities) {
|
||||
if (!entity.hasVehicle()) {
|
||||
++candidates;
|
||||
}
|
||||
}
|
||||
|
||||
if (int_2 > int_1 - 1) {
|
||||
if (candidates > maxEntityCramming - 1) {
|
||||
this.damage(DamageSource.CRAMMING, 6.0F);
|
||||
}
|
||||
}
|
||||
|
||||
int limit = list_1.size();
|
||||
if (CarpetSettings.maxEntityCollisions > 0)
|
||||
limit = Math.min(limit, CarpetSettings.maxEntityCollisions);
|
||||
|
||||
for(int_2 = 0; int_2 < limit; ++int_2) {
|
||||
Entity entity_1 = (Entity)list_1.get(int_2);
|
||||
this.pushAway(entity_1);
|
||||
for (Entity entity : entities) {
|
||||
this.pushAway(entity);
|
||||
}
|
||||
}
|
||||
ci.cancel();
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.CustomPayloadC2SPacketInterface;
|
||||
import carpet.network.CarpetClient;
|
||||
import carpet.network.ServerNetworkHandler;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.network.packet.c2s.play.CustomPayloadC2SPacket;
|
||||
import net.minecraft.server.network.ServerPlayNetworkHandler;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
@@ -21,10 +21,10 @@ public class ServerPlayNetworkHandlerMixin
|
||||
@Inject(method = "onCustomPayload", at = @At("HEAD"), cancellable = true)
|
||||
private void onCustomCarpetPayload(CustomPayloadC2SPacket packet, CallbackInfo ci)
|
||||
{
|
||||
Identifier channel = ((CustomPayloadC2SPacketInterface) packet).getPacketChannel();
|
||||
Identifier channel = packet.getChannel();
|
||||
if (CarpetClient.CARPET_CHANNEL.equals(channel))
|
||||
{
|
||||
ServerNetworkHandler.handleData(((CustomPayloadC2SPacketInterface) packet).getPacketData(), player);
|
||||
ServerNetworkHandler.handleData(new PacketByteBuf(packet.getData().copy()), player);
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Mixin(ServerWorld.class)
|
||||
public class ServerWorld_onePlayerSleepingMixin
|
||||
{/* removed due to 1.17 changes
|
||||
@Shadow @Final private List<ServerPlayerEntity> players;
|
||||
|
||||
@Shadow private boolean allPlayersSleeping;
|
||||
|
||||
@Inject(method = "updateSleepingPlayers", cancellable = true, at = @At("HEAD"))
|
||||
private void updateOnePlayerSleeping(CallbackInfo ci)
|
||||
{
|
||||
if(CarpetSettings.onePlayerSleeping)
|
||||
{
|
||||
allPlayersSleeping = false;
|
||||
for (ServerPlayerEntity p : players)
|
||||
if (!p.isSpectator() && p.isSleeping())
|
||||
{
|
||||
allPlayersSleeping = true;
|
||||
ci.cancel();
|
||||
return;
|
||||
}
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Redirect(method = "tick", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Ljava/util/stream/Stream;noneMatch(Ljava/util/function/Predicate;)Z"
|
||||
))
|
||||
private boolean noneMatchSleep(Stream<ServerPlayerEntity> stream, Predicate<ServerPlayerEntity> predicate)
|
||||
{
|
||||
if (CarpetSettings.onePlayerSleeping)
|
||||
return stream.anyMatch((p) -> !p.isSpectator() && p.isSleepingLongEnough());
|
||||
return stream.noneMatch(predicate);
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -79,18 +79,27 @@ public abstract class ServerWorld_tickMixin extends World
|
||||
currentSection = CarpetProfiler.start_section((World) (Object) this, "Village", CarpetProfiler.TYPE.GENERAL);
|
||||
}
|
||||
}
|
||||
@Inject(method = "tick", at = @At(
|
||||
value = "CONSTANT",
|
||||
args = "stringValue=chunkSource"
|
||||
))
|
||||
private void stopVillageSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
|
||||
{
|
||||
if (currentSection != null)
|
||||
{
|
||||
CarpetProfiler.end_current_section(currentSection);
|
||||
currentSection = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Inject(method = "tick", at = @At(
|
||||
value = "CONSTANT",
|
||||
args = "stringValue=blockEvents"
|
||||
))
|
||||
private void stopVillageStartBlockAgainSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
|
||||
private void startBlockAgainSection(BooleanSupplier booleanSupplier_1, CallbackInfo ci)
|
||||
{
|
||||
if (currentSection != null)
|
||||
{
|
||||
CarpetProfiler.end_current_section(currentSection);
|
||||
currentSection = CarpetProfiler.start_section((World) (Object) this, "Blocks", CarpetProfiler.TYPE.GENERAL);
|
||||
}
|
||||
currentSection = CarpetProfiler.start_section((World) (Object) this, "Blocks", CarpetProfiler.TYPE.GENERAL);
|
||||
}
|
||||
|
||||
@Inject(method = "tick", at = @At(
|
||||
|
||||
@@ -138,7 +138,7 @@ public class SpawnHelperMixin
|
||||
{
|
||||
if (CarpetSettings.lagFreeSpawning)
|
||||
{
|
||||
Map<EntityType, Entity> precookedMobs = ((WorldInterface)world_1).getPrecookedMobs();
|
||||
Map<EntityType<?>, Entity> precookedMobs = ((WorldInterface)world_1).getPrecookedMobs();
|
||||
if (precookedMobs.containsKey(entityType))
|
||||
//this mob has been <init>'s but not used yet
|
||||
return precookedMobs.get(entityType);
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.StatTypeInterface;
|
||||
import net.minecraft.stat.Stat;
|
||||
import net.minecraft.stat.StatType;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(StatType.class)
|
||||
public class StatType_scarpetMixin<T> implements StatTypeInterface<T>
|
||||
{
|
||||
@Shadow @Final private Map<T, Stat<T>> stats;
|
||||
|
||||
@Override
|
||||
public boolean hasStatCreated(T key)
|
||||
{
|
||||
return this.stats.containsKey(key);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import net.minecraft.util.collection.WeightedPicker;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
@Mixin(WeightedPicker.Entry.class)
|
||||
public interface WeightedPickerEntryMixin
|
||||
{/* /// not needed in 1.17
|
||||
@Accessor("weight")
|
||||
int getWeight();*/
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.WorldInterface;
|
||||
import com.google.common.collect.Lists;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.boss.dragon.EnderDragonEntity;
|
||||
import net.minecraft.entity.boss.dragon.EnderDragonPart;
|
||||
import net.minecraft.util.math.Box;
|
||||
import net.minecraft.util.profiler.Profiler;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.entity.EntityLookup;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@Mixin(World.class)
|
||||
public abstract class World_getOtherEntitiesLimited implements WorldInterface {
|
||||
|
||||
private static final RuntimeException CONTROL_FLOW_EXCEPTION = new RuntimeException("Should be caught for control flow in World_getOtherEntitiesLimited!");
|
||||
|
||||
@Override
|
||||
public List<Entity> getOtherEntitiesLimited(@Nullable Entity except, Box box, Predicate<? super Entity> predicate, int limit) {
|
||||
this.getProfiler().visit("getEntities");
|
||||
AtomicInteger checkedEntities = new AtomicInteger();
|
||||
List<Entity> list = Lists.newArrayList();
|
||||
try {
|
||||
this.getEntityLookup().forEachIntersects(box, (entity) -> {
|
||||
if (checkedEntities.getAndIncrement() > limit) {
|
||||
throw CONTROL_FLOW_EXCEPTION;
|
||||
}
|
||||
|
||||
if (entity != except && predicate.test(entity)) {
|
||||
list.add(entity);
|
||||
}
|
||||
|
||||
if (entity instanceof EnderDragonEntity) {
|
||||
EnderDragonPart[] var4 = ((EnderDragonEntity) entity).getBodyParts();
|
||||
|
||||
for (EnderDragonPart enderDragonPart : var4) {
|
||||
if (entity != except && predicate.test(enderDragonPart)) {
|
||||
list.add(enderDragonPart);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (RuntimeException e) {
|
||||
if (e != CONTROL_FLOW_EXCEPTION)
|
||||
// If it wasn't the exception we were watching, rethrow it
|
||||
throw e;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Shadow
|
||||
public abstract Profiler getProfiler();
|
||||
|
||||
@Shadow
|
||||
protected abstract EntityLookup<Entity> getEntityLookup();
|
||||
}
|
||||
@@ -3,23 +3,18 @@ package carpet.mixins;
|
||||
import carpet.fakes.WorldInterface;
|
||||
import carpet.helpers.TickSpeed;
|
||||
import carpet.utils.CarpetProfiler;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.util.profiler.Profiler;
|
||||
import net.minecraft.world.World;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@@ -30,9 +25,9 @@ public abstract class World_tickMixin implements WorldInterface
|
||||
CarpetProfiler.ProfilerToken currentSection;
|
||||
CarpetProfiler.ProfilerToken entitySection;
|
||||
|
||||
Map<EntityType, Entity> precookedMobs = new HashMap<>();
|
||||
Map<EntityType<?>, Entity> precookedMobs = new HashMap<>();
|
||||
|
||||
public Map<EntityType, Entity> getPrecookedMobs()
|
||||
public Map<EntityType<?>, Entity> getPrecookedMobs()
|
||||
{
|
||||
return precookedMobs;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,9 @@ package carpet.script;
|
||||
import carpet.CarpetServer;
|
||||
import carpet.CarpetSettings;
|
||||
import carpet.helpers.TickSpeed;
|
||||
import carpet.script.exception.IntegrityException;
|
||||
import carpet.script.exception.InternalExpressionException;
|
||||
import carpet.script.exception.InvalidCallbackException;
|
||||
import carpet.script.value.BlockValue;
|
||||
import carpet.script.value.BooleanValue;
|
||||
import carpet.script.value.EntityValue;
|
||||
@@ -25,7 +27,6 @@ import net.minecraft.entity.TntEntity;
|
||||
import net.minecraft.entity.damage.DamageSource;
|
||||
import net.minecraft.entity.passive.MerchantEntity;
|
||||
import net.minecraft.entity.projectile.ProjectileEntity;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
@@ -46,7 +47,6 @@ import net.minecraft.village.Merchant;
|
||||
import net.minecraft.village.TradeOffer;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.explosion.Explosion;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -70,10 +70,17 @@ import java.util.stream.Collectors;
|
||||
public class CarpetEventServer
|
||||
{
|
||||
public final List<ScheduledCall> scheduledCalls = new LinkedList<>();
|
||||
public final MinecraftServer server;
|
||||
public final CarpetScriptServer scriptServer;
|
||||
private static final List<Value> NOARGS = Collections.emptyList();
|
||||
public final Map<String, Event> customEvents = new HashMap<>();
|
||||
|
||||
|
||||
|
||||
public enum CallbackResult
|
||||
{
|
||||
SUCCESS, PASS, FAIL
|
||||
}
|
||||
|
||||
public static class Callback
|
||||
{
|
||||
public final String host;
|
||||
@@ -81,7 +88,6 @@ public class CarpetEventServer
|
||||
public final FunctionValue function;
|
||||
public final List<Value> parametrizedArgs;
|
||||
|
||||
|
||||
public Callback(String host, String target, FunctionValue function, List<Value> parametrizedArgs)
|
||||
{
|
||||
this.host = host;
|
||||
@@ -95,18 +101,17 @@ public class CarpetEventServer
|
||||
* @param sender - entity command source
|
||||
* @param runtimeArgs = options
|
||||
*/
|
||||
public boolean execute(ServerCommandSource sender, List<Value> runtimeArgs)
|
||||
public CallbackResult execute(ServerCommandSource sender, List<Value> runtimeArgs)
|
||||
{
|
||||
if (!this.parametrizedArgs.isEmpty())
|
||||
{
|
||||
runtimeArgs = new ArrayList<>(runtimeArgs);
|
||||
runtimeArgs.addAll(this.parametrizedArgs);
|
||||
}
|
||||
if (CarpetServer.scriptServer == null) return false; // already stopped
|
||||
return CarpetServer.scriptServer.runEventCall(
|
||||
if (CarpetServer.scriptServer == null) return CallbackResult.FAIL; // already stopped
|
||||
return CarpetServer.scriptServer.events.runEventCall(
|
||||
sender.withLevel(CarpetSettings.runPermissionLevel),
|
||||
host, optionalTarget, function, runtimeArgs
|
||||
);
|
||||
host, optionalTarget, function, runtimeArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,18 +120,12 @@ public class CarpetEventServer
|
||||
* @param optionalRecipient - optional target player argument
|
||||
* @param runtimeArgs = options
|
||||
*/
|
||||
public int signal(ServerCommandSource sender, ServerPlayerEntity optionalRecipient, List<Value> runtimeArgs)
|
||||
public CallbackResult signal(ServerCommandSource sender, ServerPlayerEntity optionalRecipient, List<Value> runtimeArgs)
|
||||
{
|
||||
// recipent of the call doesn't match the handlingHost
|
||||
if (optionalRecipient != null && !optionalRecipient.getEntityName().equals(optionalTarget))
|
||||
return 0;
|
||||
List<Value> args = runtimeArgs;
|
||||
if (!this.parametrizedArgs.isEmpty())
|
||||
{
|
||||
args = new ArrayList<>(runtimeArgs);
|
||||
args.addAll(this.parametrizedArgs);
|
||||
}
|
||||
return CarpetServer.scriptServer.signal(sender, optionalRecipient, host, function, args, false);
|
||||
return CallbackResult.FAIL;
|
||||
return execute(sender, runtimeArgs);
|
||||
}
|
||||
|
||||
|
||||
@@ -135,18 +134,8 @@ public class CarpetEventServer
|
||||
{
|
||||
return function.getString()+((host==null)?"":"(from "+host+(optionalTarget == null?"":"/"+optionalTarget)+")");
|
||||
}
|
||||
public static class Signature
|
||||
{
|
||||
String function;
|
||||
String host;
|
||||
String target;
|
||||
public Signature(String fun, String h, String t)
|
||||
{
|
||||
function = fun;
|
||||
host = h;
|
||||
target = t;
|
||||
}
|
||||
}
|
||||
public static record Signature(String function, String host, String target) {}
|
||||
|
||||
public static Signature fromString(String str)
|
||||
{
|
||||
Pattern find = Pattern.compile("(\\w+)(?:\\(from (\\w+)(?:/(\\w+))?\\))?");
|
||||
@@ -178,10 +167,8 @@ public class CarpetEventServer
|
||||
*/
|
||||
public void execute()
|
||||
{
|
||||
CarpetServer.scriptServer.runScheduledCall(ctx.origin, ctx.s, host, (CarpetScriptHost) ctx.host, function, parametrizedArgs);
|
||||
CarpetServer.scriptServer.events.runScheduledCall(ctx.origin, ctx.s, host, (CarpetScriptHost) ctx.host, function, parametrizedArgs);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static class CallbackList
|
||||
@@ -190,7 +177,6 @@ public class CarpetEventServer
|
||||
public final List<Callback> callList;
|
||||
public final int reqArgs;
|
||||
final boolean isSystem;
|
||||
final boolean isGlobalOnly;
|
||||
final boolean perPlayerDistribution;
|
||||
|
||||
public CallbackList(int reqArgs, boolean isSystem, boolean isGlobalOnly)
|
||||
@@ -198,7 +184,6 @@ public class CarpetEventServer
|
||||
this.callList = new ArrayList<>();
|
||||
this.reqArgs = reqArgs;
|
||||
this.isSystem = isSystem;
|
||||
this.isGlobalOnly = isGlobalOnly;
|
||||
perPlayerDistribution = isSystem && !isGlobalOnly;
|
||||
}
|
||||
|
||||
@@ -230,7 +215,7 @@ public class CarpetEventServer
|
||||
// supressing calls where target player hosts simply don't match
|
||||
// handling global hosts with player targets is left to when the host is resolved (few calls deeper).
|
||||
if (nameCheck != null && call.optionalTarget != null && !nameCheck.equals(call.optionalTarget)) continue;
|
||||
if (!call.execute(source, argv)) fails.add(call);
|
||||
if (call.execute(source, argv) == CallbackResult.FAIL) fails.add(call);
|
||||
}
|
||||
for (Callback call : fails) callList.remove(call);
|
||||
CarpetProfiler.end_current_section(currentSection);
|
||||
@@ -245,7 +230,9 @@ public class CarpetEventServer
|
||||
int successes = 0;
|
||||
for (Callback call: callList)
|
||||
{
|
||||
successes += Math.max(0, call.signal(sender, optinoalReceipient, callArg));
|
||||
//successes += Math.max(0, call.signal(sender, optinoalReceipient, callArg));
|
||||
if (call.signal(sender, optinoalReceipient, callArg) == CallbackResult.SUCCESS) successes ++;
|
||||
|
||||
}
|
||||
//for (Callback call : fails) callList.remove(call);
|
||||
return successes;
|
||||
@@ -253,7 +240,7 @@ public class CarpetEventServer
|
||||
|
||||
public boolean addFromExternal(ServerCommandSource source, String hostName, String funName, Consumer<ScriptHost> hostOnEventHandler)
|
||||
{
|
||||
ScriptHost host = CarpetServer.scriptServer.getHostByName(hostName);
|
||||
ScriptHost host = CarpetServer.scriptServer.getAppHostByName(hostName);
|
||||
if (host == null)
|
||||
{
|
||||
// impossible call to add
|
||||
@@ -991,8 +978,6 @@ public class CarpetEventServer
|
||||
public final String name;
|
||||
|
||||
public final CallbackList handler;
|
||||
@Deprecated
|
||||
public final boolean globalOnly;
|
||||
public final boolean isPublic; // public events can be targetted with __on_<event> defs
|
||||
public Event(String name, int reqArgs, boolean isGlobalOnly)
|
||||
{
|
||||
@@ -1002,7 +987,6 @@ public class CarpetEventServer
|
||||
{
|
||||
this.name = name;
|
||||
this.handler = new CallbackList(reqArgs, true, isGlobalOnly);
|
||||
this.globalOnly = isGlobalOnly;
|
||||
this.isPublic = isPublic;
|
||||
byName.put(name, this);
|
||||
}
|
||||
@@ -1050,7 +1034,6 @@ public class CarpetEventServer
|
||||
{
|
||||
this.name = name;
|
||||
this.handler = new CallbackList(1, false, false);
|
||||
this.globalOnly = false;
|
||||
this.isPublic = true;
|
||||
server.events.customEvents.put(name, this);
|
||||
}
|
||||
@@ -1122,9 +1105,9 @@ public class CarpetEventServer
|
||||
}
|
||||
|
||||
|
||||
public CarpetEventServer(MinecraftServer server)
|
||||
public CarpetEventServer(CarpetScriptServer scriptServer)
|
||||
{
|
||||
this.server = server;
|
||||
this.scriptServer = scriptServer;
|
||||
Event.clearAllBuiltinEvents();
|
||||
}
|
||||
|
||||
@@ -1155,6 +1138,45 @@ public class CarpetEventServer
|
||||
scheduledCalls.add(new ScheduledCall(context, function, args, due));
|
||||
}
|
||||
|
||||
public void runScheduledCall(BlockPos origin, ServerCommandSource source, String hostname, CarpetScriptHost host, FunctionValue udf, List<Value> argv)
|
||||
{
|
||||
if (hostname != null && !scriptServer.modules.containsKey(hostname)) // well - scheduled call app got unloaded
|
||||
return;
|
||||
try
|
||||
{
|
||||
host.callUDF(origin, source, udf, argv);
|
||||
}
|
||||
catch (NullPointerException | InvalidCallbackException | IntegrityException ignored) { }
|
||||
}
|
||||
|
||||
public CallbackResult runEventCall(ServerCommandSource sender, String hostname, String optionalTarget, FunctionValue udf, List<Value> argv)
|
||||
{
|
||||
CarpetScriptHost appHost = scriptServer.getAppHostByName(hostname);
|
||||
// no such app
|
||||
if (appHost == null) return CallbackResult.FAIL;
|
||||
// dummy call for player apps that reside on the global copy - do not run them, but report as passes.
|
||||
if (appHost.isPerUser() && optionalTarget==null) return CallbackResult.PASS;
|
||||
ServerPlayerEntity target = null;
|
||||
if (optionalTarget != null)
|
||||
{
|
||||
target = sender.getServer().getPlayerManager().getPlayer(optionalTarget);
|
||||
if (target == null) return CallbackResult.FAIL;
|
||||
}
|
||||
ServerCommandSource source = sender.withLevel(CarpetSettings.runPermissionLevel);
|
||||
CarpetScriptHost executingHost = appHost.retrieveForExecution(sender, target);
|
||||
if (executingHost == null) return CallbackResult.FAIL;
|
||||
try
|
||||
{
|
||||
executingHost.callUDF(BlockPos.ORIGIN, source.withLevel(CarpetSettings.runPermissionLevel), udf, argv);
|
||||
return CallbackResult.SUCCESS;
|
||||
}
|
||||
catch (NullPointerException | InvalidCallbackException | IntegrityException error)
|
||||
{
|
||||
CarpetScriptServer.LOG.error("Got exception: "+error.getMessage());
|
||||
return CallbackResult.FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean addEventFromCommand(ServerCommandSource source, String event, String host, String funName)
|
||||
{
|
||||
Event ev = Event.getEvent(event, CarpetServer.scriptServer);
|
||||
@@ -1178,7 +1200,7 @@ public class CarpetEventServer
|
||||
|
||||
public boolean handleCustomEvent(String event, CarpetScriptHost host, FunctionValue function, List<Value> args)
|
||||
{
|
||||
Event ev = Event.getOrCreateCustom(event, host.getScriptServer());
|
||||
Event ev = Event.getOrCreateCustom(event, scriptServer);
|
||||
onEventAddedToHost(ev, host);
|
||||
return ev.handler.addEventCallInternal(host, function, args==null?NOARGS:args);
|
||||
}
|
||||
@@ -1233,15 +1255,4 @@ public class CarpetEventServer
|
||||
// remove scheduled calls
|
||||
scheduledCalls.removeIf(sc -> sc.host != null && sc.host.equals(host.getName()));
|
||||
}
|
||||
|
||||
private Pair<String,String> decodeCallback(String funName)
|
||||
{
|
||||
Pattern find = Pattern.compile("(\\w+)\\(from (\\w+)\\)");
|
||||
Matcher matcher = find.matcher(funName);
|
||||
if(matcher.matches())
|
||||
{
|
||||
return Pair.of(matcher.group(2), matcher.group(1));
|
||||
}
|
||||
return Pair.of(null, funName);
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import carpet.script.command.CommandArgument;
|
||||
import carpet.script.command.CommandToken;
|
||||
import carpet.script.exception.CarpetExpressionException;
|
||||
import carpet.script.exception.ExpressionException;
|
||||
import carpet.script.exception.IntegrityException;
|
||||
import carpet.script.exception.InternalExpressionException;
|
||||
import carpet.script.exception.InvalidCallbackException;
|
||||
import carpet.script.utils.AppStoreManager;
|
||||
@@ -644,37 +645,19 @@ public class CarpetScriptHost extends ScriptHost
|
||||
}
|
||||
}
|
||||
|
||||
public List<CarpetScriptHost> retrieveForExecution(ServerCommandSource source, String optionalTarget)
|
||||
public CarpetScriptHost retrieveForExecution(ServerCommandSource source, ServerPlayerEntity player)
|
||||
{
|
||||
List<CarpetScriptHost> targets = new ArrayList<>();
|
||||
if (perUser)
|
||||
CarpetScriptHost target = null;
|
||||
if (!perUser)
|
||||
{
|
||||
if (optionalTarget == null)
|
||||
{
|
||||
for (ServerPlayerEntity player : source.getServer().getPlayerManager().getPlayerList())
|
||||
{
|
||||
CarpetScriptHost host = (CarpetScriptHost) retrieveForExecution(player.getEntityName());
|
||||
targets.add(host);
|
||||
if (host.errorSnooper == null) host.setChatErrorSnooper(player.getCommandSource());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ServerPlayerEntity player = source.getServer().getPlayerManager().getPlayer(optionalTarget);
|
||||
if (player != null)
|
||||
{
|
||||
CarpetScriptHost host = (CarpetScriptHost) retrieveForExecution(player.getEntityName());
|
||||
targets.add(host);
|
||||
if (host.errorSnooper == null) host.setChatErrorSnooper(player.getCommandSource());
|
||||
}
|
||||
}
|
||||
target = this;
|
||||
}
|
||||
else
|
||||
else if (player != null)
|
||||
{
|
||||
targets.add(this);
|
||||
if (this.errorSnooper == null) this.setChatErrorSnooper(source);
|
||||
target = (CarpetScriptHost) retrieveForExecution(player.getEntityName());
|
||||
}
|
||||
return targets;
|
||||
if (target != null && target.errorSnooper == null) target.setChatErrorSnooper(source);
|
||||
return target;
|
||||
}
|
||||
|
||||
public CarpetScriptHost retrieveOwnForExecution(ServerCommandSource source) throws CommandSyntaxException
|
||||
@@ -830,6 +813,7 @@ public class CarpetScriptHost extends ScriptHost
|
||||
try
|
||||
{
|
||||
// TODO: this is just for now - invoke would be able to invoke other hosts scripts
|
||||
assertAppIntegrity(function.getModule());
|
||||
Context context = new CarpetContext(this, source, BlockPos.ORIGIN);
|
||||
return function.getExpression().evalValue(
|
||||
() -> function.lazyEval(context, Context.VOID, function.getExpression(), function.getToken(), argv),
|
||||
@@ -860,7 +844,7 @@ public class CarpetScriptHost extends ScriptHost
|
||||
}
|
||||
try
|
||||
{
|
||||
// TODO: this is just for now - invoke would be able to invoke other hosts scripts
|
||||
assertAppIntegrity(function.getModule());
|
||||
Context context = new CarpetContext(this, source, BlockPos.ORIGIN);
|
||||
return function.getExpression().evalValue(
|
||||
() -> function.execute(context, Context.VOID, function.getExpression(), function.getToken(), argv),
|
||||
@@ -874,7 +858,7 @@ public class CarpetScriptHost extends ScriptHost
|
||||
}
|
||||
}
|
||||
|
||||
public Value callUDF(BlockPos pos, ServerCommandSource source, FunctionValue fun, List<Value> argv) throws InvalidCallbackException
|
||||
public Value callUDF(BlockPos pos, ServerCommandSource source, FunctionValue fun, List<Value> argv) throws InvalidCallbackException, IntegrityException
|
||||
{
|
||||
if (CarpetServer.scriptServer.stopAll)
|
||||
return Value.NULL;
|
||||
@@ -889,7 +873,7 @@ public class CarpetScriptHost extends ScriptHost
|
||||
}
|
||||
try
|
||||
{
|
||||
// TODO: this is just for now - invoke would be able to invoke other hosts scripts
|
||||
assertAppIntegrity(fun.getModule());
|
||||
Context context = new CarpetContext(this, source, pos);
|
||||
return fun.getExpression().evalValue(
|
||||
() -> fun.execute(context, Context.VOID, fun.getExpression(), fun.getToken(), argv),
|
||||
|
||||
@@ -12,8 +12,6 @@ import carpet.script.bundled.BundledModule;
|
||||
import carpet.CarpetServer;
|
||||
import carpet.script.bundled.FileModule;
|
||||
import carpet.script.bundled.Module;
|
||||
import carpet.script.exception.IntegrityException;
|
||||
import carpet.script.exception.InvalidCallbackException;
|
||||
import carpet.script.language.Arithmetic;
|
||||
import carpet.script.language.ControlFlow;
|
||||
import carpet.script.language.DataStructures;
|
||||
@@ -23,7 +21,6 @@ import carpet.script.language.Sys;
|
||||
import carpet.script.language.Threading;
|
||||
import carpet.script.utils.AppStoreManager;
|
||||
import carpet.script.value.FunctionValue;
|
||||
import carpet.script.value.Value;
|
||||
import carpet.utils.CarpetProfiler;
|
||||
import carpet.utils.Messenger;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
@@ -35,7 +32,6 @@ import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.util.WorldSavePath;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
@@ -94,7 +90,7 @@ public class CarpetScriptServer
|
||||
* @param app The {@link BundledModule} of the app.
|
||||
*/
|
||||
public static void registerSettingsApp(BundledModule app) {
|
||||
ruleModuleData.add(app);
|
||||
ruleModuleData.add(app);
|
||||
}
|
||||
|
||||
static
|
||||
@@ -120,9 +116,9 @@ public class CarpetScriptServer
|
||||
private void init()
|
||||
{
|
||||
ScriptHost.systemGlobals.clear();
|
||||
events = new CarpetEventServer(server);
|
||||
events = new CarpetEventServer(this);
|
||||
modules = new HashMap<>();
|
||||
unloadableModules = new HashSet<String>();
|
||||
unloadableModules = new HashSet<>();
|
||||
tickStart = 0L;
|
||||
stopAll = false;
|
||||
holyMoly = server.getCommandManager().getDispatcher().getRoot().getChildren().stream().map(CommandNode::getName).collect(Collectors.toSet());
|
||||
@@ -232,7 +228,7 @@ public class CarpetScriptServer
|
||||
return moduleNames;
|
||||
}
|
||||
|
||||
public ScriptHost getHostByName(String name)
|
||||
public CarpetScriptHost getAppHostByName(String name)
|
||||
{
|
||||
if (name == null)
|
||||
return globalHost;
|
||||
@@ -310,7 +306,10 @@ public class CarpetScriptServer
|
||||
if (newHost.isPerUser())
|
||||
{
|
||||
// that will provide player hosts right at the startup
|
||||
newHost.retrieveForExecution(source, null);
|
||||
for (ServerPlayerEntity player : source.getServer().getPlayerManager().getPlayerList())
|
||||
{
|
||||
newHost.retrieveForExecution(player.getCommandSource(), player);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -372,86 +371,6 @@ public class CarpetScriptServer
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean runEventCall(ServerCommandSource sender, String hostname, String optionalTarget, FunctionValue udf, List<Value> argv)
|
||||
{
|
||||
CarpetScriptHost host = globalHost;
|
||||
if (hostname != null)
|
||||
host = modules.get(hostname);
|
||||
if (host == null) return false;
|
||||
// dummy call for player apps that reside on the global copy - do not run them, but report as successes.
|
||||
if (host.isPerUser() && optionalTarget==null) return true;
|
||||
ServerPlayerEntity target = null;
|
||||
if (optionalTarget != null)
|
||||
{
|
||||
target = sender.getServer().getPlayerManager().getPlayer(optionalTarget);
|
||||
if (target == null) return false;
|
||||
}
|
||||
int successes = signal(sender, target, hostname, udf, argv, true );
|
||||
return successes >= 0;
|
||||
}
|
||||
|
||||
public void runScheduledCall(BlockPos origin, ServerCommandSource source, String hostname, CarpetScriptHost host, FunctionValue udf, List<Value> argv)
|
||||
{
|
||||
if (hostname != null && !modules.containsKey(hostname)) // well - scheduled call app got unloaded
|
||||
return;
|
||||
try
|
||||
{
|
||||
host.callUDF(origin, source, udf, argv);
|
||||
}
|
||||
catch (NullPointerException | InvalidCallbackException ignored)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns number of successful calls in the host or -1 if failed exceptionally
|
||||
* @param sender
|
||||
* @param optionalRecipient
|
||||
* @param hostname
|
||||
* @param udf
|
||||
* @param argv
|
||||
* @param reportFails - returns -1 when any call failed
|
||||
* @return
|
||||
*/
|
||||
public int signal(ServerCommandSource sender, ServerPlayerEntity optionalRecipient, String hostname, FunctionValue udf, List<Value> argv, boolean reportFails)
|
||||
{
|
||||
|
||||
if (hostname == null)
|
||||
{
|
||||
if (optionalRecipient != null) return 0;
|
||||
try
|
||||
{
|
||||
globalHost.callUDF(BlockPos.ORIGIN, sender, udf, argv);
|
||||
}
|
||||
catch (NullPointerException | InvalidCallbackException npe)
|
||||
{
|
||||
return reportFails?-1:0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
String hostRecipient = optionalRecipient == null?null:optionalRecipient.getEntityName();
|
||||
ServerCommandSource source = (optionalRecipient == null)? sender : optionalRecipient.getCommandSource().withLevel(CarpetSettings.runPermissionLevel);
|
||||
int successes = 0;
|
||||
for (CarpetScriptHost host : modules.get(hostname).retrieveForExecution(sender, hostRecipient))
|
||||
{
|
||||
// getPlayer will always return nonnull cause retrieve for execution only returns hosts for existing players.
|
||||
ServerCommandSource executingSource = host.perUser
|
||||
? source.getServer().getPlayerManager().getPlayer(host.user).getCommandSource()
|
||||
: source.getServer().getCommandSource();
|
||||
try
|
||||
{
|
||||
host.callUDF(BlockPos.ORIGIN, source.withLevel(CarpetSettings.runPermissionLevel), udf, argv);
|
||||
}
|
||||
catch (NullPointerException | InvalidCallbackException | IntegrityException npe)
|
||||
{
|
||||
if (reportFails) return -1;
|
||||
continue;
|
||||
}
|
||||
successes ++;
|
||||
}
|
||||
return successes;
|
||||
}
|
||||
|
||||
public void tick()
|
||||
{
|
||||
CarpetProfiler.ProfilerToken token;
|
||||
@@ -493,16 +412,11 @@ public class CarpetScriptServer
|
||||
});
|
||||
}
|
||||
|
||||
static class TransferData
|
||||
private static record TransferData(boolean perUser, Predicate<ServerCommandSource> commandValidator, boolean isRuleApp)
|
||||
{
|
||||
boolean perUser;
|
||||
Predicate<ServerCommandSource> commandValidator;
|
||||
boolean isRuleApp;
|
||||
private TransferData(CarpetScriptHost host)
|
||||
{
|
||||
perUser = host.perUser;
|
||||
commandValidator = host.commandValidator;
|
||||
isRuleApp = host.isRuleApp;
|
||||
this(host.perUser, host.commandValidator, host.isRuleApp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ import carpet.script.value.StringValue;
|
||||
import carpet.script.value.Value;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.damage.DamageSource;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@@ -20,7 +19,8 @@ import java.util.Map;
|
||||
|
||||
public class EntityEventsGroup
|
||||
{
|
||||
private final Map<Event, Map<Pair<String,String>, CarpetEventServer.Callback>> actions;
|
||||
private static record EventKey(String host, String user) {}
|
||||
private final Map<Event, Map<EventKey, CarpetEventServer.Callback>> actions;
|
||||
private final Entity entity;
|
||||
public EntityEventsGroup(Entity e)
|
||||
{
|
||||
@@ -31,28 +31,28 @@ public class EntityEventsGroup
|
||||
public void onEvent(Event type, Object... args)
|
||||
{
|
||||
if (actions.isEmpty()) return; // most of the cases, trying to be nice
|
||||
Map<Pair<String,String>, CarpetEventServer.Callback> actionSet = actions.get(type);
|
||||
Map<EventKey, CarpetEventServer.Callback> actionSet = actions.get(type);
|
||||
if (actionSet == null) return;
|
||||
if (CarpetServer.scriptServer == null) return; // executed after world is closin down
|
||||
for (Iterator<Map.Entry<Pair<String,String>, CarpetEventServer.Callback>> iterator = actionSet.entrySet().iterator(); iterator.hasNext(); )
|
||||
for (Iterator<Map.Entry<EventKey, CarpetEventServer.Callback>> iterator = actionSet.entrySet().iterator(); iterator.hasNext(); )
|
||||
{
|
||||
Map.Entry<Pair<String,String>, CarpetEventServer.Callback> action = iterator.next();
|
||||
Pair<String,String> key = action.getKey();
|
||||
ScriptHost host = CarpetServer.scriptServer.getHostByName(key.getLeft());
|
||||
Map.Entry<EventKey, CarpetEventServer.Callback> action = iterator.next();
|
||||
EventKey key = action.getKey();
|
||||
ScriptHost host = CarpetServer.scriptServer.getAppHostByName(key.host());
|
||||
if (host == null)
|
||||
{
|
||||
iterator.remove();
|
||||
continue;
|
||||
}
|
||||
if (key.getRight() != null)
|
||||
if (key.user() != null)
|
||||
{
|
||||
if (entity.getServer().getPlayerManager().getPlayer(key.getRight())==null)
|
||||
if (entity.getServer().getPlayerManager().getPlayer(key.user())==null)
|
||||
{
|
||||
iterator.remove();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!type.call(action.getValue(), entity, args))
|
||||
if (type.call(action.getValue(), entity, args) == CarpetEventServer.CallbackResult.FAIL)
|
||||
iterator.remove();
|
||||
}
|
||||
if (actionSet.isEmpty()) actions.remove(type);
|
||||
@@ -60,7 +60,7 @@ public class EntityEventsGroup
|
||||
|
||||
public void addEvent(Event type, ScriptHost host, FunctionValue fun, List<Value> extraargs)
|
||||
{
|
||||
Pair<String,String> key = Pair.of(host.getName(), host.user);
|
||||
EventKey key = new EventKey(host.getName(), host.user);
|
||||
if (fun != null)
|
||||
{
|
||||
CarpetEventServer.Callback call = type.create(key, fun, extraargs);
|
||||
@@ -117,15 +117,15 @@ public class EntityEventsGroup
|
||||
argcount = args+1; // entity is not extra
|
||||
byName.put(identifier, this);
|
||||
}
|
||||
public CarpetEventServer.Callback create(Pair<String,String> key, FunctionValue function, List<Value> extraArgs)
|
||||
public CarpetEventServer.Callback create(EventKey key, FunctionValue function, List<Value> extraArgs)
|
||||
{
|
||||
if ((function.getArguments().size()-(extraArgs == null ? 0 : extraArgs.size())) != argcount)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new CarpetEventServer.Callback(key.getLeft(), key.getRight(), function, extraArgs);
|
||||
return new CarpetEventServer.Callback(key.host(), key.user(), function, extraArgs);
|
||||
}
|
||||
public boolean call(CarpetEventServer.Callback tickCall, Entity entity, Object ... args)
|
||||
public CarpetEventServer.CallbackResult call(CarpetEventServer.Callback tickCall, Entity entity, Object ... args)
|
||||
{
|
||||
assert args.length == argcount-1;
|
||||
return tickCall.execute(entity.getCommandSource(), makeArgs(entity, args));
|
||||
|
||||
@@ -33,8 +33,6 @@ import carpet.script.value.FunctionValue;
|
||||
import carpet.script.value.NumericValue;
|
||||
import carpet.script.value.StringValue;
|
||||
import carpet.script.value.Value;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
|
||||
import java.math.BigInteger;
|
||||
@@ -98,7 +96,7 @@ public class Expression
|
||||
functionalEquivalence.put(operator, function);
|
||||
}
|
||||
|
||||
private final Map<String, Value> constants = ImmutableMap.of(
|
||||
private final Map<String, Value> constants = Map.of(
|
||||
"euler", Arithmetic.euler,
|
||||
"pi", Arithmetic.PI,
|
||||
"null", Value.NULL,
|
||||
@@ -972,7 +970,7 @@ public class Expression
|
||||
final ExpressionNode v1 = nodeStack.pop();
|
||||
final ExpressionNode v2 = nodeStack.pop();
|
||||
LazyValue result = (c,t) -> operators.get(token.surface).lazyEval(c, t,this, token, v2.op, v1.op).evalValue(c, t);
|
||||
nodeStack.push(new ExpressionNode(result, ImmutableList.of(v2, v1), token ));
|
||||
nodeStack.push(new ExpressionNode(result, List.of(v2, v1), token ));
|
||||
break;
|
||||
case VARIABLE:
|
||||
Value constant = getConstantFor(token.surface);
|
||||
|
||||
@@ -101,10 +101,12 @@ public abstract class Fluff
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumParams() {
|
||||
return numParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean numParamsVaries() {
|
||||
return numParams < 0;
|
||||
}
|
||||
@@ -162,6 +164,7 @@ public abstract class Fluff
|
||||
return new LazyValue()
|
||||
{ // eager evaluation always ignores the required type and evals params by none default
|
||||
private List<Value> params;
|
||||
@Override
|
||||
public Value evalValue(Context c, Context.Type type)
|
||||
{
|
||||
ILazyFunction.checkInterrupts();
|
||||
@@ -202,10 +205,12 @@ public abstract class Fluff
|
||||
this.leftAssoc = leftAssoc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPrecedence() {
|
||||
return precedence;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLeftAssoc() {
|
||||
return leftAssoc;
|
||||
}
|
||||
|
||||
@@ -305,6 +305,11 @@ public abstract class ScriptHost
|
||||
return data;
|
||||
}
|
||||
|
||||
protected void assertAppIntegrity(Module module)
|
||||
{
|
||||
getModuleData(module);
|
||||
}
|
||||
|
||||
public void addUserDefinedFunction(Context ctx, Module module, String name, FunctionValue fun)
|
||||
{
|
||||
getModuleData(module).globalFunctions.put(name, fun);
|
||||
|
||||
@@ -12,8 +12,6 @@ import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import carpet.CarpetServer;
|
||||
import carpet.script.Context;
|
||||
import carpet.script.value.BooleanValue;
|
||||
@@ -195,12 +193,8 @@ public interface Param
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* <p>Strict converters</p>
|
||||
*
|
||||
* <p>Stored as {@code <Pair<Type, shallow?>, Converter>}</p>
|
||||
*/
|
||||
private static final Map<Pair<Class<?>, Boolean>, ValueConverter<?>> strictParamsByClassAndShallowness = new HashMap<>();
|
||||
static record StrictConverterInfo(Class<?> type, boolean shallow) {}
|
||||
private static final Map<StrictConverterInfo, ValueConverter<?>> strictParamsByClassAndShallowness = new HashMap<>();
|
||||
static
|
||||
{ // TODO Specify strictness in name?
|
||||
registerStrictConverter(String.class, false, new SimpleTypeConverter<>(StringValue.class, StringValue::getString, "string"));
|
||||
@@ -224,7 +218,7 @@ public interface Param
|
||||
{
|
||||
boolean shallow = type.getAnnotation(Strict.class).shallow();
|
||||
Class<?> clazz = (Class<?>) type.getType();
|
||||
Pair<Class<?>, Boolean> key = Pair.of(clazz, shallow);
|
||||
var key = new StrictConverterInfo(clazz, shallow);
|
||||
ValueConverter<?> converter = strictParamsByClassAndShallowness.get(key);
|
||||
if (converter != null)
|
||||
return converter;
|
||||
@@ -245,7 +239,7 @@ public interface Param
|
||||
*/
|
||||
public static <T> void registerStrictConverter(Class<T> type, boolean shallow, ValueConverter<T> converter)
|
||||
{
|
||||
Pair<Class<?>, Boolean> key = Pair.of(type, shallow);
|
||||
var key = new StrictConverterInfo(type, shallow);
|
||||
if (strictParamsByClassAndShallowness.containsKey(key))
|
||||
throw new IllegalArgumentException(type + " already has a registered " + (shallow ? "" : "non-") + "shallow StrictConverter");
|
||||
strictParamsByClassAndShallowness.put(key, converter);
|
||||
|
||||
@@ -3,7 +3,6 @@ package carpet.script.api;
|
||||
import carpet.CarpetServer;
|
||||
import carpet.fakes.MinecraftServerInterface;
|
||||
import carpet.fakes.ServerWorldInterface;
|
||||
import carpet.fakes.StatTypeInterface;
|
||||
import carpet.fakes.ThreadedAnvilChunkStorageInterface;
|
||||
import carpet.helpers.FeatureGenerator;
|
||||
import carpet.logging.HUDController;
|
||||
@@ -38,8 +37,6 @@ import carpet.script.value.StringValue;
|
||||
import carpet.script.value.Value;
|
||||
import carpet.script.value.ValueConversions;
|
||||
import carpet.utils.Messenger;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Lists;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.block.BlockState;
|
||||
@@ -104,7 +101,6 @@ import net.minecraft.world.gen.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.UnmodifiableLevelProperties;
|
||||
import net.minecraft.world.level.storage.LevelStorage;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
@@ -334,7 +330,7 @@ public class Auxiliary {
|
||||
ServerWorld world = cc.s.getWorld();
|
||||
MinecraftServer server = world.getServer();
|
||||
Set<ServerPlayerEntity> playerTargets = new HashSet<>();
|
||||
List<Pair<ShapeDispatcher.ExpiringShape, Map<String,Value>>> shapes = new ArrayList<>();
|
||||
List<ShapeDispatcher.ShapeWithConfig> shapes = new ArrayList<>();
|
||||
if (lv.size() == 1) // bulk
|
||||
{
|
||||
Value specLoad = lv.get(0);
|
||||
@@ -1062,10 +1058,10 @@ public class Auxiliary {
|
||||
{
|
||||
try {
|
||||
//Files.createDirectory(packFloder);
|
||||
try (FileSystem zipfs = FileSystems.newFileSystem(URI.create("jar:" + packFloder.toUri().toString()), ImmutableMap.of("create", "true"))) {
|
||||
try (FileSystem zipfs = FileSystems.newFileSystem(URI.create("jar:" + packFloder.toUri().toString()), Map.of("create", "true"))) {
|
||||
Path zipRoot = zipfs.getPath("/");
|
||||
zipValueToJson(zipRoot.resolve("pack.mcmeta"), MapValue.wrap(
|
||||
ImmutableMap.of(StringValue.of("pack"), MapValue.wrap(ImmutableMap.of(
|
||||
Map.of(StringValue.of("pack"), MapValue.wrap(Map.of(
|
||||
StringValue.of("pack_format"), new NumericValue(SharedConstants.getGameVersion().getPackVersion()),
|
||||
StringValue.of("description"), StringValue.of(name),
|
||||
StringValue.of("source"), StringValue.of("scarpet")
|
||||
@@ -1144,7 +1140,7 @@ public class Auxiliary {
|
||||
DimensionType dimensionType3 = entry.getValue().getDimensionType();
|
||||
ChunkGenerator chunkGenerator3 = entry.getValue().getChunkGenerator();
|
||||
UnmodifiableLevelProperties unmodifiableLevelProperties = new UnmodifiableLevelProperties(saveProperties, ((ServerWorldInterface) server.getOverworld()).getWorldPropertiesCM());
|
||||
ServerWorld serverWorld2 = new ServerWorld(server, Util.getMainWorkerExecutor(), session, unmodifiableLevelProperties, registryKey2, dimensionType3, WorldTools.NOOP_LISTENER, chunkGenerator3, bl, m, ImmutableList.of(), false);
|
||||
ServerWorld serverWorld2 = new ServerWorld(server, Util.getMainWorkerExecutor(), session, unmodifiableLevelProperties, registryKey2, dimensionType3, WorldTools.NOOP_LISTENER, chunkGenerator3, bl, m, List.of(), false);
|
||||
server.getOverworld().getWorldBorder().addListener(new WorldBorderListener.WorldBorderSyncer(serverWorld2.getWorldBorder()));
|
||||
existing_worlds.put(registryKey2, serverWorld2);
|
||||
}
|
||||
@@ -1209,7 +1205,7 @@ public class Auxiliary {
|
||||
private static <T> Stat<T> getStat(StatType<T> type, Identifier id)
|
||||
{
|
||||
T key = type.getRegistry().get(id);
|
||||
if (key == null || !((StatTypeInterface)type).hasStatCreated(key))
|
||||
if (key == null || !type.hasStat(key))
|
||||
return null;
|
||||
return type.getOrCreateStat(key);
|
||||
}
|
||||
|
||||
@@ -262,7 +262,6 @@ public class Entities {
|
||||
|
||||
expression.addContextFunction("entity_load_handler", -1, (c, t, lv) ->
|
||||
{
|
||||
if (c.host.isPerUser()) throw new InternalExpressionException("'entity_load_handler' can only be called in apps with global scope");
|
||||
if (lv.size() < 2) throw new InternalExpressionException("'entity_load_handler' required the entity type, and a function to call");
|
||||
Value entityValue = lv.get(0);
|
||||
List<String> descriptors = (entityValue instanceof ListValue)
|
||||
|
||||
@@ -181,7 +181,7 @@ public class Inventories {
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||
if (inventoryLocator == null) return Value.NULL;
|
||||
return new NumericValue(inventoryLocator.inventory.size());
|
||||
return new NumericValue(inventoryLocator.inventory().size());
|
||||
});
|
||||
|
||||
expression.addContextFunction("inventory_has_items", -1, (c, t, lv) ->
|
||||
@@ -189,7 +189,7 @@ public class Inventories {
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||
if (inventoryLocator == null) return Value.NULL;
|
||||
return BooleanValue.of(!inventoryLocator.inventory.isEmpty());
|
||||
return BooleanValue.of(!inventoryLocator.inventory().isEmpty());
|
||||
});
|
||||
|
||||
//inventory_get(<b, e>, <n>) -> item_triple
|
||||
@@ -198,17 +198,17 @@ public class Inventories {
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||
if (inventoryLocator == null) return Value.NULL;
|
||||
if (lv.size() == inventoryLocator.offset)
|
||||
if (lv.size() == inventoryLocator.offset())
|
||||
{
|
||||
List<Value> fullInventory = new ArrayList<>();
|
||||
for (int i = 0, maxi = inventoryLocator.inventory.size(); i < maxi; i++)
|
||||
fullInventory.add(ValueConversions.of(inventoryLocator.inventory.getStack(i)));
|
||||
for (int i = 0, maxi = inventoryLocator.inventory().size(); i < maxi; i++)
|
||||
fullInventory.add(ValueConversions.of(inventoryLocator.inventory().getStack(i)));
|
||||
return ListValue.wrap(fullInventory);
|
||||
}
|
||||
int slot = (int)NumericValue.asNumber(lv.get(inventoryLocator.offset)).getLong();
|
||||
slot = NBTSerializableValue.validateSlot(slot, inventoryLocator.inventory);
|
||||
if (slot == inventoryLocator.inventory.size()) return Value.NULL;
|
||||
return ValueConversions.of(inventoryLocator.inventory.getStack(slot));
|
||||
int slot = (int)NumericValue.asNumber(lv.get(inventoryLocator.offset())).getLong();
|
||||
slot = NBTSerializableValue.validateSlot(slot, inventoryLocator.inventory());
|
||||
if (slot == inventoryLocator.inventory().size()) return Value.NULL;
|
||||
return ValueConversions.of(inventoryLocator.inventory().getStack(slot));
|
||||
});
|
||||
|
||||
//inventory_set(<b,e>, <n>, <count>, <item>, <nbt>)
|
||||
@@ -217,33 +217,33 @@ public class Inventories {
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||
if (inventoryLocator == null) return Value.NULL;
|
||||
if (lv.size() < inventoryLocator.offset+2)
|
||||
if (lv.size() < inventoryLocator.offset()+2)
|
||||
throw new InternalExpressionException("'inventory_set' requires at least slot number and new stack size, and optional new item");
|
||||
int slot = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset+0)).getLong();
|
||||
slot = NBTSerializableValue.validateSlot(slot, inventoryLocator.inventory);
|
||||
if (slot == inventoryLocator.inventory.size()) return Value.NULL;
|
||||
int count = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset+1)).getLong();
|
||||
int slot = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset()+0)).getLong();
|
||||
slot = NBTSerializableValue.validateSlot(slot, inventoryLocator.inventory());
|
||||
if (slot == inventoryLocator.inventory().size()) return Value.NULL;
|
||||
int count = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset()+1)).getLong();
|
||||
if (count == 0)
|
||||
{
|
||||
// clear slot
|
||||
ItemStack removedStack = inventoryLocator.inventory.removeStack(slot);
|
||||
ItemStack removedStack = inventoryLocator.inventory().removeStack(slot);
|
||||
syncPlayerInventory(inventoryLocator, slot);
|
||||
//Value res = ListValue.fromItemStack(removedStack); // that tuple will be read only but cheaper if noone cares
|
||||
return ValueConversions.of(removedStack);
|
||||
}
|
||||
if (lv.size() < inventoryLocator.offset+3)
|
||||
if (lv.size() < inventoryLocator.offset()+3)
|
||||
{
|
||||
ItemStack previousStack = inventoryLocator.inventory.getStack(slot);
|
||||
ItemStack previousStack = inventoryLocator.inventory().getStack(slot);
|
||||
ItemStack newStack = previousStack.copy();
|
||||
newStack.setCount(count);
|
||||
inventoryLocator.inventory.setStack(slot, newStack);
|
||||
inventoryLocator.inventory().setStack(slot, newStack);
|
||||
syncPlayerInventory(inventoryLocator, slot);
|
||||
return ValueConversions.of(previousStack);
|
||||
}
|
||||
NbtCompound nbt = null; // skipping one argument
|
||||
if (lv.size() > inventoryLocator.offset+3)
|
||||
if (lv.size() > inventoryLocator.offset()+3)
|
||||
{
|
||||
Value nbtValue = lv.get(inventoryLocator.offset+3);
|
||||
Value nbtValue = lv.get(inventoryLocator.offset()+3);
|
||||
if (nbtValue instanceof NBTSerializableValue)
|
||||
nbt = ((NBTSerializableValue)nbtValue).getCompoundTag();
|
||||
else if (nbtValue instanceof NullValue)
|
||||
@@ -251,11 +251,11 @@ public class Inventories {
|
||||
else
|
||||
nbt = new NBTSerializableValue(nbtValue.getString()).getCompoundTag();
|
||||
}
|
||||
ItemStackArgument newitem = NBTSerializableValue.parseItem(lv.get(inventoryLocator.offset+2).getString(), nbt);
|
||||
ItemStack previousStack = inventoryLocator.inventory.getStack(slot);
|
||||
ItemStackArgument newitem = NBTSerializableValue.parseItem(lv.get(inventoryLocator.offset()+2).getString(), nbt);
|
||||
ItemStack previousStack = inventoryLocator.inventory().getStack(slot);
|
||||
try
|
||||
{
|
||||
inventoryLocator.inventory.setStack(slot, newitem.createStack(count, false));
|
||||
inventoryLocator.inventory().setStack(slot, newitem.createStack(count, false));
|
||||
syncPlayerInventory(inventoryLocator, slot);
|
||||
}
|
||||
catch (CommandSyntaxException e)
|
||||
@@ -272,21 +272,21 @@ public class Inventories {
|
||||
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||
if (inventoryLocator == null) return Value.NULL;
|
||||
ItemStackArgument itemArg = null;
|
||||
if (lv.size() > inventoryLocator.offset)
|
||||
if (lv.size() > inventoryLocator.offset())
|
||||
{
|
||||
Value secondArg = lv.get(inventoryLocator.offset+0);
|
||||
Value secondArg = lv.get(inventoryLocator.offset()+0);
|
||||
if (!(secondArg instanceof NullValue))
|
||||
itemArg = NBTSerializableValue.parseItem(secondArg.getString());
|
||||
}
|
||||
int startIndex = 0;
|
||||
if (lv.size() > inventoryLocator.offset+1)
|
||||
if (lv.size() > inventoryLocator.offset()+1)
|
||||
{
|
||||
startIndex = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset+1)).getLong();
|
||||
startIndex = (int) NumericValue.asNumber(lv.get(inventoryLocator.offset()+1)).getLong();
|
||||
}
|
||||
startIndex = NBTSerializableValue.validateSlot(startIndex, inventoryLocator.inventory);
|
||||
for (int i = startIndex, maxi = inventoryLocator.inventory.size(); i < maxi; i++)
|
||||
startIndex = NBTSerializableValue.validateSlot(startIndex, inventoryLocator.inventory());
|
||||
for (int i = startIndex, maxi = inventoryLocator.inventory().size(); i < maxi; i++)
|
||||
{
|
||||
ItemStack stack = inventoryLocator.inventory.getStack(i);
|
||||
ItemStack stack = inventoryLocator.inventory().getStack(i);
|
||||
if ( (itemArg == null && stack.isEmpty()) || (itemArg != null && itemArg.getItem().equals(stack.getItem())) )
|
||||
return new NumericValue(i);
|
||||
}
|
||||
@@ -299,18 +299,18 @@ public class Inventories {
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||
if (inventoryLocator == null) return Value.NULL;
|
||||
if (lv.size() <= inventoryLocator.offset)
|
||||
if (lv.size() <= inventoryLocator.offset())
|
||||
throw new InternalExpressionException("'inventory_remove' requires at least an item to be removed");
|
||||
ItemStackArgument searchItem = NBTSerializableValue.parseItem(lv.get(inventoryLocator.offset).getString());
|
||||
ItemStackArgument searchItem = NBTSerializableValue.parseItem(lv.get(inventoryLocator.offset()).getString());
|
||||
int amount = 1;
|
||||
if (lv.size() > inventoryLocator.offset+1)
|
||||
amount = (int)NumericValue.asNumber(lv.get(inventoryLocator.offset+1)).getLong();
|
||||
if (lv.size() > inventoryLocator.offset()+1)
|
||||
amount = (int)NumericValue.asNumber(lv.get(inventoryLocator.offset()+1)).getLong();
|
||||
// not enough
|
||||
if (((amount == 1) && (!inventoryLocator.inventory.containsAny(Sets.newHashSet(searchItem.getItem()))))
|
||||
|| (inventoryLocator.inventory.count(searchItem.getItem()) < amount)) return Value.FALSE;
|
||||
for (int i = 0, maxi = inventoryLocator.inventory.size(); i < maxi; i++)
|
||||
if (((amount == 1) && (!inventoryLocator.inventory().containsAny(Sets.newHashSet(searchItem.getItem()))))
|
||||
|| (inventoryLocator.inventory().count(searchItem.getItem()) < amount)) return Value.FALSE;
|
||||
for (int i = 0, maxi = inventoryLocator.inventory().size(); i < maxi; i++)
|
||||
{
|
||||
ItemStack stack = inventoryLocator.inventory.getStack(i);
|
||||
ItemStack stack = inventoryLocator.inventory().getStack(i);
|
||||
if (stack.isEmpty())
|
||||
continue;
|
||||
if (!stack.getItem().equals(searchItem.getItem()))
|
||||
@@ -319,13 +319,13 @@ public class Inventories {
|
||||
if (left > 0)
|
||||
{
|
||||
stack.setCount(left);
|
||||
inventoryLocator.inventory.setStack(i, stack);
|
||||
inventoryLocator.inventory().setStack(i, stack);
|
||||
syncPlayerInventory(inventoryLocator, i);
|
||||
return Value.TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
inventoryLocator.inventory.removeStack(i);
|
||||
inventoryLocator.inventory().removeStack(i);
|
||||
syncPlayerInventory(inventoryLocator, i);
|
||||
amount -= stack.getCount();
|
||||
}
|
||||
@@ -341,30 +341,29 @@ public class Inventories {
|
||||
CarpetContext cc = (CarpetContext) c;
|
||||
NBTSerializableValue.InventoryLocator inventoryLocator = NBTSerializableValue.locateInventory(cc, lv, 0);
|
||||
if (inventoryLocator == null) return Value.NULL;
|
||||
if (lv.size() == inventoryLocator.offset)
|
||||
if (lv.size() == inventoryLocator.offset())
|
||||
throw new InternalExpressionException("Slot number is required for inventory_drop");
|
||||
int slot = (int)NumericValue.asNumber(lv.get(inventoryLocator.offset)).getLong();
|
||||
slot = NBTSerializableValue.validateSlot(slot, inventoryLocator.inventory);
|
||||
if (slot == inventoryLocator.inventory.size()) return Value.NULL;
|
||||
int slot = (int)NumericValue.asNumber(lv.get(inventoryLocator.offset())).getLong();
|
||||
slot = NBTSerializableValue.validateSlot(slot, inventoryLocator.inventory());
|
||||
if (slot == inventoryLocator.inventory().size()) return Value.NULL;
|
||||
int amount = 0;
|
||||
if (lv.size() > inventoryLocator.offset+1)
|
||||
amount = (int)NumericValue.asNumber(lv.get(inventoryLocator.offset+1)).getLong();
|
||||
if (lv.size() > inventoryLocator.offset()+1)
|
||||
amount = (int)NumericValue.asNumber(lv.get(inventoryLocator.offset()+1)).getLong();
|
||||
if (amount < 0)
|
||||
throw new InternalExpressionException("Cannot throw negative number of items");
|
||||
ItemStack stack = inventoryLocator.inventory.getStack(slot);
|
||||
ItemStack stack = inventoryLocator.inventory().getStack(slot);
|
||||
if (stack == null || stack.isEmpty()) return Value.ZERO;
|
||||
if (amount == 0) amount = stack.getCount();
|
||||
ItemStack droppedStack = inventoryLocator.inventory.removeStack(slot, amount);
|
||||
ItemStack droppedStack = inventoryLocator.inventory().removeStack(slot, amount);
|
||||
if (droppedStack.isEmpty()) return Value.ZERO;
|
||||
Object owner = inventoryLocator.owner;
|
||||
Object owner = inventoryLocator.owner();
|
||||
ItemEntity item;
|
||||
if (owner instanceof PlayerEntity)
|
||||
{
|
||||
item = ((PlayerEntity) owner).dropItem(droppedStack, false, true);
|
||||
}
|
||||
else if (owner instanceof LivingEntity)
|
||||
else if (owner instanceof LivingEntity villager)
|
||||
{
|
||||
LivingEntity villager = (LivingEntity)owner;
|
||||
// stolen from LookTargetUtil.give((VillagerEntity)owner, droppedStack, (LivingEntity) owner);
|
||||
double double_1 = villager.getY() - 0.30000001192092896D + (double)villager.getStandingEyeHeight();
|
||||
item = new ItemEntity(villager.world, villager.getX(), double_1, villager.getZ(), droppedStack);
|
||||
@@ -375,7 +374,7 @@ public class Inventories {
|
||||
}
|
||||
else
|
||||
{
|
||||
Vec3d point = Vec3d.ofCenter(inventoryLocator.position); //pos+0.5v
|
||||
Vec3d point = Vec3d.ofCenter(inventoryLocator.position()); //pos+0.5v
|
||||
item = new ItemEntity(cc.s.getWorld(), point.x, point.y, point.z, droppedStack);
|
||||
item.setToDefaultPickupDelay();
|
||||
cc.s.getWorld().spawnEntity(item);
|
||||
@@ -386,13 +385,12 @@ public class Inventories {
|
||||
|
||||
private static void syncPlayerInventory(NBTSerializableValue.InventoryLocator inventory, int int_1)
|
||||
{
|
||||
if (inventory.owner instanceof ServerPlayerEntity && !inventory.isEnder)
|
||||
if (inventory.owner() instanceof ServerPlayerEntity player && !inventory.isEnder())
|
||||
{
|
||||
ServerPlayerEntity player = (ServerPlayerEntity) inventory.owner;
|
||||
player.networkHandler.sendPacket(new ScreenHandlerSlotUpdateS2CPacket(
|
||||
-2, 0, // resolve mystery argument
|
||||
int_1,
|
||||
inventory.inventory.getStack(int_1)
|
||||
inventory.inventory().getStack(int_1)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package carpet.script.api;
|
||||
import carpet.fakes.SpawnHelperInnerInterface;
|
||||
import carpet.script.CarpetContext;
|
||||
import carpet.script.Expression;
|
||||
import carpet.script.LazyValue;
|
||||
import carpet.script.exception.InternalExpressionException;
|
||||
import carpet.script.utils.SystemInfo;
|
||||
import carpet.script.value.ListValue;
|
||||
|
||||
@@ -9,7 +9,6 @@ import carpet.script.exception.Throwables;
|
||||
import carpet.script.value.MapValue;
|
||||
import carpet.script.value.StringValue;
|
||||
import carpet.script.value.Value;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonParser;
|
||||
@@ -523,7 +522,7 @@ public class FileArgument
|
||||
Throwable exc = e;
|
||||
if(e.getCause() != null)
|
||||
exc = e.getCause();
|
||||
throw new ThrowStatement(MapValue.wrap(ImmutableMap.of(
|
||||
throw new ThrowStatement(MapValue.wrap(Map.of(
|
||||
StringValue.of("error"), StringValue.of(exc.getMessage()),
|
||||
StringValue.of("path"), StringValue.of(filePath.toString())
|
||||
)), Throwables.JSON_ERROR);
|
||||
|
||||
@@ -4,7 +4,6 @@ import carpet.CarpetServer;
|
||||
import carpet.fakes.BlockStateArgumentInterface;
|
||||
import carpet.script.CarpetScriptHost;
|
||||
import carpet.script.argument.FunctionArgument;
|
||||
import carpet.script.exception.InternalExpressionException;
|
||||
import carpet.script.value.BlockValue;
|
||||
import carpet.script.value.BooleanValue;
|
||||
import carpet.script.value.EntityValue;
|
||||
@@ -17,6 +16,9 @@ import carpet.script.value.StringValue;
|
||||
import carpet.script.value.Value;
|
||||
import carpet.script.value.ValueConversions;
|
||||
import carpet.utils.CarpetProfiler;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.brigadier.arguments.ArgumentType;
|
||||
@@ -84,7 +86,6 @@ import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.Vec2f;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -102,7 +103,6 @@ import java.util.stream.Collectors;
|
||||
|
||||
import static net.minecraft.server.command.CommandManager.argument;
|
||||
|
||||
|
||||
public abstract class CommandArgument
|
||||
{
|
||||
public static CommandSyntaxException error(String text)
|
||||
@@ -878,49 +878,50 @@ public abstract class CommandArgument
|
||||
}
|
||||
private static class SlotArgument extends CommandArgument
|
||||
{
|
||||
private static record ContainerIds(IntSet numericalIds, Set<String> commandIds) {}
|
||||
private String restrict;
|
||||
private static final Map<String, Pair<Set<Integer>, Set<String>>> RESTRICTED_CONTAINERS = new HashMap<String, Pair<Set<Integer>, Set<String>>>(){{
|
||||
private static final Map<String, ContainerIds> RESTRICTED_CONTAINERS = new HashMap<String, ContainerIds>(){{
|
||||
int i;
|
||||
for (String source : Arrays.asList("player", "enderchest", "equipment", "armor", "weapon", "container", "villager", "horse"))
|
||||
put(source, Pair.of(new HashSet<>(), new HashSet<>()));
|
||||
for (i = 0; i < 41; i++) get("player").getLeft().add(i);
|
||||
for(i = 0; i < 41; i++) get("player").getRight().add("container." + i);
|
||||
for(i = 0; i < 9; i++) get("player").getRight().add("hotbar." + i);
|
||||
for(i = 0; i < 27; i++) get("player").getRight().add("inventory." + i);
|
||||
put(source, new ContainerIds(new IntOpenHashSet(), new HashSet<>()));
|
||||
for (i = 0; i < 41; i++) get("player").numericalIds().add(i);
|
||||
for(i = 0; i < 41; i++) get("player").commandIds().add("container." + i);
|
||||
for(i = 0; i < 9; i++) get("player").commandIds().add("hotbar." + i);
|
||||
for(i = 0; i < 27; i++) get("player").commandIds().add("inventory." + i);
|
||||
for (String place : Arrays.asList("weapon", "weapon.mainhand", "weapon.offhand"))
|
||||
{
|
||||
get("player").getRight().add(place);
|
||||
get("equipment").getRight().add(place);
|
||||
get("weapon").getRight().add(place);
|
||||
get("player").commandIds().add(place);
|
||||
get("equipment").commandIds().add(place);
|
||||
get("weapon").commandIds().add(place);
|
||||
}
|
||||
for (String place : Arrays.asList("armor.feet","armor.legs", "armor.chest","armor.head"))
|
||||
{
|
||||
get("player").getRight().add(place);
|
||||
get("equipment").getRight().add(place);
|
||||
get("armor").getRight().add(place);
|
||||
get("player").commandIds().add(place);
|
||||
get("equipment").commandIds().add(place);
|
||||
get("armor").commandIds().add(place);
|
||||
}
|
||||
|
||||
for (i = 0; i < 27; i++) get("enderchest").getLeft().add(200+i);
|
||||
for(i = 0; i < 27; i++) get("enderchest").getRight().add("enderchest." + i);
|
||||
for (i = 0; i < 27; i++) get("enderchest").numericalIds().add(200+i);
|
||||
for(i = 0; i < 27; i++) get("enderchest").commandIds().add("enderchest." + i);
|
||||
|
||||
for (i = 0; i < 6; i++) get("equipment").getLeft().add(98+i);
|
||||
for (i = 0; i < 6; i++) get("equipment").numericalIds().add(98+i);
|
||||
|
||||
for (i = 0; i < 4; i++) get("armor").getLeft().add(100+i);
|
||||
for (i = 0; i < 4; i++) get("armor").numericalIds().add(100+i);
|
||||
|
||||
for (i = 0; i < 2; i++) get("weapon").getLeft().add(98+i);
|
||||
for (i = 0; i < 2; i++) get("weapon").numericalIds().add(98+i);
|
||||
|
||||
for (i = 0; i < 54; i++) get("container").getLeft().add(i);
|
||||
for(i = 0; i < 41; i++) get("container").getRight().add("container." + i);
|
||||
for (i = 0; i < 54; i++) get("container").numericalIds().add(i);
|
||||
for(i = 0; i < 41; i++) get("container").commandIds().add("container." + i);
|
||||
|
||||
for (i = 0; i < 8; i++) get("villager").getLeft().add(i);
|
||||
for(i = 0; i < 8; i++) get("villager").getRight().add("villager." + i);
|
||||
for (i = 0; i < 8; i++) get("villager").numericalIds().add(i);
|
||||
for(i = 0; i < 8; i++) get("villager").commandIds().add("villager." + i);
|
||||
|
||||
for (i = 0; i < 15; i++) get("horse").getLeft().add(500+i);
|
||||
for(i = 0; i < 15; i++) get("horse").getRight().add("horse." + i);
|
||||
get("horse").getLeft().add(400);
|
||||
get("horse").getRight().add("horse.saddle");
|
||||
get("horse").getLeft().add(401);
|
||||
get("horse").getRight().add("horse.armor");
|
||||
for (i = 0; i < 15; i++) get("horse").numericalIds().add(500+i);
|
||||
for(i = 0; i < 15; i++) get("horse").commandIds().add("horse." + i);
|
||||
get("horse").numericalIds().add(400);
|
||||
get("horse").commandIds().add("horse.saddle");
|
||||
get("horse").numericalIds().add(401);
|
||||
get("horse").commandIds().add("horse.armor");
|
||||
}};
|
||||
|
||||
protected SlotArgument()
|
||||
@@ -938,7 +939,7 @@ public abstract class CommandArgument
|
||||
protected Value getValueFromContext(CommandContext<ServerCommandSource> context, String param) throws CommandSyntaxException
|
||||
{
|
||||
int slot = ItemSlotArgumentType.getItemSlot(context, param);
|
||||
if (restrict != null && !RESTRICTED_CONTAINERS.get(restrict).getLeft().contains(slot))
|
||||
if (restrict != null && !RESTRICTED_CONTAINERS.get(restrict).numericalIds().contains(slot))
|
||||
{
|
||||
throw new SimpleCommandExceptionType(new LiteralText("Incorrect slot restricted to "+restrict+" for custom type "+suffix)).create();
|
||||
}
|
||||
@@ -961,7 +962,7 @@ public abstract class CommandArgument
|
||||
@Override
|
||||
protected Collection<String> getOptions(CommandContext<ServerCommandSource> context, CarpetScriptHost host) throws CommandSyntaxException
|
||||
{
|
||||
return restrict==null?super.getOptions(context, host):RESTRICTED_CONTAINERS.get(restrict).getRight();
|
||||
return restrict==null?super.getOptions(context, host):RESTRICTED_CONTAINERS.get(restrict).commandIds();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -13,8 +13,8 @@ import carpet.script.value.MapValue;
|
||||
import carpet.script.value.NumericValue;
|
||||
import carpet.script.value.StringValue;
|
||||
import carpet.script.value.Value;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ControlFlow {
|
||||
@@ -106,7 +106,7 @@ public class ControlFlow {
|
||||
LazyValue __ = c.getVariable("_");
|
||||
c.setVariable("_", (__c, __t) -> ret.data.reboundedTo("_"));
|
||||
LazyValue _trace = c.getVariable("_trace");
|
||||
c.setVariable("_trace", (__c, __t) -> MapValue.wrap(ImmutableMap.of(
|
||||
c.setVariable("_trace", (__c, __t) -> MapValue.wrap(Map.of(
|
||||
StringValue.of("stack"), ListValue.wrap(ret.stack.stream().map(f -> ListValue.of(
|
||||
StringValue.of(f.getModule().getName()),
|
||||
StringValue.of(f.getString()),
|
||||
|
||||
@@ -123,9 +123,8 @@ public class Functions {
|
||||
return (cc, tt) -> result;
|
||||
}
|
||||
Value v1 = lv1.evalValue(c, Context.SIGNATURE);
|
||||
if (!(v1 instanceof FunctionSignatureValue))
|
||||
if (!(v1 instanceof FunctionSignatureValue sign))
|
||||
throw new InternalExpressionException("'->' operator requires a function signature on the LHS");
|
||||
FunctionSignatureValue sign = (FunctionSignatureValue) v1;
|
||||
Value result = expression.createUserDefinedFunction(c, sign.getName(), e, t, sign.getArgs(), sign.getVarArgs(), sign.getGlobals(), lv2);
|
||||
return (cc, tt) -> result;
|
||||
});
|
||||
|
||||
@@ -51,9 +51,8 @@ public class Sys {
|
||||
|
||||
expression.addUnaryFunction("number", v ->
|
||||
{
|
||||
if (v instanceof NumericValue)
|
||||
if (v instanceof NumericValue num)
|
||||
{
|
||||
NumericValue num = (NumericValue)v;
|
||||
if (num.isInteger()) return new NumericValue(num.getLong());
|
||||
return new NumericValue(num.getDouble());
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.util.WorldSavePath;
|
||||
import org.apache.commons.lang3.tuple.Triple;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
@@ -55,6 +54,7 @@ public class AppStoreManager
|
||||
*/
|
||||
private static String scarpetRepoLink = "https://api.github.com/repos/gnembon/scarpet/contents/programs/";
|
||||
|
||||
private static record AppInfo(String name, String url, StoreNode source) {}
|
||||
|
||||
public static class ScarpetAppStoreValidator extends Validator<String>
|
||||
{
|
||||
@@ -253,23 +253,23 @@ public class AppStoreManager
|
||||
|
||||
public static int downloadScript(ServerCommandSource source, String path)
|
||||
{
|
||||
Triple<String, String, StoreNode> nodeInfo = getFileNode(path);
|
||||
AppInfo nodeInfo = getFileNode(path);
|
||||
return downloadScript(source, path, nodeInfo, false);
|
||||
}
|
||||
|
||||
private static int downloadScript(ServerCommandSource source, String path, Triple<String, String, StoreNode> nodeInfo, boolean useTrash)
|
||||
private static int downloadScript(ServerCommandSource source, String path, AppInfo nodeInfo, boolean useTrash)
|
||||
{
|
||||
String code;
|
||||
try
|
||||
{
|
||||
code = getStringFromStream(nodeInfo.getMiddle());
|
||||
code = getStringFromStream(nodeInfo.url());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new CommandException(Messenger.c("rb Failed to obtain app file content: "+e.getMessage()));
|
||||
}
|
||||
if (!saveScriptToFile(source, path, nodeInfo.getLeft(), code, false, useTrash)) return 0;
|
||||
boolean success = CarpetServer.scriptServer.addScriptHost(source, nodeInfo.getLeft().replaceFirst("\\.sc$", ""), null, true, false, false, nodeInfo.getRight());
|
||||
if (!saveScriptToFile(source, path, nodeInfo.name(), code, false, useTrash)) return 0;
|
||||
boolean success = CarpetServer.scriptServer.addScriptHost(source, nodeInfo.name().replaceFirst("\\.sc$", ""), null, true, false, false, nodeInfo.source());
|
||||
return success?1:0;
|
||||
}
|
||||
|
||||
@@ -278,12 +278,12 @@ public class AppStoreManager
|
||||
* @param appPath The user inputted path to the scarpet script
|
||||
* @return Pair of app file name and content
|
||||
*/
|
||||
public static Triple<String, String, StoreNode> getFileNode(String appPath)
|
||||
public static AppInfo getFileNode(String appPath)
|
||||
{
|
||||
return getFileNodeFrom(APP_STORE_ROOT, appPath);
|
||||
}
|
||||
|
||||
public static Triple<String, String, StoreNode> getFileNodeFrom(StoreNode start, String appPath)
|
||||
public static AppInfo getFileNodeFrom(StoreNode start, String appPath)
|
||||
{
|
||||
String[] path = appPath.split("/");
|
||||
StoreNode appKiosk = start;
|
||||
@@ -293,7 +293,7 @@ public class AppStoreManager
|
||||
appKiosk = appKiosk.drillDown(pathElement);
|
||||
String appName = path[path.length-1];
|
||||
appKiosk.getValue(appName);
|
||||
return Triple.of(appName, appKiosk.getValue(appName), appKiosk);
|
||||
return new AppInfo(appName, appKiosk.getValue(appName), appKiosk);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
@@ -390,8 +390,8 @@ public class AppStoreManager
|
||||
if (original.matches("^https?://.*$")) // We've got a full url here: Just use it
|
||||
return original;
|
||||
if (original.charAt(0) == '/') // We've got an absolute path: Use app store root
|
||||
return getFileNode(original.substring(1)).getMiddle();
|
||||
return getFileNodeFrom(storeSource, original).getMiddle(); // Relative path: Use download location
|
||||
return getFileNode(original.substring(1)).url();
|
||||
return getFileNodeFrom(storeSource, original).url(); // Relative path: Use download location
|
||||
}
|
||||
|
||||
public static void addResource(CarpetScriptHost carpetScriptHost, StoreNode storeSource, Value resource)
|
||||
@@ -461,7 +461,7 @@ public class AppStoreManager
|
||||
throw new InternalExpressionException("App resource tried to leave script reserved space");
|
||||
try
|
||||
{
|
||||
downloadScript(carpetScriptHost.responsibleSource, target, Triple.of(target, contentUrl, getNewStoreNode(storeSource, source, contentUrl)), true);
|
||||
downloadScript(carpetScriptHost.responsibleSource, target, new AppInfo(target, contentUrl, getNewStoreNode(storeSource, source, contentUrl)), true);
|
||||
}
|
||||
catch (CommandException e)
|
||||
{
|
||||
|
||||
@@ -2,7 +2,6 @@ package carpet.script.utils;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import carpet.network.ServerNetworkHandler;
|
||||
import carpet.script.CarpetContext;
|
||||
import carpet.script.exception.InternalExpressionException;
|
||||
import carpet.script.exception.ThrowStatement;
|
||||
import carpet.script.exception.Throwables;
|
||||
@@ -16,8 +15,6 @@ import carpet.script.value.MapValue;
|
||||
import carpet.script.value.NumericValue;
|
||||
import carpet.script.value.StringValue;
|
||||
import carpet.script.value.Value;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
@@ -45,7 +42,6 @@ import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -60,11 +56,14 @@ import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static java.util.Map.entry;
|
||||
|
||||
public class ShapeDispatcher
|
||||
{
|
||||
private static final Map<String, ParticleEffect> particleCache = new HashMap<>();
|
||||
public static record ShapeWithConfig(ExpiringShape shape, Map<String, Value> config) {}
|
||||
|
||||
public static Pair<ExpiringShape,Map<String, Value>> fromFunctionArgs(
|
||||
public static ShapeWithConfig fromFunctionArgs(
|
||||
MinecraftServer server, ServerWorld world,
|
||||
List<Value> lv,
|
||||
Set<ServerPlayerEntity> playerSet
|
||||
@@ -114,10 +113,10 @@ public class ShapeDispatcher
|
||||
}
|
||||
params.remove("player");
|
||||
}
|
||||
return Pair.of(ShapeDispatcher.create(server, shapeType, params), params);
|
||||
return new ShapeWithConfig(ShapeDispatcher.create(server, shapeType, params), params);
|
||||
}
|
||||
|
||||
public static void sendShape(Collection<ServerPlayerEntity> players, List<Pair<ExpiringShape,Map<String, Value>>> shapes)
|
||||
public static void sendShape(Collection<ServerPlayerEntity> players, List<ShapeWithConfig> shapes)
|
||||
{
|
||||
List<ServerPlayerEntity> clientPlayers = new ArrayList<>();
|
||||
List<ServerPlayerEntity> alternativePlayers = new ArrayList<>();
|
||||
@@ -137,9 +136,9 @@ public class ShapeDispatcher
|
||||
|
||||
NbtList tag = new NbtList();
|
||||
int tagcount = 0;
|
||||
for (Pair<ExpiringShape, Map<String, Value>> s : shapes)
|
||||
for (ShapeWithConfig s : shapes)
|
||||
{
|
||||
tag.add(ExpiringShape.toTag(s.getRight())); // 4000 shapes limit boxes
|
||||
tag.add(ExpiringShape.toTag(s.config())); // 4000 shapes limit boxes
|
||||
if (tagcount++>1000)
|
||||
{
|
||||
tagcount = 0;
|
||||
@@ -154,7 +153,7 @@ public class ShapeDispatcher
|
||||
if (!alternativePlayers.isEmpty())
|
||||
{
|
||||
List<Consumer<ServerPlayerEntity>> alternatives = new ArrayList<>();
|
||||
shapes.forEach(s -> alternatives.add(s.getLeft().alternative()));
|
||||
shapes.forEach(s -> alternatives.add(s.shape().alternative()));
|
||||
alternativePlayers.forEach(p -> alternatives.forEach( a -> a.accept(p)));
|
||||
}
|
||||
}
|
||||
@@ -405,8 +404,8 @@ public class ShapeDispatcher
|
||||
}
|
||||
|
||||
// list of params that need to be there
|
||||
private final Set<String> required = ImmutableSet.of("duration", "shape", "dim");
|
||||
private final Map<String, Value> optional = ImmutableMap.of(
|
||||
private final Set<String> required = Set.of("duration", "shape", "dim");
|
||||
private final Map<String, Value> optional = Map.of(
|
||||
"color", new NumericValue(-1),
|
||||
"follow", new NumericValue(-1),
|
||||
"line", new NumericValue(2.0),
|
||||
@@ -425,20 +424,19 @@ public class ShapeDispatcher
|
||||
|
||||
public static class DisplayedText extends ExpiringShape
|
||||
{
|
||||
private final Set<String> required = ImmutableSet.of("pos", "text");
|
||||
private final Map<String, Value> optional = ImmutableMap.<String, Value>builder().
|
||||
put("facing", new StringValue("player")).
|
||||
put("raise", new NumericValue(0)).
|
||||
put("tilt", new NumericValue(0)).
|
||||
put("lean", new NumericValue(0)).
|
||||
put("turn", new NumericValue(0)).
|
||||
put("indent", new NumericValue(0)).
|
||||
put("height", new NumericValue(0)).
|
||||
put("align", new StringValue("center")).
|
||||
put("size", new NumericValue(10)).
|
||||
put("value", Value.NULL).
|
||||
put("doublesided", new NumericValue(0)).
|
||||
build();
|
||||
private final Set<String> required = Set.of("pos", "text");
|
||||
private final Map<String, Value> optional = Map.ofEntries(
|
||||
entry("facing", new StringValue("player")),
|
||||
entry("raise", new NumericValue(0)),
|
||||
entry("tilt", new NumericValue(0)),
|
||||
entry("lean", new NumericValue(0)),
|
||||
entry("turn", new NumericValue(0)),
|
||||
entry("indent", new NumericValue(0)),
|
||||
entry("height", new NumericValue(0)),
|
||||
entry("align", new StringValue("center")),
|
||||
entry("size", new NumericValue(10)),
|
||||
entry("value", Value.NULL),
|
||||
entry("doublesided", new NumericValue(0)));
|
||||
@Override
|
||||
protected Set<String> requiredParams() { return Sets.union(super.requiredParams(), required); }
|
||||
@Override
|
||||
@@ -552,8 +550,8 @@ public class ShapeDispatcher
|
||||
|
||||
public static class Box extends ExpiringShape
|
||||
{
|
||||
private final Set<String> required = ImmutableSet.of("from", "to");
|
||||
private final Map<String, Value> optional = ImmutableMap.of();
|
||||
private final Set<String> required = Set.of("from", "to");
|
||||
private final Map<String, Value> optional = Map.of();
|
||||
@Override
|
||||
protected Set<String> requiredParams() { return Sets.union(super.requiredParams(), required); }
|
||||
@Override
|
||||
@@ -630,8 +628,8 @@ public class ShapeDispatcher
|
||||
|
||||
public static class Line extends ExpiringShape
|
||||
{
|
||||
private final Set<String> required = ImmutableSet.of("from", "to");
|
||||
private final Map<String, Value> optional = ImmutableMap.of();
|
||||
private final Set<String> required = Set.of("from", "to");
|
||||
private final Map<String, Value> optional = Map.of();
|
||||
@Override
|
||||
protected Set<String> requiredParams() { return Sets.union(super.requiredParams(), required); }
|
||||
@Override
|
||||
@@ -683,8 +681,8 @@ public class ShapeDispatcher
|
||||
|
||||
public static class Sphere extends ExpiringShape
|
||||
{
|
||||
private final Set<String> required = ImmutableSet.of("center", "radius");
|
||||
private final Map<String, Value> optional = ImmutableMap.of("level", Value.ZERO);
|
||||
private final Set<String> required = Set.of("center", "radius");
|
||||
private final Map<String, Value> optional = Map.of("level", Value.ZERO);
|
||||
@Override
|
||||
protected Set<String> requiredParams() { return Sets.union(super.requiredParams(), required); }
|
||||
@Override
|
||||
@@ -755,8 +753,8 @@ public class ShapeDispatcher
|
||||
}
|
||||
public static class Cylinder extends ExpiringShape
|
||||
{
|
||||
private final Set<String> required = ImmutableSet.of("center", "radius");
|
||||
private final Map<String, Value> optional = ImmutableMap.of(
|
||||
private final Set<String> required = Set.of("center", "radius");
|
||||
private final Map<String, Value> optional = Map.of(
|
||||
"level", Value.ZERO,
|
||||
"height", Value.ZERO,
|
||||
"axis", new StringValue("y")
|
||||
@@ -913,6 +911,7 @@ public class ShapeDispatcher
|
||||
|
||||
@Override
|
||||
public NbtElement toTag(Value value) { return NbtString.of(value.getString()); }
|
||||
@Override
|
||||
public Value decode(NbtElement tag) { return new StringValue(tag.asString()); }
|
||||
}
|
||||
public static class TextParam extends StringParam
|
||||
@@ -1149,6 +1148,7 @@ public class ShapeDispatcher
|
||||
throw new InternalExpressionException("'"+p.id+"' requires a triple, block or entity to indicate position");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value decode(NbtElement tag)
|
||||
{
|
||||
NbtList ctag = (NbtList)tag;
|
||||
@@ -1187,6 +1187,7 @@ public class ShapeDispatcher
|
||||
return ListValue.wrap(points);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value decode(NbtElement tag)
|
||||
{
|
||||
NbtList ltag = (NbtList)tag;
|
||||
@@ -1228,6 +1229,7 @@ public class ShapeDispatcher
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value decode(NbtElement tag) { return new NumericValue(((NbtInt)tag).intValue()); }
|
||||
@Override
|
||||
public NbtElement toTag(Value value) { return NbtInt.of(NumericValue.asNumber(value, id).getInt()); }
|
||||
@@ -1254,6 +1256,7 @@ public class ShapeDispatcher
|
||||
return new NumericValue(player.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value decode(NbtElement tag) { return new NumericValue(((NbtInt)tag).intValue()); }
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ public class SimplexNoiseSampler extends PerlinNoiseSampler {
|
||||
return g;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double sample2d(double x, double y) {
|
||||
x = x/2;
|
||||
y = y/2;
|
||||
@@ -75,6 +76,7 @@ public class SimplexNoiseSampler extends PerlinNoiseSampler {
|
||||
return 35.0D * (aa + ab + ac)+0.5;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double sample3d(double d, double e, double f) {
|
||||
d = d/2;
|
||||
e = e/2;
|
||||
|
||||
@@ -122,6 +122,7 @@ public class SnoopyCommandSource extends ServerCommandSource
|
||||
return new SnoopyCommandSource(output, position, rotation, world, level, simpleName, name, server, entity, consumer, entityAnchor, error, chatOutput);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerCommandSource mergeConsumers(ResultConsumer<ServerCommandSource> consumer, BinaryOperator<ResultConsumer<ServerCommandSource>> binaryOperator)
|
||||
{
|
||||
ResultConsumer<ServerCommandSource> resultConsumer = binaryOperator.apply(this.resultConsumer, consumer);
|
||||
|
||||
@@ -133,7 +133,7 @@ public class SystemInfo {
|
||||
put("java_system_cpu_load", c -> {
|
||||
OperatingSystemMXBean osBean = ManagementFactory.getPlatformMXBean(
|
||||
OperatingSystemMXBean.class);
|
||||
return new NumericValue(osBean.getSystemCpuLoad());
|
||||
return new NumericValue(osBean.getCpuLoad());
|
||||
});
|
||||
put("java_process_cpu_load", c -> {
|
||||
OperatingSystemMXBean osBean = ManagementFactory.getPlatformMXBean(
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package carpet.script.utils;
|
||||
|
||||
import carpet.fakes.MinecraftServerInterface;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.network.packet.s2c.play.ChunkDataS2CPacket;
|
||||
@@ -93,7 +92,7 @@ public class WorldTools
|
||||
boolean bl = generatorOptions.isDebugWorld();
|
||||
long l = generatorOptions.getSeed();
|
||||
long m = BiomeAccess.hashSeed(l);
|
||||
List<Spawner> list = ImmutableList.of();
|
||||
List<Spawner> list = List.of();
|
||||
SimpleRegistry<DimensionOptions> simpleRegistry = generatorOptions.getDimensions();
|
||||
DimensionOptions dimensionOptions = simpleRegistry.get(DimensionOptions.OVERWORLD);
|
||||
ChunkGenerator chunkGenerator2;
|
||||
|
||||
@@ -8,7 +8,7 @@ import java.util.List;
|
||||
|
||||
public abstract class AbstractListValue extends Value implements Iterable<Value>
|
||||
{
|
||||
public abstract Iterator<Value> iterator();
|
||||
@Override public abstract Iterator<Value> iterator();
|
||||
public List<Value> unpack() { return Lists.newArrayList(iterator()); }
|
||||
public void fatality() { }
|
||||
public void append(Value v)
|
||||
|
||||
@@ -12,7 +12,7 @@ public class BooleanValue extends NumericValue
|
||||
|
||||
boolean boolValue;
|
||||
private BooleanValue(boolean boolval) {
|
||||
super(boolval);
|
||||
super(boolval ? 1L : 0L);
|
||||
boolValue = boolval;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ import carpet.fakes.ItemEntityInterface;
|
||||
import carpet.fakes.LivingEntityInterface;
|
||||
import carpet.fakes.MemoryInterface;
|
||||
import carpet.fakes.MobEntityInterface;
|
||||
import carpet.fakes.HungerManagerInterface;
|
||||
import carpet.fakes.ServerPlayerEntityInterface;
|
||||
import carpet.fakes.ServerPlayerInteractionManagerInterface;
|
||||
import carpet.helpers.Tracer;
|
||||
@@ -413,14 +412,14 @@ public class EntityValue extends Value
|
||||
throw new InternalExpressionException("Cannot fetch '"+what+"' with these arguments");
|
||||
}
|
||||
}
|
||||
private static final Map<String, EquipmentSlot> inventorySlots = new HashMap<String, EquipmentSlot>(){{
|
||||
put("mainhand", EquipmentSlot.MAINHAND);
|
||||
put("offhand", EquipmentSlot.OFFHAND);
|
||||
put("head", EquipmentSlot.HEAD);
|
||||
put("chest", EquipmentSlot.CHEST);
|
||||
put("legs", EquipmentSlot.LEGS);
|
||||
put("feet", EquipmentSlot.FEET);
|
||||
}};
|
||||
private static final Map<String, EquipmentSlot> inventorySlots = Map.of(
|
||||
"mainhand", EquipmentSlot.MAINHAND,
|
||||
"offhand", EquipmentSlot.OFFHAND,
|
||||
"head", EquipmentSlot.HEAD,
|
||||
"chest", EquipmentSlot.CHEST,
|
||||
"legs", EquipmentSlot.LEGS,
|
||||
"feet", EquipmentSlot.FEET
|
||||
);
|
||||
|
||||
private static final Map<String, BiFunction<Entity, Value, Value>> featureAccessors = new HashMap<String, BiFunction<Entity, Value, Value>>() {{
|
||||
//put("test", (e, a) -> a == null ? Value.NULL : new StringValue(a.getString()));
|
||||
@@ -530,9 +529,8 @@ public class EntityValue extends Value
|
||||
return Value.NULL;
|
||||
});
|
||||
put("spawn_point", (e, a) -> {
|
||||
if (e instanceof ServerPlayerEntity)
|
||||
if (e instanceof ServerPlayerEntity spe)
|
||||
{
|
||||
ServerPlayerEntity spe = (ServerPlayerEntity)e;
|
||||
if (spe.getSpawnPointPosition() == null) return Value.FALSE;
|
||||
return ListValue.of(
|
||||
ValueConversions.of(spe.getSpawnPointPosition()),
|
||||
@@ -573,7 +571,7 @@ public class EntityValue extends Value
|
||||
});
|
||||
|
||||
put("exhaustion",(e, a)->{
|
||||
if(e instanceof PlayerEntity) return new NumericValue(((HungerManagerInterface)((PlayerEntity) e).getHungerManager()).getExhaustionCM());
|
||||
if(e instanceof PlayerEntity) return new NumericValue(((PlayerEntity) e).getHungerManager().getExhaustion());
|
||||
return Value.NULL;
|
||||
});
|
||||
|
||||
@@ -631,9 +629,8 @@ public class EntityValue extends Value
|
||||
String module = a.getString();
|
||||
MemoryModuleType<?> moduleType = Registry.MEMORY_MODULE_TYPE.get(InputValidator.identifierOf(module));
|
||||
if (moduleType == MemoryModuleType.DUMMY) return Value.NULL;
|
||||
if (e instanceof LivingEntity)
|
||||
if (e instanceof LivingEntity livingEntity)
|
||||
{
|
||||
LivingEntity livingEntity = (LivingEntity)e;
|
||||
Brain<?> brain = livingEntity.getBrain();
|
||||
Map<MemoryModuleType<?>, Optional<? extends Memory<?>>> memories = ((BrainInterface)brain).getMobMemories();
|
||||
Optional<? extends Memory<?>> optmemory = memories.get(moduleType);
|
||||
@@ -652,9 +649,8 @@ public class EntityValue extends Value
|
||||
});
|
||||
|
||||
put("permission_level", (e, a) -> {
|
||||
if (e instanceof ServerPlayerEntity)
|
||||
if (e instanceof ServerPlayerEntity spe)
|
||||
{
|
||||
ServerPlayerEntity spe = (ServerPlayerEntity) e;
|
||||
for (int i=4; i>=0; i--)
|
||||
{
|
||||
if (spe.hasPermissionLevel(i))
|
||||
@@ -667,10 +663,9 @@ public class EntityValue extends Value
|
||||
});
|
||||
|
||||
put("player_type", (e, a) -> {
|
||||
if (e instanceof PlayerEntity)
|
||||
if (e instanceof PlayerEntity p)
|
||||
{
|
||||
if (e instanceof EntityPlayerMPFake) return new StringValue(((EntityPlayerMPFake) e).isAShadow?"shadow":"fake");
|
||||
PlayerEntity p = (PlayerEntity)e;
|
||||
MinecraftServer server = p.getEntityWorld().getServer();
|
||||
if (server.isDedicated()) return new StringValue("multiplayer");
|
||||
boolean runningLan = server.isRemote();
|
||||
@@ -927,9 +922,8 @@ public class EntityValue extends Value
|
||||
e.refreshPositionAndAngles(x, y, z, yaw, pitch);
|
||||
// we were sending to players for not-living entites, that were untracked. Living entities should be tracked.
|
||||
//((ServerWorld) e.getEntityWorld()).getChunkManager().sendToNearbyPlayers(e, new EntityS2CPacket.(e));
|
||||
if (e instanceof LivingEntity)
|
||||
if (e instanceof LivingEntity le)
|
||||
{
|
||||
LivingEntity le = (LivingEntity)e;
|
||||
le.prevBodyYaw = le.prevYaw = yaw;
|
||||
le.prevHeadYaw = le.headYaw = yaw;
|
||||
// seems universal for:
|
||||
@@ -956,9 +950,8 @@ public class EntityValue extends Value
|
||||
put("age", (e, v) -> e.age = Math.abs((int)NumericValue.asNumber(v).getLong()) );
|
||||
put("health", (e, v) -> {
|
||||
float health = (float) NumericValue.asNumber(v).getDouble();
|
||||
if (health <= 0f && e instanceof ServerPlayerEntity)
|
||||
if (health <= 0f && e instanceof ServerPlayerEntity player)
|
||||
{
|
||||
ServerPlayerEntity player = (ServerPlayerEntity) e;
|
||||
if (player.currentScreenHandler != null)
|
||||
{
|
||||
// if player dies with open container, then that causes NPE on the client side
|
||||
@@ -1273,8 +1266,7 @@ public class EntityValue extends Value
|
||||
}); //requires mixing
|
||||
|
||||
put("spawn_point", (e, a) -> {
|
||||
if (!(e instanceof ServerPlayerEntity)) return;
|
||||
ServerPlayerEntity spe = (ServerPlayerEntity)e;
|
||||
if (!(e instanceof ServerPlayerEntity spe)) return;
|
||||
if (a == null)
|
||||
{
|
||||
spe.setSpawnPoint(null, null, 0, false, false);
|
||||
@@ -1302,9 +1294,8 @@ public class EntityValue extends Value
|
||||
}
|
||||
spe.setSpawnPoint(world, pos, angle, forced, false);
|
||||
}
|
||||
else if (a instanceof BlockValue)
|
||||
else if (a instanceof BlockValue bv)
|
||||
{
|
||||
BlockValue bv= (BlockValue)a;
|
||||
if (bv.getPos()==null || bv.getWorld() == null)
|
||||
throw new InternalExpressionException("block for spawn modification should be localised in the world");
|
||||
spe.setSpawnPoint(bv.getWorld().getRegistryKey(), bv.getPos(), e.getYaw(), true, false); // yaw
|
||||
@@ -1367,8 +1358,7 @@ public class EntityValue extends Value
|
||||
});
|
||||
put("effect", (e, v) ->
|
||||
{
|
||||
if (!(e instanceof LivingEntity)) return;
|
||||
LivingEntity le = (LivingEntity)e;
|
||||
if (!(e instanceof LivingEntity le)) return;
|
||||
if (v == null)
|
||||
{
|
||||
le.clearStatusEffects();
|
||||
@@ -1473,7 +1463,7 @@ public class EntityValue extends Value
|
||||
});
|
||||
|
||||
put("exhaustion", (e, v)-> {
|
||||
if(e instanceof PlayerEntity) ((HungerManagerInterface) ((PlayerEntity) e).getHungerManager()).setExhaustionCM(NumericValue.asNumber(v).getFloat());
|
||||
if(e instanceof PlayerEntity) ((PlayerEntity) e).getHungerManager().setExhaustion(NumericValue.asNumber(v).getFloat());
|
||||
});
|
||||
|
||||
put("add_exhaustion", (e, v)-> {
|
||||
@@ -1506,7 +1496,7 @@ public class EntityValue extends Value
|
||||
});
|
||||
|
||||
put("saturation", (e, v)-> {
|
||||
if(e instanceof PlayerEntity) ((HungerManagerInterface) ((PlayerEntity) e).getHungerManager()).setSaturationCM(NumericValue.asNumber(v, "saturation").getFloat());
|
||||
if(e instanceof PlayerEntity) ((PlayerEntity) e).getHungerManager().setSaturationLevel(NumericValue.asNumber(v, "saturation").getFloat());
|
||||
});
|
||||
|
||||
put("air", (e, v) -> e.setAir(NumericValue.asNumber(v, "air").getInt()));
|
||||
|
||||
@@ -109,9 +109,9 @@ public abstract class LazyListValue extends AbstractListValue implements Iterato
|
||||
{
|
||||
return hasNext();
|
||||
}
|
||||
public abstract boolean hasNext();
|
||||
@Override public abstract boolean hasNext();
|
||||
|
||||
public abstract Value next();
|
||||
@Override public abstract Value next();
|
||||
|
||||
@Override
|
||||
public void fatality() {reset();}
|
||||
|
||||
@@ -149,6 +149,8 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
{
|
||||
items.add(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value subtract(Value other)
|
||||
{
|
||||
ListValue output = new ListValue();
|
||||
@@ -182,6 +184,7 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Value multiply(Value other)
|
||||
{
|
||||
ListValue output = new ListValue();
|
||||
@@ -209,6 +212,8 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value divide(Value other)
|
||||
{
|
||||
ListValue output = new ListValue();
|
||||
@@ -272,8 +277,10 @@ public class ListValue extends AbstractListValue implements ContainerValueInterf
|
||||
return items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Value> iterator() { return new ArrayList<>(items).iterator(); } // should be thread safe
|
||||
|
||||
@Override
|
||||
public List<Value> unpack()
|
||||
{
|
||||
return new ArrayList<>(items);
|
||||
|
||||
@@ -235,11 +235,11 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
{
|
||||
Inventory inv = null;
|
||||
Entity e = ((EntityValue) v1).getEntity();
|
||||
if (e instanceof PlayerEntity) inv = ((PlayerEntity) e).getInventory();
|
||||
if (e instanceof PlayerEntity pe) inv = pe.getInventory();
|
||||
else if (e instanceof Inventory) inv = (Inventory) e;
|
||||
else if (e instanceof InventoryOwner) inv = ((InventoryOwner) e).getInventory();
|
||||
else if (e instanceof InventoryBearerInterface) inv = ((InventoryBearerInterface)e).getCMInventory(); // horse only
|
||||
else if (e instanceof LivingEntity) return new InventoryLocator(e, e.getBlockPos(), new EquipmentInventory((MobEntity) e), offset+1);
|
||||
else if (e instanceof InventoryOwner io) inv = io.getInventory();
|
||||
else if (e instanceof InventoryBearerInterface ibi) inv = ibi.getCMInventory(); // horse only
|
||||
else if (e instanceof LivingEntity le) return new InventoryLocator(e, e.getBlockPos(), new EquipmentInventory(le), offset+1);
|
||||
if (inv == null)
|
||||
return null;
|
||||
|
||||
@@ -633,26 +633,12 @@ public class NBTSerializableValue extends Value implements ContainerValueInterfa
|
||||
return false;
|
||||
}
|
||||
|
||||
public static class InventoryLocator
|
||||
public static record InventoryLocator(Object owner, BlockPos position, Inventory inventory, int offset, boolean isEnder)
|
||||
{
|
||||
public Object owner;
|
||||
public BlockPos position;
|
||||
public Inventory inventory;
|
||||
public int offset;
|
||||
public boolean isEnder;
|
||||
InventoryLocator(Object owner, BlockPos pos, Inventory i, int o)
|
||||
{
|
||||
this(owner, pos, i, o, false);
|
||||
}
|
||||
|
||||
InventoryLocator(Object owner, BlockPos pos, Inventory i, int o, boolean isEnder)
|
||||
{
|
||||
this.owner = owner;
|
||||
position = pos;
|
||||
inventory = i;
|
||||
offset = o;
|
||||
this.isEnder = isEnder;
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<String, NbtPathArgumentType.NbtPath> pathCache = new HashMap<>();
|
||||
|
||||
@@ -33,7 +33,7 @@ public class NullValue extends NumericValue // TODO check nonsingleton code
|
||||
{
|
||||
return new NullValue();
|
||||
}
|
||||
private NullValue() {super(false);}
|
||||
private NullValue() {super(0);}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o)
|
||||
|
||||
@@ -110,9 +110,8 @@ public class NumericValue extends Value
|
||||
@Override
|
||||
public Value add(Value v)
|
||||
{ // TODO test if definintn add(NumericVlaue) woud solve the casting
|
||||
if (v instanceof NumericValue)
|
||||
if (v instanceof NumericValue nv)
|
||||
{
|
||||
NumericValue nv = (NumericValue)v;
|
||||
if (longValue != null && nv.longValue != null)
|
||||
{
|
||||
return new NumericValue(longValue+nv.longValue);
|
||||
@@ -121,10 +120,11 @@ public class NumericValue extends Value
|
||||
}
|
||||
return super.add(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value subtract(Value v) { // TODO test if definintn add(NumericVlaue) woud solve the casting
|
||||
if (v instanceof NumericValue)
|
||||
if (v instanceof NumericValue nv)
|
||||
{
|
||||
NumericValue nv = (NumericValue)v;
|
||||
if (longValue != null && nv.longValue != null)
|
||||
{
|
||||
return new NumericValue(longValue-nv.longValue);
|
||||
@@ -133,11 +133,12 @@ public class NumericValue extends Value
|
||||
}
|
||||
return super.subtract(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value multiply(Value v)
|
||||
{
|
||||
if (v instanceof NumericValue)
|
||||
if (v instanceof NumericValue nv)
|
||||
{
|
||||
NumericValue nv = (NumericValue)v;
|
||||
if (longValue != null && nv.longValue != null)
|
||||
{
|
||||
return new NumericValue(longValue*nv.longValue);
|
||||
@@ -150,6 +151,8 @@ public class NumericValue extends Value
|
||||
}
|
||||
return new StringValue(StringUtils.repeat(v.getString(), (int) getLong()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value divide(Value v)
|
||||
{
|
||||
//if (1+2==3) throw new ArithmeticException("Booyah");
|
||||
@@ -173,9 +176,8 @@ public class NumericValue extends Value
|
||||
{
|
||||
return -o.compareTo(this);
|
||||
}
|
||||
if (o instanceof NumericValue)
|
||||
if (o instanceof NumericValue no)
|
||||
{
|
||||
NumericValue no = (NumericValue)o;
|
||||
if (longValue != null && no.longValue != null)
|
||||
return longValue.compareTo(no.longValue);
|
||||
return Double.compare(value, no.value);
|
||||
@@ -189,9 +191,8 @@ public class NumericValue extends Value
|
||||
{
|
||||
return o.equals(this);
|
||||
}
|
||||
if (o instanceof NumericValue)
|
||||
if (o instanceof NumericValue no)
|
||||
{
|
||||
NumericValue no = (NumericValue)o;
|
||||
if (longValue != null && no.longValue != null)
|
||||
return longValue.equals(no.longValue);
|
||||
return !this.subtract(no).getBoolean();
|
||||
@@ -228,17 +229,6 @@ public class NumericValue extends Value
|
||||
this.value = (double)value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a legacy {@link NumericValue} for a {@code boolean}.
|
||||
* @param boolval The boolean to set 1 or 0 for this {@link NumericValue}
|
||||
* @deprecated Use {@link BooleanValue#of(boolean)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public NumericValue(boolean boolval)
|
||||
{
|
||||
this(boolval?1L:0L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int length()
|
||||
{
|
||||
|
||||
@@ -123,9 +123,8 @@ public class ValueConversions
|
||||
{
|
||||
return ((EntityValue)dimensionValue).getEntity().getEntityWorld();
|
||||
}
|
||||
else if (dimensionValue instanceof BlockValue)
|
||||
else if (dimensionValue instanceof BlockValue bv)
|
||||
{
|
||||
BlockValue bv = (BlockValue)dimensionValue;
|
||||
if (bv.getWorld() != null)
|
||||
{
|
||||
return bv.getWorld();
|
||||
@@ -225,9 +224,8 @@ public class ValueConversions
|
||||
|
||||
private static Value fromEntityMemory(Entity e, Object v)
|
||||
{
|
||||
if (v instanceof GlobalPos)
|
||||
if (v instanceof GlobalPos pos)
|
||||
{
|
||||
GlobalPos pos = (GlobalPos)v;
|
||||
return of(pos);
|
||||
}
|
||||
if (v instanceof Entity)
|
||||
@@ -250,9 +248,8 @@ public class ValueConversions
|
||||
{
|
||||
return ofUUID( (ServerWorld) e.getEntityWorld(), (UUID)v);
|
||||
}
|
||||
if (v instanceof DamageSource)
|
||||
if (v instanceof DamageSource source)
|
||||
{
|
||||
DamageSource source = (DamageSource) v;
|
||||
return ListValue.of(
|
||||
new StringValue(source.getName()),
|
||||
source.getAttacker()==null?Value.NULL:new EntityValue(source.getAttacker())
|
||||
@@ -278,9 +275,8 @@ public class ValueConversions
|
||||
{
|
||||
v = new ArrayList(((Set) v));
|
||||
}
|
||||
if (v instanceof List)
|
||||
if (v instanceof List l)
|
||||
{
|
||||
List l = (List)v;
|
||||
if (l.isEmpty()) return ListValue.of();
|
||||
Object el = l.get(0);
|
||||
if (el instanceof Entity)
|
||||
|
||||
@@ -2,7 +2,6 @@ package carpet.settings;
|
||||
|
||||
import carpet.utils.Translations;
|
||||
import carpet.utils.Messenger;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
@@ -11,6 +10,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.lang3.ClassUtils;
|
||||
|
||||
@@ -29,9 +29,9 @@ public final class ParsedRule<T> implements Comparable<ParsedRule> {
|
||||
public final String name;
|
||||
public final String description;
|
||||
public final String scarpetApp;
|
||||
public final ImmutableList<String> extraInfo;
|
||||
public final ImmutableList<String> categories;
|
||||
public final ImmutableList<String> options;
|
||||
public final List<String> extraInfo;
|
||||
public final List<String> categories;
|
||||
public final List<String> options;
|
||||
public boolean isStrict;
|
||||
public boolean isClient;
|
||||
public final Class<T> type;
|
||||
@@ -47,8 +47,8 @@ public final class ParsedRule<T> implements Comparable<ParsedRule> {
|
||||
this.type = (Class<T>) field.getType();
|
||||
this.description = rule.desc();
|
||||
this.isStrict = rule.strict();
|
||||
this.extraInfo = ImmutableList.copyOf(rule.extra());
|
||||
this.categories = ImmutableList.copyOf(rule.category());
|
||||
this.extraInfo = List.of(rule.extra());
|
||||
this.categories = List.of(rule.category());
|
||||
this.scarpetApp = rule.appSource();
|
||||
this.settingsManager = settingsManager;
|
||||
this.validators = new ArrayList<>();
|
||||
@@ -76,22 +76,22 @@ public final class ParsedRule<T> implements Comparable<ParsedRule> {
|
||||
this.defaultAsString = convertToString(this.defaultValue);
|
||||
if (rule.options().length > 0)
|
||||
{
|
||||
this.options = ImmutableList.copyOf(rule.options());
|
||||
this.options = List.of(rule.options());
|
||||
}
|
||||
else if (this.type == boolean.class){
|
||||
this.options = ImmutableList.of("true","false");
|
||||
this.options = List.of("true","false");
|
||||
}
|
||||
else if(this.type == String.class && categories.contains(RuleCategory.COMMAND))
|
||||
{
|
||||
this.options = ImmutableList.of("true", "false", "ops");
|
||||
this.options = List.of("true", "false", "ops");
|
||||
}
|
||||
else if (this.type.isEnum())
|
||||
{
|
||||
this.options = Arrays.stream(this.type.getEnumConstants()).map(e -> ((Enum) e).name().toLowerCase(Locale.ROOT)).collect(ImmutableList.toImmutableList());
|
||||
this.options = Arrays.stream(this.type.getEnumConstants()).map(e -> ((Enum) e).name().toLowerCase(Locale.ROOT)).collect(Collectors.toUnmodifiableList());
|
||||
}
|
||||
else
|
||||
{
|
||||
this.options = ImmutableList.of();
|
||||
this.options = List.of();
|
||||
}
|
||||
if (isStrict && !this.options.isEmpty())
|
||||
{
|
||||
|
||||
@@ -5,7 +5,6 @@ import carpet.CarpetSettings;
|
||||
import carpet.network.ServerNetworkHandler;
|
||||
import carpet.utils.Translations;
|
||||
import carpet.utils.Messenger;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||
@@ -72,6 +71,7 @@ public class SettingsManager
|
||||
private MinecraftServer server;
|
||||
private List<TriConsumer<ServerCommandSource, ParsedRule<?>, String>> observers = new ArrayList<>();
|
||||
private static List<TriConsumer<ServerCommandSource, ParsedRule<?>, String>> staticObservers = new ArrayList<>();
|
||||
static record ConfigReadResult(Map<String, String> ruleMap, boolean locked) {}
|
||||
|
||||
/**
|
||||
* Creates a new {@link SettingsManager} without a fancy name.
|
||||
@@ -264,7 +264,7 @@ public class SettingsManager
|
||||
*/
|
||||
public Collection<ParsedRule<?>> findStartupOverrides()
|
||||
{
|
||||
Set<String> defaults = readSettingsFromConf(getFile()).getLeft().keySet();
|
||||
Set<String> defaults = readSettingsFromConf(getFile()).ruleMap().keySet();
|
||||
return rules.values().stream().filter(r -> defaults.contains(r.name)).
|
||||
sorted().collect(Collectors.toList());
|
||||
}
|
||||
@@ -396,30 +396,30 @@ public class SettingsManager
|
||||
private void loadConfigurationFromConf()
|
||||
{
|
||||
for (ParsedRule<?> rule : rules.values()) rule.resetToDefault(server.getCommandSource());
|
||||
Pair<Map<String, String>, Boolean> conf = readSettingsFromConf(getFile());
|
||||
ConfigReadResult conf = readSettingsFromConf(getFile());
|
||||
locked = false;
|
||||
if (conf.getRight())
|
||||
if (conf.locked())
|
||||
{
|
||||
CarpetSettings.LOG.info("[CM]: "+fancyName+" features are locked by the administrator");
|
||||
disableBooleanCommands();
|
||||
}
|
||||
for (String key: conf.getLeft().keySet())
|
||||
for (String key: conf.ruleMap().keySet())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (rules.get(key).set(server.getCommandSource(), conf.getLeft().get(key)) != null)
|
||||
CarpetSettings.LOG.info("[CM]: loaded setting " + key + " as " + conf.getLeft().get(key) + " from " + identifier + ".conf");
|
||||
if (rules.get(key).set(server.getCommandSource(), conf.ruleMap().get(key)) != null)
|
||||
CarpetSettings.LOG.info("[CM]: loaded setting " + key + " as " + conf.ruleMap().get(key) + " from " + identifier + ".conf");
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
CarpetSettings.LOG.error("[CM Error]: Failed to load setting: "+key+", "+exc);
|
||||
}
|
||||
}
|
||||
locked = conf.getRight();
|
||||
locked = conf.locked();
|
||||
}
|
||||
|
||||
|
||||
private Pair<Map<String, String>, Boolean> readSettingsFromConf(Path path)
|
||||
private ConfigReadResult readSettingsFromConf(Path path)
|
||||
{
|
||||
try (BufferedReader reader = Files.newBufferedReader(path))
|
||||
{
|
||||
@@ -452,9 +452,9 @@ public class SettingsManager
|
||||
|
||||
}
|
||||
}
|
||||
return Pair.of(result, confLocked);
|
||||
return new ConfigReadResult(result, confLocked);
|
||||
}
|
||||
catch(NoSuchFileException e)
|
||||
catch (NoSuchFileException e)
|
||||
{
|
||||
if (path.equals(getFile()) && FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT)
|
||||
{
|
||||
@@ -467,15 +467,15 @@ public class SettingsManager
|
||||
}
|
||||
return readSettingsFromConf(defaultsPath);
|
||||
} catch (IOException e2) {
|
||||
CarpetSettings.LOG.error("Exception when loading fallback default config: ", e);
|
||||
CarpetSettings.LOG.error("Exception when loading fallback default config: ", e2);
|
||||
}
|
||||
}
|
||||
return Pair.of(new HashMap<>(), false);
|
||||
return new ConfigReadResult(new HashMap<>(), false);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
return Pair.of(new HashMap<>(), false);
|
||||
return new ConfigReadResult(new HashMap<>(), false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -486,7 +486,7 @@ public class SettingsManager
|
||||
if (rule.name.toLowerCase(Locale.ROOT).contains(lcSearch)) return true; // substring match, case insensitive
|
||||
for (String c : rule.categories) if (c.equals(search)) return true; // category exactly, case sensitive
|
||||
return Sets.newHashSet(rule.description.toLowerCase(Locale.ROOT).split("\\W+")).contains(lcSearch); // contains full term in description, but case insensitive
|
||||
}).sorted().collect(ImmutableList.toImmutableList());
|
||||
}).sorted().collect(Collectors.toUnmodifiableList());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -647,9 +647,9 @@ public class SettingsManager
|
||||
{
|
||||
if (locked) return 0;
|
||||
if (!rules.containsKey(rule.name)) return 0;
|
||||
Pair<Map<String, String>,Boolean> conf = readSettingsFromConf(getFile());
|
||||
conf.getLeft().put(rule.name, stringValue);
|
||||
writeSettingsToConf(conf.getLeft()); // this may feels weird, but if conf
|
||||
ConfigReadResult conf = readSettingsFromConf(getFile());
|
||||
conf.ruleMap().put(rule.name, stringValue);
|
||||
writeSettingsToConf(conf.ruleMap()); // this may feels weird, but if conf
|
||||
// is locked, it will never reach this point.
|
||||
rule.set(source,stringValue);
|
||||
Messenger.m(source ,"gi "+String.format(tr("ui.rule_%(rule)s_will_now_default_to_%(value)s","Rule %s will now default to %s"), rule.translatedName(), stringValue));
|
||||
@@ -660,9 +660,9 @@ public class SettingsManager
|
||||
{
|
||||
if (locked) return 0;
|
||||
if (!rules.containsKey(rule.name)) return 0;
|
||||
Pair<Map<String, String>,Boolean> conf = readSettingsFromConf(getFile());
|
||||
conf.getLeft().remove(rule.name);
|
||||
writeSettingsToConf(conf.getLeft());
|
||||
ConfigReadResult conf = readSettingsFromConf(getFile());
|
||||
conf.ruleMap().remove(rule.name);
|
||||
writeSettingsToConf(conf.ruleMap());
|
||||
rules.get(rule.name).resetToDefault(source);
|
||||
Messenger.m(source ,"gi "+String.format(tr("ui.rule_%(rule)s_not_set_restart","Rule %s will now not be set on restart"), rule.translatedName()));
|
||||
return 1;
|
||||
|
||||
@@ -2,9 +2,9 @@ package carpet.settings;
|
||||
|
||||
import carpet.CarpetServer;
|
||||
import carpet.utils.Messenger;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -48,7 +48,7 @@ public abstract class Validator<T>
|
||||
}
|
||||
|
||||
public static class _COMMAND_LEVEL_VALIDATOR extends Validator<String> {
|
||||
private static ImmutableList<String> OPTIONS = ImmutableList.of("true", "false", "ops", "0", "1", "2", "3", "4");
|
||||
private static List<String> OPTIONS = List.of("true", "false", "ops", "0", "1", "2", "3", "4");
|
||||
@Override public String validate(ServerCommandSource source, ParsedRule<String> currentRule, String newValue, String userString) {
|
||||
if (!OPTIONS.contains(userString.toLowerCase(Locale.ROOT)))
|
||||
{
|
||||
@@ -59,7 +59,7 @@ public abstract class Validator<T>
|
||||
}
|
||||
return userString.toLowerCase(Locale.ROOT);
|
||||
}
|
||||
public String description() { return "Can be limited to 'ops' only, or a custom permission level";}
|
||||
@Override public String description() { return "Can be limited to 'ops' only, or a custom permission level";}
|
||||
}
|
||||
|
||||
public static class _SCARPET<T> extends Validator<T> {
|
||||
@@ -68,7 +68,7 @@ public abstract class Validator<T>
|
||||
{
|
||||
return newValue;
|
||||
}
|
||||
public String description() {
|
||||
@Override public String description() {
|
||||
return "It controls an accompanying Scarpet App";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,19 +50,11 @@ public class CarpetProfiler
|
||||
TILEENTITY
|
||||
}
|
||||
|
||||
public static class ProfilerToken
|
||||
public static record ProfilerToken(TYPE type, Object section, long start, World world)
|
||||
{
|
||||
public final TYPE type;
|
||||
public final Object section;
|
||||
public final long start;
|
||||
public final World world;
|
||||
|
||||
public ProfilerToken(TYPE type, Object section, World world)
|
||||
{
|
||||
this.type = type;
|
||||
this.section = section;
|
||||
this.start = System.nanoTime();
|
||||
this.world = world;
|
||||
this(type, section, System.nanoTime(), world);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
package carpet.utils;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
@@ -520,7 +519,7 @@ public class SpawnReporter
|
||||
|
||||
String creature_name = mob.getType().getName().getString();
|
||||
String pack_size = String.format("%d", mob.getLimitPerChunk());//String.format("%d-%d", animal.minGroupCount, animal.maxGroupCount);
|
||||
int weight = spawnEntry.getWeight().getValue();// ((WeightedPickerEntryMixin) spawnEntry).getWeight();
|
||||
int weight = spawnEntry.getWeight().getValue();
|
||||
if (canspawn)
|
||||
{
|
||||
String c = (fits_true && will_spawn>0)?"e":"gi";
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
"CommandManagerMixin",
|
||||
|
||||
"ServerPlayNetworkHandlerMixin",
|
||||
"CustomPayloadC2SPacketMixin",
|
||||
|
||||
"PerfCommand_permissionMixin",
|
||||
"FillCommandMixin",
|
||||
@@ -75,7 +74,6 @@
|
||||
"ServerPlayNetworkHandler_tickMixin",
|
||||
"MinecraftServer_scarpetMixin",
|
||||
"PlayerListHeaderS2CPacketMixin",
|
||||
"WeightedPickerEntryMixin",
|
||||
"ExperienceOrbEntityMixin",
|
||||
"PlayerActionC2SPacketMixin",
|
||||
"ServerPlayerEntityMixin",
|
||||
@@ -88,8 +86,9 @@
|
||||
"PistonHandler_pushLimitMixin",
|
||||
"PoweredRailBlock_powerLimitMixin",
|
||||
"LivingEntity_maxCollisionsMixin",
|
||||
"ServerWorld_onePlayerSleepingMixin",
|
||||
"World_getOtherEntitiesLimited",
|
||||
"CoralBlockMixin",
|
||||
"CoralFanBlockMixin",
|
||||
"CoralFeatureMixin",
|
||||
"BuddingAmethystBlock_movableAmethystMixin",
|
||||
"FluidBlock_renewableBlackstoneMixin",
|
||||
@@ -188,11 +187,9 @@
|
||||
|
||||
"BiomeEffects_scarpetMixin",
|
||||
"ChunkTicketManager_scarpetMixin",
|
||||
"StatType_scarpetMixin",
|
||||
"PointOfInterest_scarpetMixin",
|
||||
"ServerWorld_scarpetMixin",
|
||||
"ServerEntityManager_scarpetMixin",
|
||||
"HungerManagerMixin_scarpetEventsMixin",
|
||||
"ReloadCommand_reloadAppsMixin",
|
||||
"CrashReport_addScarpetAppsMixin",
|
||||
|
||||
@@ -245,4 +242,4 @@
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user