1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-11-01 14:12:59 +00:00

Compare commits

...

18 Commits

Author SHA1 Message Date
Jonathan Coates
7c373c6e06 Merge branch 'mc-1.17.x' into mc-1.18.x 2021-12-11 07:50:18 +00:00
Jonathan Coates
6196aae488 Merge branch 'mc-1.16.x' into mc-1.17.x 2021-12-11 07:49:33 +00:00
Jonathan Coates
92a0ef2b75 Bump CC:T version 2021-12-11 07:37:10 +00:00
Jonathan Coates
57c5d19f95 Update to Forge 1.18.1 2021-12-11 07:31:41 +00:00
Jonathan Coates
1f6e0f287d Ensure the origin monitor is valid too
Blurh, still not sure if this is Correct or anything, but have no clue
what's causing this. Fixes #985. Hopefully.
2021-12-10 13:13:31 +00:00
Jonathan Coates
0e4b7a5a75 Prevent terminal buttons stealing focus
I have shutdown my computer by accident far too many times now.
2021-12-08 23:16:53 +00:00
Jonathan Coates
47ad7a35dc Fix NPE when pulling an event with no type
I assume people have broken coroutine dispatchers - I didn't think it
was possible to queue an actual event with no type.

See cc-tweaked/cc-restitched#31. Will fix it too once merged downstream!
2021-12-08 22:47:21 +00:00
Jonathan Coates
3eab2a9b57 Add support for a zero-copy Lua table
The API is entirely designed for the needs of the speaker right now, so
doesn't do much else.
2021-12-07 18:27:29 +00:00
Jonathan Coates
c4024a4c4c Use an admonition instead 2021-12-02 22:41:58 +00:00
Jonathan Coates
f5fb82cd7d Merge pull request #977 from MCJack123/patch-9
Add package.searchpath
2021-12-02 12:34:07 +00:00
Jonathan Coates
23c17075be save -> saveAdditional
Also add in a janky workabround for handleUpdateTag not being called.
Being an early porter is always fun :D:.
2021-12-02 09:20:06 +00:00
MCJack123
e18ba8a2c2 Add package.searchpath 2021-12-01 18:55:24 -05:00
Jonathan Coates
87988a705b Exclude Jetbrains annotations from testModExtra
testModExtra must /strictly/ be the set of dependencies which are not
present in implementation - there can't be any duplicates.

Yes, it's stupid, but the whole lazyToken("minecraft_classpath") thing
wasn't really built with this in mind, so not much we can do :)
2021-12-01 20:40:46 +00:00
Jonathan Coates
422bfdb60d Add 1.18 and remove 1.15 from the issue template
No, we're not pushing it to Curse yet, but while I remember.
2021-12-01 20:24:37 +00:00
Jonathan Coates
1851ed31cd Release keys when opening the offhand pocket computer screen
Opening a screen KeyBinding.releaseAll(), which forces all inputs to be
considered released. However, our init() function then calls
grabMouse(), which calls Keybinding.setAll(), undoing this work.

The fix we're going for here is to call releaseAll() one more time[^1]
after grabbing the mouse. I think if this becomes any more of a problem,
we should roll our own grabMouse which _doesn't_ implement any specific
behaviour.

Fixes #975

[^1]: Obvious problem here is that we do minecraft.screen=xyz rather
      than setScreen. We need to - otherwise we'd just hit a stack
      overflow - but it's not great.
2021-12-01 20:09:38 +00:00
Jonathan Coates
179da1d8cf Update to MC 1.18
- Build fails right now due to module issues, so this won't be pushed
   to GitHub.
 - Monitors render transparently when loaded into the world. I don't
   think this is a 1.17 bug, so not sure what's going on here!
2021-11-30 22:48:38 +00:00
Jonathan Coates
92fd93c0e0 Merge branch 'mc-1.16.x' into mc-1.17.x 2021-11-30 22:37:07 +00:00
Jonathan Coates
3929dba4a5 Only send update packets on the TEs which need it
More bits of #658
2021-11-30 22:01:09 +00:00
89 changed files with 783 additions and 242 deletions

View File

@@ -8,9 +8,9 @@ body:
label: Minecraft Version
description: What version of Minecraft are you using?
options:
- 1.15.x
- 1.16.x
- 1.17.x
- 1.18.x
validations:
required: true
- type: input

View File

