Merge branch 1.12.1-dev into 1.12.2-dev
db1717fMerge branch 1.12-dev into 1.12.1-devd7dc2baMerge branch 1.11.2-dev into 1.12-devb1c6098Merge branch 1.11-dev into 1.11.2-devcaf6051Merge branch 1.9.4-dev into 1.11-dev263e080Merge branch 1.8.9-dev into 1.9.4-dev8fad02cMerge branch 1.8-dev into 1.8.9-dev1c888aaAdd minVersion to mixin configs and bump bundled mixin version10ce71eFix mapwriter crash when opening replay for <MC1.12 (fixes #96)5fb1cf3Fix half-despawned player entities (see #93) when the entity is moved greater distancesadfe6a2Fix NPE when spectated non-player entity despawns (fixes #94)b27af27Fix player entities being half-despawned after jumping in time (fixes #93)
This commit is contained in:
@@ -59,9 +59,7 @@ configurations {
|
|||||||
dependencies {
|
dependencies {
|
||||||
compile 'org.projectlombok:lombok:1.16.4'
|
compile 'org.projectlombok:lombok:1.16.4'
|
||||||
|
|
||||||
compile('org.spongepowered:mixin:0.6.11-SNAPSHOT') {
|
compile 'org.spongepowered:mixin:0.7.5-SNAPSHOT'
|
||||||
exclude group: 'org.apache.logging.log4j'
|
|
||||||
}
|
|
||||||
shade 'com.googlecode.mp4parser:isoparser:1.1.7'
|
shade 'com.googlecode.mp4parser:isoparser:1.1.7'
|
||||||
shade 'org.apache.commons:commons-exec:1.3'
|
shade 'org.apache.commons:commons-exec:1.3'
|
||||||
shade 'com.google.apis:google-api-services-youtube:v3-rev178-1.22.0'
|
shade 'com.google.apis:google-api-services-youtube:v3-rev178-1.22.0'
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.replaymod.compat.mapwriter.mixin;
|
||||||
|
|
||||||
|
import com.replaymod.replay.ReplayModReplay;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.multiplayer.ServerData;
|
||||||
|
import net.minecraftforge.fml.common.Loader;
|
||||||
|
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.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Approximately this for <1.12: https://github.com/Vectron/mapwriter/commit/68234520c7a3a0ae8201a085d7e66369900586ac
|
||||||
|
*/
|
||||||
|
@Mixin(Minecraft.class)
|
||||||
|
public abstract class MixinMinecraft {
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
private ServerData currentServerData;
|
||||||
|
|
||||||
|
@Inject(method = "getCurrentServerData", cancellable = true, at = @At("HEAD"))
|
||||||
|
private void replayModCompat_fixBug96(CallbackInfoReturnable<ServerData> ci) {
|
||||||
|
if (currentServerData == null
|
||||||
|
&& (Loader.isModLoaded("mapwriter") || Loader.isModLoaded("MapWriter"))
|
||||||
|
&& ReplayModReplay.instance.getReplayHandler() != null) {
|
||||||
|
for (StackTraceElement elem : Thread.currentThread().getStackTrace()) {
|
||||||
|
if ("mapwriter.util.Utils".equals(elem.getClassName()) && "getWorldName".equals(elem.getMethodName())) {
|
||||||
|
ci.setReturnValue(new ServerData(null, "replay", false));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,6 +19,7 @@ public class LoadingPlugin implements IFMLLoadingPlugin {
|
|||||||
Mixins.addConfiguration("mixins.recording.replaymod.json");
|
Mixins.addConfiguration("mixins.recording.replaymod.json");
|
||||||
Mixins.addConfiguration("mixins.render.replaymod.json");
|
Mixins.addConfiguration("mixins.render.replaymod.json");
|
||||||
Mixins.addConfiguration("mixins.replay.replaymod.json");
|
Mixins.addConfiguration("mixins.replay.replaymod.json");
|
||||||
|
Mixins.addConfiguration("mixins.compat.mapwriter.replaymod.json");
|
||||||
Mixins.addConfiguration("mixins.compat.shaders.replaymod.json");
|
Mixins.addConfiguration("mixins.compat.shaders.replaymod.json");
|
||||||
Mixins.addConfiguration("mixins.extras.playeroverview.replaymod.json");
|
Mixins.addConfiguration("mixins.extras.playeroverview.replaymod.json");
|
||||||
|
|
||||||
|
|||||||
@@ -22,11 +22,15 @@ import net.minecraft.entity.Entity;
|
|||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.network.*;
|
import net.minecraft.network.*;
|
||||||
import net.minecraft.network.play.server.*;
|
import net.minecraft.network.play.server.*;
|
||||||
|
import net.minecraft.util.ClassInheritanceMultiMap;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.text.ITextComponent;
|
import net.minecraft.util.text.ITextComponent;
|
||||||
import net.minecraft.world.EnumDifficulty;
|
import net.minecraft.world.EnumDifficulty;
|
||||||
import net.minecraft.world.GameType;
|
import net.minecraft.world.GameType;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.WorldType;
|
import net.minecraft.world.WorldType;
|
||||||
|
import net.minecraft.world.chunk.Chunk;
|
||||||
|
import net.minecraft.world.chunk.IChunkProvider;
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
||||||
@@ -34,6 +38,7 @@ import org.apache.commons.io.FileUtils;
|
|||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -820,6 +825,50 @@ public class ReplaySender extends ChannelDuplexHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Packet processPacketSync(Packet p) {
|
protected Packet processPacketSync(Packet p) {
|
||||||
|
if (p instanceof SPacketUnloadChunk) {
|
||||||
|
SPacketUnloadChunk packet = (SPacketUnloadChunk) p;
|
||||||
|
// If the chunk is getting unloaded, we will have to forcefully update the position of all entities
|
||||||
|
// within. Otherwise, if there wasn't a game tick recently, there may be entities that have moved
|
||||||
|
// out of the chunk by now but are still registered in it. If we do not update those, they will get
|
||||||
|
// unloaded even though they shouldn't.
|
||||||
|
// To make things worse, it seems like players were never supposed to be unloaded this way because
|
||||||
|
// they will remain glitched in the World#playerEntities list.
|
||||||
|
World world = mc.world;
|
||||||
|
IChunkProvider chunkProvider = world.getChunkProvider();
|
||||||
|
// Get the chunk that will be unloaded
|
||||||
|
Chunk chunk = chunkProvider.provideChunk(packet.getX(), packet.getZ());
|
||||||
|
if (!chunk.isEmpty()) {
|
||||||
|
List<Entity> entitiesInChunk = new ArrayList<>();
|
||||||
|
// Gather all entities in that chunk
|
||||||
|
for (ClassInheritanceMultiMap<Entity> entityList : chunk.getEntityLists()) {
|
||||||
|
entitiesInChunk.addAll(entityList);
|
||||||
|
}
|
||||||
|
for (Entity entity : entitiesInChunk) {
|
||||||
|
// Skip interpolation of position updates coming from server
|
||||||
|
// (See: newX in EntityLivingBase or otherPlayerMPX in EntityOtherPlayerMP)
|
||||||
|
// Needs to be called at least 4 times thanks to
|
||||||
|
// EntityOtherPlayerMP#otherPlayerMPPosRotationIncrements (max vanilla value is 3)
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
entity.onUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check whether the entity has left the chunk
|
||||||
|
int chunkX = MathHelper.floor(entity.posX / 16);
|
||||||
|
int chunkZ = MathHelper.floor(entity.posZ / 16);
|
||||||
|
if (entity.chunkCoordX != chunkX || entity.chunkCoordZ != chunkZ) {
|
||||||
|
// Entity has left the chunk
|
||||||
|
chunk.removeEntityAtIndex(entity, entity.chunkCoordY);
|
||||||
|
Chunk newChunk = chunkProvider.getLoadedChunk(chunkX, chunkZ);
|
||||||
|
if (newChunk != null) {
|
||||||
|
newChunk.addEntity(entity);
|
||||||
|
} else {
|
||||||
|
// Entity has left all loaded chunks
|
||||||
|
entity.addedToChunk = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return p; // During synchronous playback everything is sent normally
|
return p; // During synchronous playback everything is sent normally
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -161,6 +161,11 @@ public class CameraEntity extends EntityPlayerSP {
|
|||||||
if (spectating != null && (view.getUniqueID() != spectating
|
if (spectating != null && (view.getUniqueID() != spectating
|
||||||
|| view.world != world)
|
|| view.world != world)
|
||||||
|| world.getEntityByID(view.getEntityId()) != view) {
|
|| world.getEntityByID(view.getEntityId()) != view) {
|
||||||
|
if (spectating == null) {
|
||||||
|
// Entity (non-player) died, stop spectating
|
||||||
|
ReplayModReplay.instance.getReplayHandler().spectateEntity(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
view = world.getPlayerEntityByUUID(spectating);
|
view = world.getPlayerEntityByUUID(spectating);
|
||||||
if (view != null) {
|
if (view != null) {
|
||||||
mc.setRenderViewEntity(view);
|
mc.setRenderViewEntity(view);
|
||||||
|
|||||||
12
src/main/resources/mixins.compat.mapwriter.replaymod.json
Normal file
12
src/main/resources/mixins.compat.mapwriter.replaymod.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"required": false,
|
||||||
|
"package": "com.replaymod.compat.mapwriter.mixin",
|
||||||
|
"mixins": [],
|
||||||
|
"server": [],
|
||||||
|
"client": [
|
||||||
|
"MixinMinecraft"
|
||||||
|
],
|
||||||
|
"compatibilityLevel": "JAVA_8",
|
||||||
|
"minVersion": "0.6.11",
|
||||||
|
"refmap": "mixins.replaymod.refmap.json"
|
||||||
|
}
|
||||||
@@ -10,5 +10,6 @@
|
|||||||
"MixinShadersRender"
|
"MixinShadersRender"
|
||||||
],
|
],
|
||||||
"compatibilityLevel": "JAVA_8",
|
"compatibilityLevel": "JAVA_8",
|
||||||
|
"minVersion": "0.6.11",
|
||||||
"refmap": "mixins.replaymod.refmap.json"
|
"refmap": "mixins.replaymod.refmap.json"
|
||||||
}
|
}
|
||||||
@@ -7,5 +7,6 @@
|
|||||||
"MixinRender"
|
"MixinRender"
|
||||||
],
|
],
|
||||||
"compatibilityLevel": "JAVA_8",
|
"compatibilityLevel": "JAVA_8",
|
||||||
|
"minVersion": "0.6.11",
|
||||||
"refmap": "mixins.replaymod.refmap.json"
|
"refmap": "mixins.replaymod.refmap.json"
|
||||||
}
|
}
|
||||||
@@ -12,5 +12,6 @@
|
|||||||
"MixinWorldClient"
|
"MixinWorldClient"
|
||||||
],
|
],
|
||||||
"compatibilityLevel": "JAVA_8",
|
"compatibilityLevel": "JAVA_8",
|
||||||
|
"minVersion": "0.6.11",
|
||||||
"refmap": "mixins.replaymod.refmap.json"
|
"refmap": "mixins.replaymod.refmap.json"
|
||||||
}
|
}
|
||||||
@@ -12,5 +12,6 @@
|
|||||||
"server": [],
|
"server": [],
|
||||||
"client": [],
|
"client": [],
|
||||||
"compatibilityLevel": "JAVA_8",
|
"compatibilityLevel": "JAVA_8",
|
||||||
|
"minVersion": "0.6.11",
|
||||||
"refmap": "mixins.replaymod.refmap.json"
|
"refmap": "mixins.replaymod.refmap.json"
|
||||||
}
|
}
|
||||||
@@ -16,5 +16,6 @@
|
|||||||
"server": [],
|
"server": [],
|
||||||
"client": [],
|
"client": [],
|
||||||
"compatibilityLevel": "JAVA_8",
|
"compatibilityLevel": "JAVA_8",
|
||||||
|
"minVersion": "0.6.11",
|
||||||
"refmap": "mixins.replaymod.refmap.json"
|
"refmap": "mixins.replaymod.refmap.json"
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user