Skip to content

Commit

Permalink
use another way to change recording view distance
Browse files Browse the repository at this point in the history
  • Loading branch information
Hadron67 committed Aug 9, 2020
1 parent 25d3323 commit 3ab4777
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 64 deletions.
3 changes: 2 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def shadeExclusions = {
}

shadowJar {
// XXX: exclude a lot of things by hand...
from project.configurations.shade
configurations = [
project.configurations.shade
Expand Down Expand Up @@ -51,7 +52,7 @@ dependencies {
// PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs.
// You may need to force-disable transitiveness on them.

shade "com.github.ReplayMod.ReplayStudio:${project.minecraft_version}:be6a680", shadeExclusions
shade "com.github.ReplayMod.ReplayStudio:${project.minecraft_version}:${project.replaystudio_commit}", shadeExclusions
compileOnly "com.google.code.gson:gson:2.8.6"
}

Expand Down
3 changes: 2 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ org.gradle.jvmargs=-Xmx1G
loader_version=0.9.0+build.204

# Mod Properties
mod_version = 0.2.1
mod_version = 0.2.2
maven_group = test
archives_base_name = sreplay

# Dependencies
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
#fabric_version=0.3.0-pre+build.166
replaystudio_commit = be6a680
39 changes: 24 additions & 15 deletions src/main/java/com/hadroncfy/sreplay/SReplayMod.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.util.List;

import com.google.gson.JsonParseException;
import com.hadroncfy.sreplay.asm.MultipleOrdinalFieldInjectionPoint;
import com.hadroncfy.sreplay.command.SReplayCommand;
import com.hadroncfy.sreplay.config.Config;
import com.hadroncfy.sreplay.config.Formats;
Expand All @@ -26,6 +27,7 @@

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.spongepowered.asm.mixin.injection.InjectionPoint;

public class SReplayMod implements ModInitializer {

Expand All @@ -35,15 +37,15 @@ public class SReplayMod implements ModInitializer {

public static final SReplayCommand SREPLAY_COMMAND = new SReplayCommand();

public static Photographer getFake(MinecraftServer server, String name){
public static Photographer getFake(MinecraftServer server, String name) {
ServerPlayerEntity player = server.getPlayerManager().getPlayer(name);
if (player != null && player instanceof Photographer){
if (player != null && player instanceof Photographer) {
return (Photographer) player;
}
return null;
}

public static Server getServer(){
public static Server getServer() {
return downloadServer;
}

Expand All @@ -55,50 +57,57 @@ public static List<File> listRecordings() {

public static void loadConfig() throws IOException, JsonParseException {
File dir = new File("config");
if (!dir.exists()){
if (!dir.exists()) {
dir.mkdirs();
}
File file = new File(dir, "sreplay.json");
if (file.exists()){
try (Reader reader = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)){
if (file.exists()) {
try (Reader reader = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)) {
config = Config.GSON.fromJson(reader, Config.class);
}
}
else {
} else {
config = new Config();
}
try (Writer writer = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8)){
try (Writer writer = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8)) {
writer.write(Config.GSON.toJson(config));
}
}

public static Config getConfig(){
public static Config getConfig() {
return config;
}

public static Formats getFormats(){
public static Formats getFormats() {
return config.formats;
}

@Override
public void onInitialize() {
InjectionPoint.register(MultipleOrdinalFieldInjectionPoint.class);

try {
SReplayMod.loadConfig();
Lang.load("zh_cn");
LOGGER.info("SReplay: Initialzed");
}
catch(Throwable e) {
} catch (Throwable e) {
LOGGER.error("Exception initializing mod: " + e);
e.printStackTrace();
}

if (config == null){
if (config == null) {
config = new Config();
}

if (!config.savePath.exists()){
if (!config.savePath.exists()) {
config.savePath.mkdirs();
}

try {
LOGGER.info("!!!! test: {}",
Class.forName("com.hadroncfy.sreplay.asm.MultipleOrdinalFieldInjectionPoint").getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.hadroncfy.sreplay.asm;

import java.util.HashSet;
import java.util.Set;

import org.spongepowered.asm.mixin.injection.InjectionPoint.AtCode;
import org.spongepowered.asm.mixin.injection.points.BeforeFieldAccess;
import org.spongepowered.asm.mixin.injection.struct.InjectionPointData;

@AtCode("sreplay_MultipleOrdinalField")
public class MultipleOrdinalFieldInjectionPoint extends BeforeFieldAccess {
private final Set<Integer> ordinals = new HashSet<>();

public MultipleOrdinalFieldInjectionPoint(InjectionPointData data) {
super(data);
for (String part: data.get("ordinals", "").split(",")){
part = part.trim();
try {
if (part.indexOf("..") != -1){
String[] s = part.split("\\.\\.");
for (int i = Integer.parseInt(s[0]); i <= Integer.parseInt(s[1]); i++){
ordinals.add(i);
}
}
else {
ordinals.add(Integer.parseInt(part));
}
} catch(NumberFormatException e){
}
}
}

@Override
protected boolean matchesOrdinal(int ordinal) {
return ordinals.contains(ordinal);
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
package com.hadroncfy.sreplay.mixin;

import java.util.function.Predicate;
import java.util.stream.Stream;

import com.hadroncfy.sreplay.interfaces.IChunkSender;
import com.hadroncfy.sreplay.recording.Photographer;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
Expand All @@ -16,40 +12,57 @@
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ThreadedAnvilChunkStorage;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.chunk.WorldChunk;

import static com.hadroncfy.sreplay.recording.Photographer.getRealViewDistance;

@Mixin(ThreadedAnvilChunkStorage.class)
public abstract class MixinThreadedAnvilChunkStorage implements IChunkSender {
private static final Logger LOGGER = LogManager.getLogger();
public abstract class MixinThreadedAnvilChunkStorage {
@Shadow private int watchDistance;

@Shadow
private static int getChebyshevDistance(ChunkPos pos, ServerPlayerEntity player, boolean useCameraPosition){ return 0; }

@Shadow
abstract void sendChunkDataPackets(ServerPlayerEntity player, Packet<?>[] packets, WorldChunk chunk);
@Redirect(method = "method_18707", at = @At(
value = "FIELD",
target = "Lnet/minecraft/server/world/ThreadedAnvilChunkStorage;watchDistance:I"
))
private int getWatchDistance$lambda0$getPlayersWatchingChunk(ThreadedAnvilChunkStorage cela, ChunkPos pos, boolean bl, ServerPlayerEntity player){
return getRealViewDistance(player, watchDistance);
}

@Override
public void sendChunk(ServerPlayerEntity player, WorldChunk chunk) {
Packet<?>[] packets = new Packet[2];
sendChunkDataPackets(player, packets, chunk);
@Redirect(method = "method_17219", at = @At(
value = "FIELD",
target = "Lnet/minecraft/server/world/ThreadedAnvilChunkStorage;watchDistance:I"
))
private int getWatchDistance$lambda0$setViewDistance(ThreadedAnvilChunkStorage cela, ChunkPos pos, int previousViewDistance, Packet<?>[] packets, ServerPlayerEntity player){
return getRealViewDistance(player, watchDistance);
}

@Redirect(method = "updateCameraPosition", at = @At(
value = "sreplay_MultipleOrdinalField",
target = "Lnet/minecraft/server/world/ThreadedAnvilChunkStorage;watchDistance:I",
args = {
"ordinals=2, 3, 6, 8..11"
}
))
private int getPreviousWatchDistance(ThreadedAnvilChunkStorage cela, ServerPlayerEntity player){
if (player instanceof Photographer){
return ((Photographer)player).getCurrentWatchDistance();
}
return watchDistance;
}

@Redirect(method = "getPlayersWatchingChunk", at = @At(
value = "INVOKE",
target = "Ljava/util/stream/Stream;filter(Ljava/util/function/Predicate;)Ljava/util/stream/Stream;"
@Redirect(method = "updateCameraPosition", at = @At(
value = "sreplay_MultipleOrdinalField",
target = "Lnet/minecraft/server/world/ThreadedAnvilChunkStorage;watchDistance:I",
args = {
"ordinals=4, 5, 7, 12..15"
}
))
private Stream<ServerPlayerEntity> filterPlayers(Stream<ServerPlayerEntity> stream, Predicate<? super ServerPlayerEntity> entity, ChunkPos chunkPos, boolean onlyOnWatchDistanceEdge){
return stream.filter(player -> {
int d = getRealViewDistance(player, watchDistance);
int i = getChebyshevDistance(chunkPos, player, true);
if (i > d) {
return false;
} else {
return !onlyOnWatchDistanceEdge || i == d;
}
});
private int getCurrentWatchDistance(ThreadedAnvilChunkStorage cela, ServerPlayerEntity player){
if (player instanceof Photographer){
return ((Photographer)player).getRecordingParam().watchDistance;
}
return watchDistance;
}
}
28 changes: 8 additions & 20 deletions src/main/java/com/hadroncfy/sreplay/recording/Photographer.java
Original file line number Diff line number Diff line change
Expand Up @@ -122,17 +122,14 @@ public void setSaveName(String name){
}

private void setWatchDistance(int distance){
ServerChunkManager chunkManager = getServerWorld().getChunkManager();
recorder.onPacket(new ChunkLoadDistanceS2CPacket(distance));
int cx = MathHelper.floor(x) >> 4, cz = MathHelper.floor(z) >> 4;
ServerChunkManager chunkManager = (ServerChunkManager) world.getChunkManager();
for (int i = -distance; i <= distance; i++){
for (int j = -distance; j <= distance; j++){
WorldChunk chunk = chunkManager.method_21730(cx + i, cz + j);
if (chunk != null){
((IChunkSender)chunkManager.threadedAnvilChunkStorage).sendChunk(this, chunk);
}
}
}
chunkManager.updateCameraPosition(this);
currentWatchDistance = rparam.watchDistance;
}

public int getCurrentWatchDistance(){
return currentWatchDistance;
}

private void connect() throws IOException{
Expand Down Expand Up @@ -164,7 +161,6 @@ public void syncParams(){
updatePause();
if (currentWatchDistance != rparam.watchDistance){
setWatchDistance(rparam.watchDistance);
currentWatchDistance = rparam.watchDistance;
}
}
}
Expand Down Expand Up @@ -264,15 +260,7 @@ public Text method_14206() {
size += "/" + rparam.sizeLimit + "M";
}
Text ret = new LiteralText(getGameProfile().getName()).setStyle(new Style().setItalic(true).setColor(Formatting.AQUA));
if (rparam.watchDistance != server.getPlayerManager().getViewDistance()){
ret.append(new LiteralText(" (" + rparam.watchDistance + ")").setStyle(new Style().setColor(Formatting.GRAY)));
}
if (rparam.autoReconnect){
ret.append(new LiteralText(" [R]").setStyle(new Style().setItalic(false).setColor(Formatting.DARK_PURPLE)));
}
if (rparam.autoPause){
ret.append(new LiteralText("[P]").setStyle(new Style().setItalic(false).setColor(Formatting.GOLD)));
}

ret.append(new LiteralText(" " + time).setStyle(new Style().setItalic(false).setColor(Formatting.GREEN)))
.append(new LiteralText(" " + size).setStyle(new Style().setItalic(false).setColor(Formatting.GREEN)));
return ret;
Expand Down

0 comments on commit 3ab4777

Please sign in to comment.