@@ -5,7 +5,7 @@ buildscript {
maven { url = 'https://maven.parchmentmc.org' }
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:5.1.24'
classpath 'net.minecraftforge.gradle:ForgeGradle:5.1.+'
classpath 'org.parchmentmc:librarian:1.+'
}
}
@@ -29,7 +29,7 @@ version = mod_version
group = "org.squiddev"
archivesBaseName = "cc-tweaked-${mc_version}"
def javaVersion = JavaLanguageVersion.of(16)
def javaVersion = JavaLanguageVersion.of(17)
java {
toolchain {
languageVersion = javaVersion
@@ -47,6 +47,7 @@ tasks.withType(JavaExec).configureEach {
sourceSets {
main.java {
exclude 'dan200/computercraft/shared/integration/jei/**'
exclude 'dan200/computercraft/shared/integration/morered/**'
}
main.resources {
@@ -122,7 +123,8 @@ minecraft {
}
}
mappings channel: 'parchment', version: "${mapping_version}-${mc_version}"
// mappings channel: 'parchment', version: "${mapping_version}-${mc_version}"
mappings channel: 'official', version: mc_version
accessTransformer file('src/main/resources/META-INF/accesstransformer.cfg')
accessTransformer file('src/testMod/resources/META-INF/accesstransformer.cfg')
@@ -151,10 +153,8 @@ dependencies {
minecraft "net.minecraftforge:forge:${mc_version}-${forge_version}"
compileOnly fg.deobf("mezz.jei:jei-1.17.1:8.0.0.14:api")
// compileOnly fg.deobf("commoble.morered:morered-1.16.5:2.1.1.0")
runtimeOnly fg.deobf("mezz.jei:jei-1.17.1:8.0.0.14")
// compileOnly fg.deobf("mezz.jei:jei-1.17.1:8.0.0.14:api")
// runtimeOnly fg.deobf("mezz.jei:jei-1.17.1:8.0.0.14")
shade 'org.squiddev:Cobalt:0.5.2-SNAPSHOT'
@@ -166,7 +166,9 @@ dependencies {
testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2'
testModImplementation sourceSets.main.output
testModExtra 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.21'
testModExtra('org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.0') {
exclude group: "org.jetbrains", module: "annotations"
}
cctJavadoc 'cc.tweaked:cct-javadoc:1.4.2'
}

View File

@@ -1,10 +1,10 @@
org.gradle.jvmargs=-Xmx3G
# Mod properties
mod_version=1.99.0
mod_version=1.99.1
# Minecraft properties (update mods.toml when changing)
mc_version=1.17.1
mc_version=1.18.1
mapping_version=2021.09.05
forge_version=37.0.85
forge_version=39.0.0
# NO SERIOUSLY, UPDATE mods.toml WHEN CHANGING

View File

@@ -38,7 +38,7 @@ import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.fmllegacy.server.ServerLifecycleHooks;
import net.minecraftforge.server.ServerLifecycleHooks;
import javax.annotation.Nonnull;
import java.io.File;

View File

@@ -183,6 +183,24 @@ public interface IArguments
return (Map<?, ?>) value;
}
/**
* Get an argument as a table in an unsafe manner.
*
* Classes implementing this interface may choose to implement a more optimised version which does not copy the
* table, instead returning a wrapper version, making it more efficient. However, the caller must guarantee that
* they do not access off the computer thread (and so should not be used with main-thread functions) or once the
* function call has finished (for instance, in callbacks).
*
* @param index The argument number.
* @return The argument's value.
* @throws LuaException If the value is not a table.
*/
@Nonnull
default LuaTable<?, ?> getTableUnsafe( int index ) throws LuaException
{
return new ObjectLuaTable( getTable( index ) );
}
/**
* Get an argument as a double.
*
@@ -314,6 +332,27 @@ public interface IArguments
return Optional.of( (Map<?, ?>) value );
}
/**
* Get an argument as a table in an unsafe manner.
*
* Classes implementing this interface may choose to implement a more optimised version which does not copy the
* table, instead returning a wrapper version, making it more efficient. However, the caller must guarantee that
* they do not access off the computer thread (and so should not be used with main-thread functions) or once the
* function call has finished (for instance, in callbacks).
*
* @param index The argument number.
* @return The argument's value, or {@link Optional#empty()} if not present.
* @throws LuaException If the value is not a table.
*/
@Nonnull
default Optional<LuaTable<?, ?>> optTableUnsafe( int index ) throws LuaException
{
Object value = get( index );
if( value == null ) return Optional.empty();
if( !(value instanceof Map) ) throw LuaValues.badArgumentOf( index, "map", value );
return Optional.of( new ObjectLuaTable( (Map<?, ?>) value ) );
}
/**
* Get an argument as a double.
*
@@ -404,4 +443,13 @@ public interface IArguments
{
return optTable( index ).orElse( def );
}
/**
* This is called when the current function finishes, before any main thread tasks have run.
*
* Called when the current function returns, and so some values are no longer guaranteed to be safe to access.
*/
default void releaseImmediate()
{
}
}

View File

@@ -51,8 +51,17 @@ public @interface LuaFunction
* Run this function on the main server thread. This should be specified for any method which interacts with
* Minecraft in a thread-unsafe manner.
*
* @return Whether this functi
* @return Whether this function should be run on the main thread.
* @see ILuaContext#issueMainThreadTask(ILuaTask)
*/
boolean mainThread() default false;
/**
* Allow using "unsafe" arguments, such {@link IArguments#getTableUnsafe(int)}.
*
* This is incompatible with {@link #mainThread()}.
*
* @return Whether this function supports unsafe arguments.
*/
boolean unsafe() default false;
}

View File

@@ -0,0 +1,114 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2021. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.lua;
import org.jetbrains.annotations.Nullable;
import javax.annotation.Nonnull;
import java.util.Map;
import static dan200.computercraft.api.lua.LuaValues.*;
public interface LuaTable<K, V> extends Map<K, V>
{
/**
* Compute the length of the array part of this table.
*
* @return This table's length.
*/
default int length()
{
int size = 0;
while( containsKey( (double) (size + 1) ) ) size++;
return size;
}
/**
* Get an array entry as an integer.
*
* @param index The index in the table, starting at 1.
* @return The table's value.
* @throws LuaException If the value is not an integer.
*/
default long getLong( int index ) throws LuaException
{
Object value = get( (double) index );
if( !(value instanceof Number) ) throw badTableItem( index, "number", getType( value ) );
Number number = (Number) value;
double asDouble = number.doubleValue();
if( !Double.isFinite( asDouble ) ) throw badTableItem( index, "number", getNumericType( asDouble ) );
return number.longValue();
}
/**
* Get a table entry as an integer.
*
* @param key The name of the field in the table.
* @return The table's value.
* @throws LuaException If the value is not an integer.
*/
default long getLong( String key ) throws LuaException
{
Object value = get( key );
if( !(value instanceof Number) ) throw badField( key, "number", getType( value ) );
Number number = (Number) value;
double asDouble = number.doubleValue();
if( !Double.isFinite( asDouble ) ) throw badField( key, "number", getNumericType( asDouble ) );
return number.longValue();
}
/**
* Get an array entry as an integer.
*
* @param index The index in the table, starting at 1.
* @return The table's value.
* @throws LuaException If the value is not an integer.
*/
default int getInt( int index ) throws LuaException
{
return (int) getLong( index );
}
/**
* Get a table entry as an integer.
*
* @param key The name of the field in the table.
* @return The table's value.
* @throws LuaException If the value is not an integer.
*/
default int getInt( String key ) throws LuaException
{
return (int) getLong( key );
}
@Nullable
@Override
default V put( K o, V o2 )
{
throw new UnsupportedOperationException( "Cannot modify LuaTable" );
}
@Override
default V remove( Object o )
{
throw new UnsupportedOperationException( "Cannot modify LuaTable" );
}
@Override
default void putAll( @Nonnull Map<? extends K, ? extends V> map )
{
throw new UnsupportedOperationException( "Cannot modify LuaTable" );
}
@Override
default void clear()
{
throw new UnsupportedOperationException( "Cannot modify LuaTable" );
}
}

View File

@@ -102,6 +102,34 @@ public final class LuaValues
return new LuaException( "bad argument #" + (index + 1) + " (" + expected + " expected, got " + actual + ")" );
}
/**
* Construct a table item exception, from an expected and actual type.
*
* @param index The index into the table, starting from 1.
* @param expected The expected type for this table item.
* @param actual The provided type for this table item.
* @return The constructed exception, which should be thrown immediately.
*/
@Nonnull
public static LuaException badTableItem( int index, @Nonnull String expected, @Nonnull String actual )
{
return new LuaException( "table item #" + index + " is not " + expected + " (got " + actual + ")" );
}
/**
* Construct a field exception, from an expected and actual type.
*
* @param key The name of the field.
* @param expected The expected type for this table item.
* @param actual The provided type for this table item.
* @return The constructed exception, which should be thrown immediately.
*/
@Nonnull
public static LuaException badField( String key, @Nonnull String expected, @Nonnull String actual )
{
return new LuaException( "field " + key + " is not " + expected + " (got " + actual + ")" );
}
/**
* Ensure a numeric argument is finite (i.e. not infinite or {@link Double#NaN}.
*

View File

@@ -98,7 +98,10 @@ public final class MethodResult
{
Objects.requireNonNull( callback, "callback cannot be null" );
return new MethodResult( new Object[] { filter }, results -> {
if( results.length >= 1 && results[0].equals( "terminate" ) ) throw new LuaException( "Terminated", 0 );
if( results.length >= 1 && Objects.equals( results[0], "terminate" ) )
{
throw new LuaException( "Terminated", 0 );
}
return callback.resume( results );
} );
}

View File

@@ -5,10 +5,12 @@
*/
package dan200.computercraft.api.lua;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
/**
* An implementation of {@link IArguments} which wraps an array of {@link Object}.
@@ -16,6 +18,8 @@ import java.util.Objects;
public final class ObjectArguments implements IArguments
{
private static final IArguments EMPTY = new ObjectArguments();
private boolean released = false;
private final List<Object> args;
@Deprecated
@@ -63,4 +67,34 @@ public final class ObjectArguments implements IArguments
{
return args.toArray();
}
@Nonnull
@Override
public LuaTable<?, ?> getTableUnsafe( int index ) throws LuaException
{
if( released )
{
throw new IllegalStateException( "Cannot use getTableUnsafe after IArguments has been released" );
}
return IArguments.super.getTableUnsafe( index );
}
@Nonnull
@Override
public Optional<LuaTable<?, ?>> optTableUnsafe( int index ) throws LuaException
{
if( released )
{
throw new IllegalStateException( "Cannot use optTableUnsafe after IArguments has been released" );
}
return IArguments.super.optTableUnsafe( index );
}
@Override
public void releaseImmediate()
{
released = true;
}
}

View File

@@ -0,0 +1,73 @@
/*
* This file is part of the public ComputerCraft API - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2021. This API may be redistributed unmodified and in full only.
* For help using the API, and posting your mods, visit the forums at computercraft.info.
*/
package dan200.computercraft.api.lua;
import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
public class ObjectLuaTable implements LuaTable<Object, Object>
{
private final Map<Object, Object> map;
public ObjectLuaTable( Map<?, ?> map )
{
this.map = Collections.unmodifiableMap( map );
}
@Override
public int size()
{
return map.size();
}
@Override
public boolean isEmpty()
{
return map.isEmpty();
}
@Override
public boolean containsKey( Object o )
{
return map.containsKey( o );
}
@Override
public boolean containsValue( Object o )
{
return map.containsKey( o );
}
@Override
public Object get( Object o )
{
return map.get( o );
}
@Nonnull
@Override
public Set<Object> keySet()
{
return map.keySet();
}
@Nonnull
@Override
public Collection<Object> values()
{
return map.values();
}
@Nonnull
@Override
public Set<Entry<Object, Object>> entrySet()
{
return map.entrySet();
}
}

View File

@@ -32,7 +32,7 @@ import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.ColorHandlerEvent;
import net.minecraftforge.client.event.EntityRenderersEvent;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.client.model.ForgeModelBakery;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
@@ -76,7 +76,7 @@ public final class ClientRegistry
ModelLoaderRegistry.registerLoader( new ResourceLocation( ComputerCraft.MOD_ID, "turtle" ), TurtleModelLoader.INSTANCE );
for( String model : EXTRA_MODELS )
{
ModelLoader.addSpecialModel( new ModelResourceLocation( new ResourceLocation( ComputerCraft.MOD_ID, model ), "inventory" ) );
ForgeModelBakery.addSpecialModel( new ModelResourceLocation( new ResourceLocation( ComputerCraft.MOD_ID, model ), "inventory" ) );
}
}

View File

