#3835: Check for dialog loops

This commit is contained in:
Outfluencer 2025-05-27 19:37:54 +10:00 committed by md_5
parent 363003d8c7
commit d8f9d81b30
No known key found for this signature in database
GPG Key ID: E8E901AC7C617C11

View File

@ -13,6 +13,9 @@ import com.google.gson.JsonParser;
import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer; import com.google.gson.JsonSerializer;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.Set;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import net.md_5.bungee.api.dialog.ConfirmationDialog; import net.md_5.bungee.api.dialog.ConfirmationDialog;
import net.md_5.bungee.api.dialog.Dialog; import net.md_5.bungee.api.dialog.Dialog;
@ -28,7 +31,7 @@ import net.md_5.bungee.chat.VersionedComponentSerializer;
@RequiredArgsConstructor @RequiredArgsConstructor
public class DialogSerializer implements JsonDeserializer<Dialog>, JsonSerializer<Dialog> public class DialogSerializer implements JsonDeserializer<Dialog>, JsonSerializer<Dialog>
{ {
private static final ThreadLocal<Set<Dialog>> serializedDialogs = new ThreadLocal<Set<Dialog>>();
private static final BiMap<String, Class<? extends Dialog>> TYPES; private static final BiMap<String, Class<? extends Dialog>> TYPES;
private final VersionedComponentSerializer serializer; private final VersionedComponentSerializer serializer;
@ -102,16 +105,35 @@ public class DialogSerializer implements JsonDeserializer<Dialog>, JsonSerialize
return JsonNull.INSTANCE; return JsonNull.INSTANCE;
} }
Class<? extends Dialog> realType = src.getClass(); boolean first = serializedDialogs.get() == null;
String type = TYPES.inverse().get( realType ); if ( first )
Preconditions.checkArgument( type != null, "Unknown type %s", typeOfSrc ); {
serializedDialogs.set( Collections.newSetFromMap( new IdentityHashMap<Dialog, Boolean>() ) );
}
JsonObject object = (JsonObject) context.serialize( src, realType ); try
object.addProperty( "type", type ); {
Preconditions.checkArgument( !serializedDialogs.get().contains( src ), "Dialog loop" );
serializedDialogs.get().add( src );
JsonObject base = (JsonObject) context.serialize( src.getBase() ); Class<? extends Dialog> realType = src.getClass();
object.asMap().putAll( base.asMap() ); String type = TYPES.inverse().get( realType );
Preconditions.checkArgument( type != null, "Unknown type %s", typeOfSrc );
return object; JsonObject object = (JsonObject) context.serialize( src, realType );
object.addProperty( "type", type );
JsonObject base = (JsonObject) context.serialize( src.getBase() );
object.asMap().putAll( base.asMap() );
return object;
} finally
{
serializedDialogs.get().remove( src );
if ( first )
{
serializedDialogs.set( null );
}
}
} }
} }