@@ -8,6 +8,7 @@ package dan200.computercraft.client.gui;
import com.mojang.blaze3d.vertex.PoseStack;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.client.gui.widgets.ComputerSidebar;
import dan200.computercraft.client.gui.widgets.DynamicImageButton;
import dan200.computercraft.client.gui.widgets.WidgetTerminal;
import dan200.computercraft.shared.computer.core.ClientComputer;
import dan200.computercraft.shared.computer.core.ComputerFamily;
@@ -102,6 +103,16 @@ public abstract class ComputerScreenBase<T extends ContainerComputerBase> extend
renderTooltip( stack, mouseX, mouseY );
}
@Override
public boolean mouseClicked( double x, double y, int button )
{
boolean changed = super.mouseClicked( x, y, button );
// Clicking the terminate/shutdown button steals focus, which means then pressing "enter" will click the button
// again. Restore the focus to the terminal in these cases.
if( getFocused() instanceof DynamicImageButton ) setFocused( terminal );
return changed;
}
@Override
public final boolean mouseDragged( double x, double y, int button, double deltaX, double deltaY )
{

View File

@@ -10,6 +10,7 @@ import dan200.computercraft.ComputerCraft;
import dan200.computercraft.client.gui.widgets.WidgetTerminal;
import dan200.computercraft.shared.computer.core.ClientComputer;
import dan200.computercraft.shared.computer.inventory.ContainerComputerBase;
import net.minecraft.client.KeyMapping;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.inventory.MenuAccess;
@@ -44,8 +45,11 @@ public class NoTermComputerScreen<T extends ContainerComputerBase> extends Scree
protected void init()
{
passEvents = true; // Pass mouse vents through to the game's mouse handler.
// First ensure we're still grabbing the mouse, so the user can look around. Then reset bits of state that
// grabbing unsets.
minecraft.mouseHandler.grabMouse();
minecraft.screen = this;
KeyMapping.releaseAll();
super.init();
minecraft.keyboardHandler.setSendRepeatsToGui( true );

View File

@@ -71,12 +71,12 @@ public class DynamicImageButton extends Button
RenderSystem.disableDepthTest();
int yTex = yTexStart;
if( isHovered() ) yTex += yDiffTex;
if( isHoveredOrFocused() ) yTex += yDiffTex;
blit( stack, x, y, xTexStart.getAsInt(), yTex, width, height, textureWidth, textureHeight );
RenderSystem.enableDepthTest();
if( isHovered() ) renderToolTip( stack, mouseX, mouseY );
if( isHovered ) renderToolTip( stack, mouseX, mouseY );
}
@Nonnull

View File

@@ -45,8 +45,8 @@ public final class CableHighlightRenderer
{
BlockHitResult hit = event.getTarget();
BlockPos pos = hit.getBlockPos();
Level world = event.getInfo().getEntity().getCommandSenderWorld();
Camera info = event.getInfo();
Level world = event.getCamera().getEntity().getCommandSenderWorld();
Camera info = event.getCamera();
BlockState state = world.getBlockState( pos );
@@ -67,9 +67,9 @@ public final class CableHighlightRenderer
double yOffset = pos.getY() - cameraPos.y();
double zOffset = pos.getZ() - cameraPos.z();
VertexConsumer buffer = event.getBuffers().getBuffer( RenderType.lines() );
Matrix4f matrix4f = event.getMatrix().last().pose();
Matrix3f normal = event.getMatrix().last().normal();
VertexConsumer buffer = event.getMultiBufferSource().getBuffer( RenderType.lines() );
Matrix4f matrix4f = event.getPoseStack().last().pose();
Matrix3f normal = event.getPoseStack().last().normal();
// TODO: Can we just accesstransformer out LevelRenderer.renderShape?
shape.forAllEdges( ( x1, y1, z1, x2, y2, z2 ) -> {
float xDelta = (float) (x2 - x1);

View File

@@ -48,7 +48,7 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
event.setCanceled( true );
INSTANCE.renderItemFirstPerson(
event.getMatrixStack(), event.getBuffers(), event.getLight(),
event.getPoseStack(), event.getMultiBufferSource(), event.getPackedLight(),
event.getHand(), event.getInterpolatedPitch(), event.getEquipProgress(), event.getSwingProgress(), event.getItemStack()
);
}

View File

@@ -45,7 +45,7 @@ public final class ItemPrintoutRenderer extends ItemMapLikeRenderer
event.setCanceled( true );
INSTANCE.renderItemFirstPerson(
event.getMatrixStack(), event.getBuffers(), event.getLight(),
event.getPoseStack(), event.getMultiBufferSource(), event.getPackedLight(),
event.getHand(), event.getInterpolatedPitch(), event.getEquipProgress(), event.getSwingProgress(), event.getItemStack()
);
}
@@ -63,11 +63,11 @@ public final class ItemPrintoutRenderer extends ItemMapLikeRenderer
@SubscribeEvent
public static void onRenderInFrame( RenderItemInFrameEvent event )
{
ItemStack stack = event.getItem();
ItemStack stack = event.getItemStack();
if( !(stack.getItem() instanceof ItemPrintout) ) return;
event.setCanceled( true );
PoseStack transform = event.getMatrix();
PoseStack transform = event.getPoseStack();
// Move a little bit forward to ensure we're not clipping with the frame
transform.translate( 0.0f, 0.0f, -0.001f );
@@ -75,8 +75,8 @@ public final class ItemPrintoutRenderer extends ItemMapLikeRenderer
transform.scale( 0.95f, 0.95f, -0.95f );
transform.translate( -0.5f, -0.5f, 0.0f );
int light = event.getEntityItemFrame().getType() == EntityType.GLOW_ITEM_FRAME ? 0xf000d2 : event.getLight(); // See getLightVal.
drawPrintout( transform, event.getBuffers(), stack, light );
int light = event.getItemFrameEntity().getType() == EntityType.GLOW_ITEM_FRAME ? 0xf000d2 : event.getPackedLight(); // See getLightVal.
drawPrintout( transform, event.getMultiBufferSource(), stack, light );
}
private static void drawPrintout( PoseStack transform, MultiBufferSource render, ItemStack stack, int light )

View File

@@ -41,9 +41,9 @@ public final class MonitorHighlightRenderer
public static void drawHighlight( DrawSelectionEvent.HighlightBlock event )
{
// Preserve normal behaviour when crouching.
if( event.getInfo().getEntity().isCrouching() ) return;
if( event.getCamera().getEntity().isCrouching() ) return;
Level world = event.getInfo().getEntity().getCommandSenderWorld();
Level world = event.getCamera().getEntity().getCommandSenderWorld();
BlockPos pos = event.getTarget().getBlockPos();
BlockEntity tile = world.getBlockEntity( pos );
@@ -60,13 +60,13 @@ public final class MonitorHighlightRenderer
if( monitor.getYIndex() != 0 ) faces.remove( monitor.getDown().getOpposite() );
if( monitor.getYIndex() != monitor.getHeight() - 1 ) faces.remove( monitor.getDown() );
PoseStack transformStack = event.getMatrix();
Vec3 cameraPos = event.getInfo().getPosition();
PoseStack transformStack = event.getPoseStack();
Vec3 cameraPos = event.getCamera().getPosition();
transformStack.pushPose();
transformStack.translate( pos.getX() - cameraPos.x(), pos.getY() - cameraPos.y(), pos.getZ() - cameraPos.z() );
// I wish I could think of a better way to do this
VertexConsumer buffer = event.getBuffers().getBuffer( RenderType.lines() );
VertexConsumer buffer = event.getMultiBufferSource().getBuffer( RenderType.lines() );
Matrix4f transform = transformStack.last().pose();
Matrix3f normal = transformStack.last().normal();
if( faces.contains( NORTH ) || faces.contains( WEST ) ) line( buffer, transform, normal, 0, 0, 0, UP );

View File

@@ -130,8 +130,6 @@ public final class Generator<T>
private void addMethod( List<NamedMethod<T>> methods, Method method, LuaFunction annotation, PeripheralType genericType, T instance )
{
if( annotation.mainThread() ) instance = wrap.apply( instance );
String[] names = annotation.value();
boolean isSimple = method.getReturnType() != MethodResult.class && !annotation.mainThread();
if( names.length == 0 )
@@ -183,6 +181,13 @@ public final class Generator<T>
}
}
LuaFunction annotation = method.getAnnotation( LuaFunction.class );
if( annotation.unsafe() && annotation.mainThread() )
{
ComputerCraft.log.error( "Lua Method {} cannot use unsafe and mainThread", name );
return Optional.empty();
}
// We have some rather ugly handling of static methods in both here and the main generate function. Static methods
// only come from generic sources, so this should be safe.
Class<?> target = Modifier.isStatic( modifiers ) ? method.getParameterTypes()[0] : method.getDeclaringClass();
@@ -190,11 +195,13 @@ public final class Generator<T>
try
{
String className = method.getDeclaringClass().getName() + "$cc$" + method.getName() + METHOD_ID.getAndIncrement();
byte[] bytes = generate( className, target, method );
byte[] bytes = generate( className, target, method, annotation.unsafe() );
if( bytes == null ) return Optional.empty();
Class<?> klass = DeclaringClassLoader.INSTANCE.define( className, bytes, method.getDeclaringClass().getProtectionDomain() );
return Optional.of( klass.asSubclass( base ).getDeclaredConstructor().newInstance() );
T instance = klass.asSubclass( base ).getDeclaredConstructor().newInstance();
return Optional.of( annotation.mainThread() ? wrap.apply( instance ) : instance );
}
catch( ReflectiveOperationException | ClassFormatError | RuntimeException e )
{
@@ -205,7 +212,7 @@ public final class Generator<T>
}
@Nullable
private byte[] generate( String className, Class<?> target, Method method )
private byte[] generate( String className, Class<?> target, Method method, boolean unsafe )
{
String internalName = className.replace( ".", "/" );
@@ -238,7 +245,7 @@ public final class Generator<T>
int argIndex = 0;
for( java.lang.reflect.Type genericArg : method.getGenericParameterTypes() )
{
Boolean loadedArg = loadArg( mw, target, method, genericArg, argIndex );
Boolean loadedArg = loadArg( mw, target, method, unsafe, genericArg, argIndex );
if( loadedArg == null ) return null;
if( loadedArg ) argIndex++;
}
@@ -285,7 +292,7 @@ public final class Generator<T>
return cw.toByteArray();
}
private Boolean loadArg( MethodVisitor mw, Class<?> target, Method method, java.lang.reflect.Type genericArg, int argIndex )
private Boolean loadArg( MethodVisitor mw, Class<?> target, Method method, boolean unsafe, java.lang.reflect.Type genericArg, int argIndex )
{
if( genericArg == target )
{
@@ -324,7 +331,7 @@ public final class Generator<T>
return true;
}
String name = Reflect.getLuaName( Primitives.unwrap( klass ) );
String name = Reflect.getLuaName( Primitives.unwrap( klass ), unsafe );
if( name != null )
{
mw.visitVarInsn( ALOAD, 2 + context.size() );
@@ -344,7 +351,7 @@ public final class Generator<T>
return true;
}
String name = arg == Object.class ? "" : Reflect.getLuaName( arg );
String name = arg == Object.class ? "" : Reflect.getLuaName( arg, unsafe );
if( name != null )
{
if( Reflect.getRawType( method, genericArg, false ) == null ) return null;

View File

@@ -6,6 +6,7 @@
package dan200.computercraft.core.asm;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.lua.LuaTable;
import org.objectweb.asm.MethodVisitor;
import javax.annotation.Nullable;
@@ -25,7 +26,7 @@ final class Reflect
}
@Nullable
static String getLuaName( Class<?> klass )
static String getLuaName( Class<?> klass, boolean unsafe )
{
if( klass.isPrimitive() )
{
@@ -39,6 +40,7 @@ final class Reflect
if( klass == Map.class ) return "Table";
if( klass == String.class ) return "String";
if( klass == ByteBuffer.class ) return "Bytes";
if( klass == LuaTable.class && unsafe ) return "TableUnsafe";
}
return null;

View File

@@ -59,6 +59,10 @@ class BasicFunction extends VarArgFunction
}
throw new LuaError( "Java Exception Thrown: " + t, 0 );
}
finally
{
arguments.releaseImmediate();
}
if( results.getCallback() != null )
{

View File

@@ -15,6 +15,7 @@ import dan200.computercraft.core.tracking.Tracking;
import dan200.computercraft.core.tracking.TrackingField;
import dan200.computercraft.shared.util.ThreadUtils;
import org.squiddev.cobalt.*;
import org.squiddev.cobalt.LuaTable;
import org.squiddev.cobalt.compiler.CompileException;
import org.squiddev.cobalt.compiler.LoadState;
import org.squiddev.cobalt.debug.DebugFrame;

View File

@@ -69,6 +69,10 @@ class ResultInterpreterFunction extends ResumableVarArgFunction<ResultInterprete
}
throw new LuaError( "Java Exception Thrown: " + t, 0 );
}
finally
{
arguments.releaseImmediate();
}
ILuaCallback callback = results.getCallback();
Varargs ret = machine.toValues( results.getResult() );

View File

@@ -0,0 +1,141 @@
/*
* This file is part of ComputerCraft - http://www.computercraft.info
* Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
* Send enquiries to dratcliffe@gmail.com
*/
package dan200.computercraft.core.lua;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.lua.LuaValues;
import org.squiddev.cobalt.*;
import javax.annotation.Nonnull;
import java.util.*;
import static dan200.computercraft.api.lua.LuaValues.badTableItem;
import static dan200.computercraft.api.lua.LuaValues.getNumericType;
class TableImpl implements dan200.computercraft.api.lua.LuaTable<Object, Object>
{
private final VarargArguments arguments;
private final LuaTable table;
private Map<Object, Object> backingMap;
TableImpl( VarargArguments arguments, LuaTable table )
{
this.arguments = arguments;
this.table = table;
}
@Override
public int size()
{
checkValid();
try
{
return table.keyCount();
}
catch( LuaError e )
{
throw new IllegalStateException( e );
}
}
@Override
public int length()
{
return table.length();
}
@Override
public long getLong( int index ) throws LuaException
{
LuaValue value = table.rawget( index );
if( !(value instanceof LuaNumber) ) throw LuaValues.badTableItem( index, "number", value.typeName() );
if( value instanceof LuaInteger ) return value.toInteger();
double number = value.toDouble();
if( !Double.isFinite( number ) ) throw badTableItem( index, "number", getNumericType( number ) );
return (long) number;
}
@Override
public boolean isEmpty()
{
checkValid();
try
{
return table.next( Constants.NIL ).first().isNil();
}
catch( LuaError e )
{
throw new IllegalStateException( e );
}
}
@Nonnull
private LuaValue getImpl( Object o )
{
checkValid();
if( o instanceof String ) return table.rawget( (String) o );
if( o instanceof Integer ) return table.rawget( (Integer) o );
return Constants.NIL;
}
@Override
public boolean containsKey( Object o )
{
return !getImpl( o ).isNil();
}
@Override
public Object get( Object o )
{
return CobaltLuaMachine.toObject( getImpl( o ), null );
}
@Nonnull
private Map<Object, Object> getBackingMap()
{
checkValid();
if( backingMap != null ) return backingMap;
return backingMap = Collections.unmodifiableMap(
Objects.requireNonNull( (Map<?, ?>) CobaltLuaMachine.toObject( table, null ) )
);
}
@Override
public boolean containsValue( Object o )
{
return getBackingMap().containsKey( o );
}
@Nonnull
@Override
public Set<Object> keySet()
{
return getBackingMap().keySet();
}
@Nonnull
@Override
public Collection<Object> values()
{
return getBackingMap().values();
}
@Nonnull
@Override
public Set<Entry<Object, Object>> entrySet()
{
return getBackingMap().entrySet();
}
private void checkValid()
{
if( arguments.released )
{
throw new IllegalStateException( "Cannot use LuaTable after IArguments has been released" );
}
}
}

View File

@@ -19,6 +19,7 @@ class VarargArguments implements IArguments
{
static final IArguments EMPTY = new VarargArguments( Constants.NONE );
boolean released;
private final Varargs varargs;
private Object[] cache;
@@ -98,4 +99,39 @@ class VarargArguments implements IArguments
LuaString str = ((LuaBaseString) value).strvalue();
return Optional.of( ByteBuffer.wrap( str.bytes, str.offset, str.length ).asReadOnlyBuffer() );
}
@Nonnull
@Override
public dan200.computercraft.api.lua.LuaTable<?, ?> getTableUnsafe( int index ) throws LuaException
{
if( released )
{
throw new IllegalStateException( "Cannot use getTableUnsafe after IArguments has been released" );
}
LuaValue value = varargs.arg( index + 1 );
if( !(value instanceof LuaTable) ) throw LuaValues.badArgument( index, "table", value.typeName() );
return new TableImpl( this, (LuaTable) value );
}
@Nonnull
@Override
public Optional<dan200.computercraft.api.lua.LuaTable<?, ?>> optTableUnsafe( int index ) throws LuaException
{
if( released )
{
throw new IllegalStateException( "Cannot use optTableUnsafe after IArguments has been released" );
}
LuaValue value = varargs.arg( index + 1 );
if( value.isNil() ) return Optional.empty();
if( !(value instanceof LuaTable) ) throw LuaValues.badArgument( index, "table", value.typeName() );
return Optional.of( new TableImpl( this, (LuaTable) value ) );
}
@Override
public void releaseImmediate()
{
released = true;
}
}

View File

@@ -26,7 +26,7 @@ import net.minecraft.world.level.storage.loot.predicates.AlternativeLootItemCond
import net.minecraft.world.level.storage.loot.predicates.ExplosionCondition;
import net.minecraft.world.level.storage.loot.predicates.LootItemBlockStatePropertyCondition;
import net.minecraft.world.level.storage.loot.providers.number.ConstantValue;
import net.minecraftforge.fmllegacy.RegistryObject;
import net.minecraftforge.registries.RegistryObject;
import java.util.function.BiConsumer;

View File

@@ -28,11 +28,11 @@ import net.minecraft.world.level.storage.loot.entries.LootTableReference;
import net.minecraft.world.level.storage.loot.providers.number.ConstantValue;
import net.minecraftforge.event.*;
import net.minecraftforge.event.entity.player.PlayerContainerEvent;
import net.minecraftforge.event.server.ServerStartedEvent;
import net.minecraftforge.event.server.ServerStartingEvent;
import net.minecraftforge.event.server.ServerStoppedEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fmlserverevents.FMLServerStartedEvent;
import net.minecraftforge.fmlserverevents.FMLServerStartingEvent;
import net.minecraftforge.fmlserverevents.FMLServerStoppedEvent;
import java.util.Arrays;
import java.util.HashSet;
@@ -84,7 +84,7 @@ public final class CommonHooks
}
@SubscribeEvent
public static void onServerStarting( FMLServerStartingEvent event )
public static void onServerStarting( ServerStartingEvent event )
{
MinecraftServer server = event.getServer();
if( server instanceof DedicatedServer dediServer && dediServer.getProperties().enableJmxMonitoring )
@@ -94,7 +94,7 @@ public final class CommonHooks
}
@SubscribeEvent
public static void onServerStarted( FMLServerStartedEvent event )
public static void onServerStarted( ServerStartedEvent event )
{
ComputerCraft.serverComputerRegistry.reset();
WirelessNetwork.resetNetworks();
@@ -104,7 +104,7 @@ public final class CommonHooks
}
@SubscribeEvent
public static void onServerStopped( FMLServerStoppedEvent event )
public static void onServerStopped( ServerStoppedEvent event )
{
ComputerCraft.serverComputerRegistry.reset();
WirelessNetwork.resetNetworks();

View File

@@ -96,11 +96,11 @@ import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.fmllegacy.RegistryObject;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryBuilder;
import net.minecraftforge.registries.RegistryObject;
import java.util.function.BiFunction;

View File

@@ -13,7 +13,7 @@ import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.ClientChatEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fmllegacy.server.ServerLifecycleHooks;
import net.minecraftforge.server.ServerLifecycleHooks;
import java.io.File;

View File

@@ -19,7 +19,7 @@ import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraftforge.fmllegacy.RegistryObject;
import net.minecraftforge.registries.RegistryObject;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

View File

@@ -12,11 +12,11 @@ import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraftforge.common.util.Constants;
import javax.annotation.Nonnull;
@@ -36,7 +36,7 @@ public abstract class TileGeneric extends BlockEntity
setChanged();
BlockPos pos = getBlockPos();
BlockState state = getBlockState();
getLevel().sendBlockUpdated( pos, state, state, Constants.BlockFlags.DEFAULT );
getLevel().sendBlockUpdated( pos, state, state, Block.UPDATE_ALL );
}
@Nonnull
@@ -73,42 +73,15 @@ public abstract class TileGeneric extends BlockEntity
player.distanceToSqr( pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5 ) <= range * range;
}
protected void writeDescription( @Nonnull CompoundTag nbt )
{
}
protected void readDescription( @Nonnull CompoundTag nbt )
{
}
@Nonnull
@Override
public final ClientboundBlockEntityDataPacket getUpdatePacket()
{
CompoundTag nbt = new CompoundTag();
writeDescription( nbt );
return new ClientboundBlockEntityDataPacket( worldPosition, 0, nbt );
}
@Override
public final void onDataPacket( Connection net, ClientboundBlockEntityDataPacket packet )
{
if( packet.getType() == 0 ) readDescription( packet.getTag() );
}
@Nonnull
@Override
public CompoundTag getUpdateTag()
{
CompoundTag tag = super.getUpdateTag();
writeDescription( tag );
return tag;
var tag = packet.getTag();
if( tag != null ) handleUpdateTag( tag );
}
@Override
public void handleUpdateTag( @Nonnull CompoundTag tag )
{
super.handleUpdateTag( tag );
readDescription( tag );
}
}

View File

@@ -18,7 +18,7 @@ import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
import net.minecraft.world.level.block.state.properties.EnumProperty;
import net.minecraftforge.fmllegacy.RegistryObject;
import net.minecraftforge.registries.RegistryObject;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

View File

@@ -32,7 +32,7 @@ import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.fmllegacy.RegistryObject;
import net.minecraftforge.registries.RegistryObject;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -59,7 +59,7 @@ public abstract class BlockComputerBase<T extends TileComputerBase> extends Bloc
super.onPlace( state, world, pos, oldState, isMoving );
BlockEntity tile = world.getBlockEntity( pos );
if( tile instanceof TileComputerBase computer ) computer.updateInputsImmediately( );
if( tile instanceof TileComputerBase computer ) computer.updateInputsImmediately();
}
@Override
@@ -119,7 +119,7 @@ public abstract class BlockComputerBase<T extends TileComputerBase> extends Bloc
@Nonnull
@Override
public ItemStack getPickBlock( BlockState state, HitResult target, BlockGetter world, BlockPos pos, Player player )
public ItemStack getCloneItemStack( BlockState state, HitResult target, BlockGetter world, BlockPos pos, Player player )
{
BlockEntity tile = world.getBlockEntity( pos );
if( tile instanceof TileComputerBase )
@@ -128,7 +128,7 @@ public abstract class BlockComputerBase<T extends TileComputerBase> extends Bloc
if( !result.isEmpty() ) return result;
}
return super.getPickBlock( state, target, world, pos, player );
return super.getCloneItemStack( state, target, world, pos, player );
}
@Override

View File

@@ -24,6 +24,7 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.MenuProvider;
@@ -187,16 +188,15 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
protected abstract void updateBlockState( ComputerState newState );
@Nonnull
@Override
public CompoundTag save( @Nonnull CompoundTag nbt )
public void saveAdditional( @Nonnull CompoundTag nbt )
{
// Save ID, label and power state
if( computerID >= 0 ) nbt.putInt( NBT_ID, computerID );
if( label != null ) nbt.putString( NBT_LABEL, label );
nbt.putBoolean( NBT_ON, on );
return super.save( nbt );
super.saveAdditional( nbt );
}
@Override
@@ -383,18 +383,27 @@ public abstract class TileComputerBase extends TileGeneric implements IComputerT
// Networking stuff
@Nonnull
@Override
protected void writeDescription( @Nonnull CompoundTag nbt )
public final ClientboundBlockEntityDataPacket getUpdatePacket()
{
super.writeDescription( nbt );
return ClientboundBlockEntityDataPacket.create( this );
}
@Nonnull
@Override
public CompoundTag getUpdateTag()
{
// We need this for pick block on the client side.
CompoundTag nbt = super.getUpdateTag();
if( label != null ) nbt.putString( NBT_LABEL, label );
if( computerID >= 0 ) nbt.putInt( NBT_ID, computerID );
return nbt;
}
@Override
protected void readDescription( @Nonnull CompoundTag nbt )
public void handleUpdateTag( @Nonnull CompoundTag nbt )
{
super.readDescription( nbt );
label = nbt.contains( NBT_LABEL ) ? nbt.getString( NBT_LABEL ) : null;
computerID = nbt.contains( NBT_ID ) ? nbt.getInt( NBT_ID ) : -1;
}

View File

@@ -28,7 +28,7 @@ import net.minecraft.server.MinecraftServer;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.level.Level;
import net.minecraftforge.fmllegacy.server.ServerLifecycleHooks;
import net.minecraftforge.server.ServerLifecycleHooks;
import net.minecraftforge.versions.mcp.MCPVersion;
import javax.annotation.Nonnull;

View File

@@ -16,11 +16,11 @@ import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.fmllegacy.network.NetworkDirection;
import net.minecraftforge.fmllegacy.network.NetworkEvent;
import net.minecraftforge.fmllegacy.network.NetworkRegistry;
import net.minecraftforge.fmllegacy.network.PacketDistributor;
import net.minecraftforge.fmllegacy.network.simple.SimpleChannel;
import net.minecraftforge.network.NetworkDirection;
import net.minecraftforge.network.NetworkEvent;
import net.minecraftforge.network.NetworkRegistry;
import net.minecraftforge.network.PacketDistributor;
import net.minecraftforge.network.simple.SimpleChannel;
import java.util.function.Function;
import java.util.function.Supplier;

View File

@@ -6,7 +6,7 @@
package dan200.computercraft.shared.network;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.fmllegacy.network.NetworkEvent;
import net.minecraftforge.network.NetworkEvent;
import javax.annotation.Nonnull;

View File

@@ -10,7 +10,7 @@ import dan200.computercraft.shared.command.text.TableBuilder;
import dan200.computercraft.shared.network.NetworkMessage;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraftforge.fmllegacy.network.NetworkEvent;
import net.minecraftforge.network.NetworkEvent;
import javax.annotation.Nonnull;

View File

@@ -9,7 +9,7 @@ import dan200.computercraft.shared.computer.core.ComputerState;
import dan200.computercraft.shared.computer.core.ServerComputer;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.fmllegacy.network.NetworkEvent;
import net.minecraftforge.network.NetworkEvent;
import javax.annotation.Nonnull;

View File

@@ -7,7 +7,7 @@ package dan200.computercraft.shared.network.client;
import dan200.computercraft.ComputerCraft;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.fmllegacy.network.NetworkEvent;
import net.minecraftforge.network.NetworkEvent;
public class ComputerDeletedClientMessage extends ComputerClientMessage
{

View File

@@ -6,7 +6,7 @@
package dan200.computercraft.shared.network.client;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.fmllegacy.network.NetworkEvent;
import net.minecraftforge.network.NetworkEvent;
import javax.annotation.Nonnull;

View File

@@ -12,7 +12,7 @@ import net.minecraft.client.player.LocalPlayer;
import net.minecraft.core.BlockPos;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.fmllegacy.network.NetworkEvent;
import net.minecraftforge.network.NetworkEvent;
import javax.annotation.Nonnull;

View File

@@ -13,7 +13,7 @@ import net.minecraft.network.chat.TextComponent;
import net.minecraft.sounds.SoundEvent;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fmllegacy.network.NetworkEvent;
import net.minecraftforge.network.NetworkEvent;
import javax.annotation.Nonnull;

View File

@@ -11,7 +11,7 @@ import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fmllegacy.network.NetworkEvent;
import net.minecraftforge.network.NetworkEvent;
import javax.annotation.Nonnull;
import java.util.UUID;

View File

@@ -12,7 +12,7 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fmllegacy.network.NetworkEvent;
import net.minecraftforge.network.NetworkEvent;
import javax.annotation.Nonnull;
import java.util.UUID;

View File

@@ -10,7 +10,7 @@ import dan200.computercraft.shared.network.NetworkMessage;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fmllegacy.network.NetworkEvent;
import net.minecraftforge.network.NetworkEvent;
import javax.annotation.Nonnull;
import java.util.UUID;

View File

@@ -17,7 +17,7 @@ import dan200.computercraft.shared.UpgradeManager;
import dan200.computercraft.shared.network.NetworkMessage;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.fmllegacy.network.NetworkEvent;
import net.minecraftforge.network.NetworkEvent;
import net.minecraftforge.registries.IForgeRegistry;
import net.minecraftforge.registries.RegistryManager;

View File

@@ -13,7 +13,7 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraftforge.fmllegacy.network.NetworkEvent;
import net.minecraftforge.network.NetworkEvent;
import javax.annotation.Nonnull;

View File

@@ -12,16 +12,16 @@ import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.MenuType;
import net.minecraftforge.common.extensions.IForgeContainerType;
import net.minecraftforge.fmllegacy.network.IContainerFactory;
import net.minecraftforge.fmllegacy.network.NetworkHooks;
import net.minecraftforge.common.extensions.IForgeMenuType;
import net.minecraftforge.network.IContainerFactory;
import net.minecraftforge.network.NetworkHooks;
import javax.annotation.Nonnull;
import java.util.function.Consumer;
import java.util.function.Function;
/**
* An extension over the basic {@link IForgeContainerType}/{@link NetworkHooks#openGui(ServerPlayer, MenuProvider, Consumer)}
* An extension over the basic {@link IForgeMenuType}/{@link NetworkHooks#openGui(ServerPlayer, MenuProvider, Consumer)}
* hooks, with a more convenient way of reading and writing data.
*/
public interface ContainerData
@@ -35,7 +35,7 @@ public interface ContainerData
static <C extends AbstractContainerMenu, T extends ContainerData> MenuType<C> toType( Function<FriendlyByteBuf, T> reader, Factory<C, T> factory )
{
return IForgeContainerType.create( ( id, player, data ) -> factory.create( id, player, reader.apply( data ) ) );
return IForgeMenuType.create( ( id, player, data ) -> factory.create( id, player, reader.apply( data ) ) );
}
static <C extends AbstractContainerMenu, T extends ContainerData> MenuType<C> toType( Function<FriendlyByteBuf, T> reader, FixedFactory<C, T> factory )
@@ -60,7 +60,7 @@ public interface ContainerData
private FixedPointContainerFactory( Function<FriendlyByteBuf, T> reader, FixedFactory<C, T> factory )
{
MenuType<C> type = this.type = IForgeContainerType.create( this );
MenuType<C> type = this.type = IForgeMenuType.create( this );
impl = ( id, player, data ) -> factory.create( type, id, player, reader.apply( data ) );
}

View File

@@ -8,7 +8,7 @@ package dan200.computercraft.shared.network.server;
import dan200.computercraft.shared.computer.core.IContainerComputer;
import dan200.computercraft.shared.computer.core.ServerComputer;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.fmllegacy.network.NetworkEvent;
import net.minecraftforge.network.NetworkEvent;
import javax.annotation.Nonnull;

View File

@@ -10,7 +10,7 @@ import dan200.computercraft.shared.computer.core.IContainerComputer;
import dan200.computercraft.shared.computer.core.ServerComputer;
import dan200.computercraft.shared.network.NetworkMessage;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.fmllegacy.network.NetworkEvent;
import net.minecraftforge.network.NetworkEvent;
import javax.annotation.Nonnull;

View File

@@ -9,7 +9,7 @@ import dan200.computercraft.shared.computer.core.IContainerComputer;
import dan200.computercraft.shared.computer.core.ServerComputer;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.fmllegacy.network.NetworkEvent;
import net.minecraftforge.network.NetworkEvent;
import javax.annotation.Nonnull;

View File

@@ -9,7 +9,7 @@ import dan200.computercraft.shared.computer.core.IContainerComputer;
import dan200.computercraft.shared.computer.core.InputState;
import dan200.computercraft.shared.computer.core.ServerComputer;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.fmllegacy.network.NetworkEvent;
import net.minecraftforge.network.NetworkEvent;
import javax.annotation.Nonnull;

View File

@@ -9,7 +9,7 @@ import dan200.computercraft.shared.computer.core.IContainerComputer;
import dan200.computercraft.shared.computer.core.InputState;
import dan200.computercraft.shared.computer.core.ServerComputer;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.fmllegacy.network.NetworkEvent;
import net.minecraftforge.network.NetworkEvent;
import javax.annotation.Nonnull;

View File

@@ -10,7 +10,7 @@ import dan200.computercraft.shared.computer.core.ServerComputer;
import dan200.computercraft.shared.util.NBTUtil;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.fmllegacy.network.NetworkEvent;
import net.minecraftforge.network.NetworkEvent;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

View File

@@ -9,7 +9,7 @@ import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.computer.core.ServerComputer;
import dan200.computercraft.shared.network.NetworkMessage;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.fmllegacy.network.NetworkEvent;
import net.minecraftforge.network.NetworkEvent;
import javax.annotation.Nonnull;

View File

@@ -14,7 +14,7 @@ import dan200.computercraft.shared.network.NetworkHandler;
import io.netty.handler.codec.DecoderException;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.fmllegacy.network.NetworkEvent;
import net.minecraftforge.network.NetworkEvent;
import javax.annotation.Nonnull;
import java.nio.ByteBuffer;

View File

@@ -37,9 +37,9 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fmllegacy.network.NetworkHooks;
import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.wrapper.InvWrapper;
import net.minecraftforge.network.NetworkHooks;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -137,9 +137,8 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory
}
}
@Nonnull
@Override
public CompoundTag save( @Nonnull CompoundTag nbt )
public void saveAdditional( @Nonnull CompoundTag nbt )
{
if( customName != null ) nbt.putString( NBT_NAME, Component.Serializer.toJson( customName ) );
@@ -149,7 +148,7 @@ public final class TileDiskDrive extends TileGeneric implements DefaultInventory
diskStack.save( item );
nbt.put( NBT_ITEM, item );
}
return super.save( nbt );
super.saveAdditional( nbt );
}
void serverTick()

View File

@@ -60,9 +60,9 @@ public class ItemData
data.put( "maxDamage", stack.getMaxDamage() );
}
if( stack.getItem().showDurabilityBar( stack ) )
if( stack.getItem().isBarVisible( stack ) )
{
data.put( "durability", stack.getItem().getDurabilityForDisplay( stack ) );
data.put( "durability", stack.getItem().getBarWidth( stack ) / 13.0 );
}
data.put( "tags", DataHelpers.getTags( stack.getItem().getTags() ) );

View File

@@ -98,7 +98,7 @@ public class BlockCable extends BlockGeneric implements SimpleWaterloggedBlock
}
@Override
public boolean removedByPlayer( BlockState state, Level world, BlockPos pos, Player player, boolean willHarvest, FluidState fluid )
public boolean onDestroyedByPlayer( BlockState state, Level world, BlockPos pos, Player player, boolean willHarvest, FluidState fluid )
{
if( state.getValue( CABLE ) && state.getValue( MODEM ).getFacing() != null )
{
@@ -140,12 +140,12 @@ public class BlockCable extends BlockGeneric implements SimpleWaterloggedBlock
}
}
return super.removedByPlayer( state, world, pos, player, willHarvest, fluid );
return super.onDestroyedByPlayer( state, world, pos, player, willHarvest, fluid );
}
@Nonnull
@Override
public ItemStack getPickBlock( BlockState state, HitResult hit, BlockGetter world, BlockPos pos, Player player )
public ItemStack getCloneItemStack( BlockState state, HitResult hit, BlockGetter world, BlockPos pos, Player player )
{
Direction modem = state.getValue( MODEM ).getFacing();
boolean cable = state.getValue( CABLE );

View File

@@ -292,13 +292,12 @@ public class TileCable extends TileGeneric
peripheral.read( nbt, "" );
}
@Nonnull
@Override
public CompoundTag save( CompoundTag nbt )
public void saveAdditional( CompoundTag nbt )
{
nbt.putBoolean( NBT_PERIPHERAL_ENABLED, peripheralAccessAllowed );
peripheral.write( nbt, "" );
return super.save( nbt );
super.saveAdditional( nbt );
}
private void updateBlockState()
@@ -346,7 +345,7 @@ public class TileCable extends TileGeneric
for( Direction facing : DirectionUtil.FACINGS )
{
BlockPos offset = current.relative( facing );
if( !world.isAreaLoaded( offset, 0 ) ) continue;
if( !world.isLoaded( offset ) ) continue;
LazyOptional<IWiredElement> element = ComputerCraftAPI.getWiredElementAt( world, offset, facing.getOpposite() );
if( !element.isPresent() ) continue;

View File

@@ -241,13 +241,12 @@ public class TileWiredModemFull extends TileGeneric
for( int i = 0; i < peripherals.length; i++ ) peripherals[i].read( nbt, Integer.toString( i ) );
}
@Nonnull
@Override
public CompoundTag save( CompoundTag nbt )
public void saveAdditional( CompoundTag nbt )
{
nbt.putBoolean( NBT_PERIPHERAL_ENABLED, peripheralAccessAllowed );
for( int i = 0; i < peripherals.length; i++ ) peripherals[i].write( nbt, Integer.toString( i ) );
return super.save( nbt );
super.saveAdditional( nbt );
}
private void updateBlockState()
@@ -306,7 +305,7 @@ public class TileWiredModemFull extends TileGeneric
for( Direction facing : DirectionUtil.FACINGS )
{
BlockPos offset = current.relative( facing );
if( !world.isAreaLoaded( offset, 0 ) ) continue;
if( !world.isLoaded( offset ) ) continue;
LazyOptional<IWiredElement> element = ComputerCraftAPI.getWiredElementAt( world, offset, facing.getOpposite() );
if( !element.isPresent() ) continue;

View File

@@ -25,7 +25,7 @@ import net.minecraft.world.level.block.state.properties.DirectionProperty;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraftforge.fmllegacy.RegistryObject;
import net.minecraftforge.registries.RegistryObject;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

View File

@@ -21,7 +21,7 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
import net.minecraft.world.level.block.state.properties.EnumProperty;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.fmllegacy.RegistryObject;
import net.minecraftforge.registries.RegistryObject;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

View File

@@ -94,9 +94,12 @@ class Expander
if( !isPositive )
{
BlockEntity otherOrigin = level.getBlockEntity( otherMonitor.toWorldPos( 0, 0 ) );
if( otherOrigin == null || !origin.isCompatible( (TileMonitor) otherOrigin ) ) return false;
if( !(otherOrigin instanceof TileMonitor originMonitor) || !origin.isCompatible( originMonitor ) )
{
return false;
}
origin = (TileMonitor) otherOrigin;
origin = originMonitor;
}
this.width = width;

View File

@@ -101,7 +101,7 @@ public final class MonitorWatcher
if( !(world instanceof ServerLevel) ) continue;
LevelChunk chunk = world.getChunkAt( pos );
if( ((ServerLevel) world).getChunkSource().chunkMap.getPlayers( chunk.getPos(), false ).findAny().isEmpty() )
if( ((ServerLevel) world).getChunkSource().chunkMap.getPlayers( chunk.getPos(), false ).isEmpty() )
{
continue;
}

View File

@@ -17,6 +17,7 @@ import dan200.computercraft.shared.util.TickScheduler;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
@@ -126,15 +127,14 @@ public class TileMonitor extends TileGeneric
return InteractionResult.PASS;
}
@Nonnull
@Override
public CompoundTag save( CompoundTag tag )
public void saveAdditional( CompoundTag tag )
{
tag.putInt( NBT_X, xIndex );
tag.putInt( NBT_Y, yIndex );
tag.putInt( NBT_WIDTH, width );
tag.putInt( NBT_HEIGHT, height );
return super.save( tag );
super.saveAdditional( tag );
}
@Override
@@ -236,7 +236,6 @@ public class TileMonitor extends TileGeneric
{
// Otherwise fetch the origin and attempt to get its monitor
// Note this may load chunks, but we don't really have a choice here.
BlockPos pos = getBlockPos();
BlockEntity te = level.getBlockEntity( toWorldPos( 0, 0 ) );
if( !(te instanceof TileMonitor) ) return null;
@@ -249,7 +248,6 @@ public class TileMonitor extends TileGeneric
{
if( clientMonitor != null ) return clientMonitor;
BlockPos pos = getBlockPos();
BlockEntity te = level.getBlockEntity( toWorldPos( 0, 0 ) );
if( !(te instanceof TileMonitor) ) return null;
@@ -258,20 +256,29 @@ public class TileMonitor extends TileGeneric
// Networking stuff
@Nonnull
@Override
protected void writeDescription( @Nonnull CompoundTag nbt )
public final ClientboundBlockEntityDataPacket getUpdatePacket()
{
super.writeDescription( nbt );
return ClientboundBlockEntityDataPacket.create( this );
}
@Nonnull
@Override
public final CompoundTag getUpdateTag()
{
CompoundTag nbt = super.getUpdateTag();
nbt.putInt( NBT_X, xIndex );
nbt.putInt( NBT_Y, yIndex );
nbt.putInt( NBT_WIDTH, width );
nbt.putInt( NBT_HEIGHT, height );
return nbt;
}
@Override
protected final void readDescription( @Nonnull CompoundTag nbt )
public final void handleUpdateTag( @Nonnull CompoundTag nbt )
{
super.readDescription( nbt );
super.handleUpdateTag( nbt );
int oldXIndex = xIndex;
int oldYIndex = yIndex;
@@ -390,7 +397,7 @@ public class TileMonitor extends TileGeneric
BlockPos pos = toWorldPos( x, y );
Level world = getLevel();
if( world == null || !world.isAreaLoaded( pos, 0 ) ) return MonitorState.UNLOADED;
if( world == null || !world.isLoaded( pos ) ) return MonitorState.UNLOADED;
BlockEntity tile = world.getBlockEntity( pos );
if( !(tile instanceof TileMonitor monitor) ) return MonitorState.MISSING;

View File

@@ -31,10 +31,10 @@ import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fmllegacy.network.NetworkHooks;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.wrapper.InvWrapper;
import net.minecraftforge.items.wrapper.SidedInvWrapper;
import net.minecraftforge.network.NetworkHooks;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -113,9 +113,8 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
ContainerHelper.loadAllItems( nbt, inventory );
}
@Nonnull
@Override
public CompoundTag save( @Nonnull CompoundTag nbt )
public void saveAdditional( @Nonnull CompoundTag nbt )
{
if( customName != null ) nbt.putString( NBT_NAME, Component.Serializer.toJson( customName ) );
@@ -130,7 +129,7 @@ public final class TilePrinter extends TileGeneric implements DefaultSidedInvent
// Write inventory
ContainerHelper.saveAllItems( nbt, inventory );
return super.save( nbt );
super.saveAdditional( nbt );
}
boolean isPrinting()

View File

@@ -9,8 +9,7 @@ import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.shared.network.NetworkHandler;
import dan200.computercraft.shared.network.client.SpeakerStopClientMessage;
import net.minecraft.server.MinecraftServer;
import net.minecraftforge.fml.LogicalSide;
import net.minecraftforge.fmllegacy.LogicalSidedProvider;
import net.minecraftforge.server.ServerLifecycleHooks;
import javax.annotation.Nonnull;
import java.util.UUID;
@@ -34,7 +33,7 @@ public abstract class UpgradeSpeakerPeripheral extends SpeakerPeripheral
public void detach( @Nonnull IComputerAccess computer )
{
// We could be in the process of shutting down the server, so we can't send packets in this case.
MinecraftServer server = LogicalSidedProvider.INSTANCE.get( LogicalSide.SERVER );
MinecraftServer server = ServerLifecycleHooks.getCurrentServer();
if( server == null || server.isStopped() ) return;
NetworkHandler.sendToAllPlayers( new SpeakerStopClientMessage( source ) );

View File

@@ -42,7 +42,7 @@ import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraftforge.fmllegacy.RegistryObject;
import net.minecraftforge.registries.RegistryObject;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

View File

@@ -289,9 +289,8 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
brain.readFromNBT( nbt );
}
@Nonnull
@Override
public CompoundTag save( @Nonnull CompoundTag nbt )
public void saveAdditional( @Nonnull CompoundTag nbt )
{
// Write inventory
ListTag nbttaglist = new ListTag();
@@ -310,7 +309,7 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
// Write brain
nbt = brain.writeToNBT( nbt );
return super.save( nbt );
super.saveAdditional( nbt );
}
@Override
@@ -504,17 +503,19 @@ public class TileTurtle extends TileComputerBase implements ITurtleTile, Default
// Networking stuff
@Nonnull
@Override
protected void writeDescription( @Nonnull CompoundTag nbt )
public CompoundTag getUpdateTag()
{
super.writeDescription( nbt );
CompoundTag nbt = super.getUpdateTag();
brain.writeDescription( nbt );
return nbt;
}
@Override
protected void readDescription( @Nonnull CompoundTag nbt )
public void handleUpdateTag( @Nonnull CompoundTag nbt )
{
super.readDescription( nbt );
super.handleUpdateTag( nbt );
brain.readDescription( nbt );
}

View File

@@ -304,7 +304,7 @@ public class TurtleBrain implements ITurtleAccess
}
// Ensure the chunk is loaded
if( !world.isAreaLoaded( pos, 0 ) ) return false;
if( !world.isLoaded( pos ) ) return false;
// Ensure we're inside the world border
if( !world.getWorldBorder().isWithinBounds( pos ) ) return false;

View File

@@ -137,7 +137,7 @@ public class TurtleMoveCommand implements ITurtleCommand
return TurtleCommandResult.failure( "Cannot enter protected area" );
}
if( !world.isAreaLoaded( position, 0 ) ) return TurtleCommandResult.failure( "Cannot leave loaded world" );
if( !world.isLoaded( position ) ) return TurtleCommandResult.failure( "Cannot leave loaded world" );
if( !world.getWorldBorder().isWithinBounds( position ) )
{
return TurtleCommandResult.failure( "Cannot pass the world border" );

View File

@@ -27,13 +27,13 @@ import net.minecraft.world.item.*;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.SignBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.common.ForgeHooks;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.eventbus.api.Event.Result;
import net.minecraftforge.items.IItemHandler;
@@ -321,7 +321,7 @@ public class TurtlePlaceCommand implements ITurtleCommand
}
}
signTile.setChanged();
world.sendBlockUpdated( tile.getBlockPos(), tile.getBlockState(), tile.getBlockState(), Constants.BlockFlags.DEFAULT );
world.sendBlockUpdated( tile.getBlockPos(), tile.getBlockState(), tile.getBlockState(), Block.UPDATE_ALL );
}
private static class ErrorMessage

View File

@@ -17,7 +17,7 @@ import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.level.Level;
import net.minecraftforge.common.ForgeHooks;
import net.minecraftforge.fmllegacy.hooks.BasicEventHooks;
import net.minecraftforge.event.ForgeEventFactory;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -91,7 +91,7 @@ public class TurtleInventoryCrafting extends CraftingContainer
results.add( result );
result.onCraftedBy( world, player, result.getCount() );
BasicEventHooks.firePlayerCraftingEvent( player, result, this );
ForgeEventFactory.firePlayerCraftingEvent( player, result, this );
ForgeHooks.setCraftingPlayer( player );
NonNullList<ItemStack> remainders = recipe.getRemainingItems( this );

View File

@@ -255,7 +255,7 @@ public class TurtleTool extends AbstractTurtleUpgrade
// Destroy the block
boolean canHarvest = state.canHarvestBlock( world, blockPosition, turtlePlayer );
boolean canBreak = state.removedByPlayer( world, blockPosition, turtlePlayer, canHarvest, fluidState );
boolean canBreak = state.onDestroyedByPlayer( world, blockPosition, turtlePlayer, canHarvest, fluidState );
if( canBreak ) state.getBlock().destroy( world, blockPosition, state );
if( canHarvest && canBreak )
{

View File

@@ -11,7 +11,7 @@ import com.google.gson.reflect.TypeToken;
import dan200.computercraft.ComputerCraft;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.level.storage.LevelResource;
import net.minecraftforge.fmllegacy.server.ServerLifecycleHooks;
import net.minecraftforge.server.ServerLifecycleHooks;
import java.io.File;
import java.io.Reader;

View File

@@ -10,7 +10,8 @@ import dan200.computercraft.ComputerCraft;
import dan200.computercraft.shared.common.TileGeneric;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.TickList;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
@@ -21,7 +22,7 @@ import java.util.Iterator;
import java.util.Set;
/**
* A thread-safe version of {@link TickList#scheduleTick(BlockPos, Object, int)}.
* A thread-safe version of {@link LevelAccessor#scheduleTick(BlockPos, Block, int)}.
*
* We use this when modems and other peripherals change a block in a different thread.
*/
@@ -58,9 +59,9 @@ public final class TickScheduler
Level world = tile.getLevel();
BlockPos pos = tile.getBlockPos();
if( world != null && pos != null && world.isAreaLoaded( pos, 0 ) && world.getBlockEntity( pos ) == tile )
if( world != null && pos != null && world.isLoaded( pos ) && world.getBlockEntity( pos ) == tile )
{
world.getBlockTicks().scheduleTick( pos, tile.getBlockState().getBlock(), 0 );
world.scheduleTick( pos, tile.getBlockState().getBlock(), 0 );
}
}
}

View File

@@ -48,7 +48,7 @@ public final class WaterloggableHelpers
{
if( state.getValue( WATERLOGGED ) )
{
world.getLiquidTicks().scheduleTick( pos, Fluids.WATER, Fluids.WATER.getTickDelay( world ) );
world.scheduleTick( pos, Fluids.WATER, Fluids.WATER.getTickDelay( world ) );
}
}

View File

@@ -1,5 +1,5 @@
modLoader="javafml"
loaderVersion="[37,38)"
loaderVersion="[39,40)"
issueTrackerURL="https://github.com/cc-tweaked/CC-Tweaked/issues"
logoFile="pack.png"
@@ -21,6 +21,6 @@ CC: Tweaked is a fork of ComputerCraft, adding programmable computers, turtles a
[[dependencies.computercraft]]
modId="forge"
mandatory=true
versionRange="[37.0.85,38)"
versionRange="[39.0.0,40)"
ordering="NONE"
side="BOTH"

View File

@@ -28,9 +28,11 @@ Once you have the name of a peripheral, you can call functions on it using the
@{peripheral.call} function. This takes the name of our peripheral, the name of
the function we want to call, and then its arguments.
> Some bits of the peripheral API call peripheral functions *methods* instead
> (for example, the @{peripheral.getMethods} function). Don't worry, they're the
> same thing!
:::info
Some bits of the peripheral API call peripheral functions *methods* instead
(for example, the @{peripheral.getMethods} function). Don't worry, they're the
same thing!
:::
Let's say we have a monitor above our computer (and so "top") and want to
@{monitor.write|write some text to it}. We'd write the following:

View File

@@ -1,3 +1,14 @@
# New features in CC: Tweaked 1.99.1
* Add package.searchpath to the cc.require API. (MCJack123)
* Provide a more efficient way for the Java API to consume Lua tables in certain restricted cases.
Several bug fixes:
* Fix keys being "sticky" when opening the off-hand pocket computer GUI.
* Correctly handle broken coroutine managers resuming Java code with a `nil` event.
* Prevent computer buttons stealing focus from the terminal.
* Fix a class cast exception when a monitor is malformed in ways I do not quite understand.
# New features in CC: Tweaked 1.99.0
* Pocket computers in their offhand will open without showing a terminal. You can look around and interact with the world, but your keyboard will be forwarded to the computer. (Wojbie, MagGen-hub).

View File

@@ -1,32 +1,12 @@
New features in CC: Tweaked 1.99.0
New features in CC: Tweaked 1.99.1
* Pocket computers in their offhand will open without showing a terminal. You can look around and interact with the world, but your keyboard will be forwarded to the computer. (Wojbie, MagGen-hub).
* Peripherals can now have multiple types. `peripheral.getType` now returns multiple values, and `peripheral.hasType` checks if a peripheral has a specific type.
* Add several missing keys to the `keys` table. (ralphgod3)
* Add feature introduction/changed version information to the documentation. (MCJack123)
* Increase the file upload limit to 512KiB.
* Rednet can now handle computer IDs larger than 65535. (Ale32bit)
* Optimise deduplication of rednet messages (MCJack123)
* Make `term.blit` colours case insensitive. (Ocawesome101)
* Add a new `about` program for easier version identification. (MCJack123)
* Optimise peripheral calls in `rednet.run`. (xAnavrins)
* Add dimension parameter to `commands.getBlockInfo`.
* Add `cc.pretty.pretty_print` helper function (Lupus590).
* Add back JEI integration.
* Turtle and pocket computer upgrades can now be added and modified with data packs.
* Various translation updates (MORIMORI3017, Ale2Bit, mindy15963)
* Add package.searchpath to the cc.require API. (MCJack123)
* Provide a more efficient way for the Java API to consume Lua tables in certain restricted cases.
And several bug fixes:
* Fix various computer commands failing when OP level was 4.
* Various documentation fixes. (xXTurnerLP, MCJack123)
* Fix `textutils.serialize` not serialising infinity and nan values. (Wojbie)
* Wired modems now correctly clean up mounts when a peripheral is detached.
* Fix incorrect turtle and pocket computer upgrade recipes in the recipe book.
* Fix speakers not playing sounds added via resource packs which are not registered in-game.
* Fix speaker upgrades sending packets after the server has stopped.
* Monitor sizing has been rewritten, hopefully making it more stable.
* Peripherals are now invalidated when the computer ticks, rather than when the peripheral changes.
* Fix printouts and pocket computers rendering at fullbright when in item frames.
* All mod blocks now have an effective tool (pickaxe).
Several bug fixes:
* Fix keys being "sticky" when opening the off-hand pocket computer GUI.
* Correctly handle broken coroutine managers resuming Java code with a `nil` event.
* Prevent computer buttons stealing focus from the terminal.
* Fix a class cast exception when a monitor is malformed in ways I do not quite understand.
Type "help changelog" to see the full version history.

View File

@@ -31,22 +31,37 @@ local function preload(package)
end
end
local function from_file(package, env, dir)
local function from_file(package, env)
return function(name)
local fname = string.gsub(name, "%.", "/")
local sPath, sError = package.searchpath(name, package.path)
if not sPath then
return nil, sError
end
local fnFile, sError = loadfile(sPath, nil, env)
if fnFile then
return fnFile, sPath
else
return nil, sError
end
end
end
local function make_searchpath(dir)
return function(name, path, sep, rep)
expect(1, name, "string")
expect(2, path, "string")
sep = expect(3, sep, "string", "nil") or "."
rep = expect(4, rep, "string", "nil") or "/"
local fname = string.gsub(name, sep:gsub("%.", "%%%."), rep)
local sError = ""
for pattern in string.gmatch(package.path, "[^;]+") do
for pattern in string.gmatch(path, "[^;]+") do
local sPath = string.gsub(pattern, "%?", fname)
if sPath:sub(1, 1) ~= "/" then
sPath = fs.combine(dir, sPath)
end
if fs.exists(sPath) and not fs.isDir(sPath) then
local fnFile, sError = loadfile(sPath, nil, env)
if fnFile then
return fnFile, sPath
else
return nil, sError
end
return sPath
else
if #sError > 0 then
sError = sError .. "\n "
@@ -118,7 +133,8 @@ local function make_package(env, dir)
end
package.config = "/\n;\n?\n!\n-"
package.preload = {}
package.loaders = { preload(package), from_file(package, env, dir) }
package.loaders = { preload(package), from_file(package, env) }
package.searchpath = make_searchpath(dir)
return make_require(package), package
end

View File

@@ -97,7 +97,7 @@ public class ComputerTestDelegate
if( REPORT_PATH.delete() ) ComputerCraft.log.info( "Deleted previous coverage report." );
Terminal term = new Terminal( 80, 30 );
Terminal term = new Terminal( 80, 100 );
IWritableMount mount = new FileMount( new File( "test-files/mount" ), 10_000_000 );
// Remove any existing files

View File

@@ -120,6 +120,13 @@ public class GeneratorTest
contramap( notNullValue(), "callback", MethodResult::getCallback ) );
}
@Test
public void testUnsafe()
{
List<NamedMethod<LuaMethod>> methods = LuaMethod.GENERATOR.getMethods( Unsafe.class );
assertThat( methods, contains( named( "withUnsafe" ) ) );
}
public static class Basic
{
@LuaFunction
@@ -222,6 +229,21 @@ public class GeneratorTest
{}
}
public static class Unsafe
{
@LuaFunction( unsafe = true )
public final void withUnsafe( LuaTable<?, ?> table )
{}
@LuaFunction
public final void withoutUnsafe( LuaTable<?, ?> table )
{}
@LuaFunction( unsafe = true, mainThread = true )
public final void invalid( LuaTable<?, ?> table )
{}
}
private static <T> T find( Collection<NamedMethod<T>> methods, String name )
{
return methods.stream()

View File

@@ -27,7 +27,7 @@ import net.minecraft.world.level.levelgen.WorldGenSettings;
import net.minecraft.world.level.levelgen.flat.FlatLayerInfo;
import net.minecraft.world.level.levelgen.flat.FlatLevelGeneratorSettings;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.GuiScreenEvent;
import net.minecraftforge.client.event.ScreenEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import org.apache.logging.log4j.LogManager;
@@ -50,9 +50,9 @@ public final class ClientHooks
}
@SubscribeEvent
public static void onGuiInit( GuiScreenEvent.InitGuiEvent event )
public static void onGuiInit( ScreenEvent.InitScreenEvent event )
{
if( triggered || !(event.getGui() instanceof TitleScreen) ) return;
if( triggered || !(event.getScreen() instanceof TitleScreen) ) return;
triggered = true;
ClientHooks.openWorld();
@@ -93,7 +93,7 @@ public final class ClientHooks
WorldGenSettings generator = new WorldGenSettings( 0, false, false, withOverworld(
dimensions,
DimensionType.defaultDimensions( dimensions, biomes, registries.registryOrThrow( Registry.NOISE_GENERATOR_SETTINGS_REGISTRY ), 0 ),
DimensionType.defaultDimensions( registries, 0 ),
new FlatLevelSource( flatSettings )
) );

View File

@@ -5,9 +5,9 @@
*/
package dan200.computercraft.ingame.mod;
import dan200.computercraft.ingame.api.Times;
import net.minecraft.ChatFormatting;
import net.minecraft.SharedConstants;
import dan200.computercraft.ingame.api.Times;
import net.minecraft.client.Minecraft;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.core.BlockPos;
@@ -21,11 +21,11 @@ import net.minecraft.world.level.block.Rotation;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraftforge.event.RegisterCommandsEvent;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.event.server.ServerStartedEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.loading.FMLLoader;
import net.minecraftforge.fmllegacy.server.ServerLifecycleHooks;
import net.minecraftforge.fmlserverevents.FMLServerStartedEvent;
import net.minecraftforge.server.ServerLifecycleHooks;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -49,7 +49,7 @@ public class TestHooks
}
@SubscribeEvent
public static void onServerStarted( FMLServerStartedEvent event )
public static void onServerStarted( ServerStartedEvent event )
{
MinecraftServer server = event.getServer();
GameRules rules = server.getGameRules();