InWorldGameRulesScreen.java

net.minecraft.client.gui.screens.options.InWorldGameRulesScreen

信息

  • 全限定名:net.minecraft.client.gui.screens.options.InWorldGameRulesScreen
  • 类型:public class
  • 包:net.minecraft.client.gui.screens.options
  • 源码路径:src/main/java/net/minecraft/client/gui/screens/options/InWorldGameRulesScreen.java
  • 起始行号:L26
  • 继承:AbstractGameRulesScreen
  • 实现:HasGamemasterPermissionReaction
  • 职责:

    TODO

字段/常量

  • PENDING_TEXT

    • 类型: Component
    • 修饰符: private static final
    • 源码定位: L27
    • 说明:

      TODO

  • initialValues

    • 类型: GameRuleMap
    • 修饰符: private final
    • 源码定位: L28
    • 说明:

      TODO

  • serverProvidedRules

    • 类型: List<GameRule<?>>
    • 修饰符: private final
    • 源码定位: L29
    • 说明:

      TODO

  • connection

    • 类型: ClientPacketListener
    • 修饰符: private final
    • 源码定位: L30
    • 说明:

      TODO

  • lastScreen

    • 类型: Screen
    • 修饰符: private final
    • 源码定位: L31
    • 说明:

      TODO

  • loadingDotsWidget

    • 类型: LoadingDotsWidget
    • 修饰符: private
    • 源码定位: L32
    • 说明:

      TODO

  • receivedServerValues

    • 类型: boolean
    • 修饰符: private
    • 源码定位: L33
    • 说明:

      TODO

内部类/嵌套类型

构造器

public InWorldGameRulesScreen(ClientPacketListener connection, Consumer<Optional<GameRules>> exitCallback, Screen lastScreen) @ L35

  • 构造器名:InWorldGameRulesScreen
  • 源码定位:L35
  • 修饰符:public

参数:

  • connection: ClientPacketListener
  • exitCallback: Consumer<Optional>
  • lastScreen: Screen

说明:

TODO

方法

下面的方法块按源码顺序生成。

protected void initContent() @ L41

  • 方法名:initContent
  • 源码定位:L41
  • 返回类型:void
  • 修饰符:protected

参数:

说明:

TODO

protected void onDone() @ L48

  • 方法名:onDone
  • 源码定位:L48
  • 返回类型:void
  • 修饰符:protected

参数:

说明:

TODO

private <T> void collectChangedGameRule(GameRule<T> rule, List<ServerboundSetGameRulePacket.Entry> entries) @ L59

  • 方法名:collectChangedGameRule
  • 源码定位:L59
  • 返回类型: void
  • 修饰符:private

参数:

  • rule: GameRule
  • entries: List<ServerboundSetGameRulePacket.Entry>

说明:

TODO

public void onClose() @ L68

  • 方法名:onClose
  • 源码定位:L68
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

private boolean hasPendingChanges() @ L83

  • 方法名:hasPendingChanges
  • 源码定位:L83
  • 返回类型:boolean
  • 修饰符:private

参数:

说明:

TODO

private <T> boolean hasGameRuleChanged(GameRule<T> rule) @ L87

  • 方法名:hasGameRuleChanged
  • 源码定位:L87
  • 返回类型: boolean
  • 修饰符:private

参数:

  • rule: GameRule

说明:

TODO

public void onGameRuleValuesUpdated(Map<ResourceKey<GameRule<?>>,String> values) @ L91

  • 方法名:onGameRuleValuesUpdated
  • 源码定位:L91
  • 返回类型:void
  • 修饰符:public

参数:

  • values: Map<ResourceKey<GameRule<?>>,String>

说明:

TODO

private <T> void initializeGameRuleValue(GameRule<T> rule, String valueStr) @ L112

  • 方法名:initializeGameRuleValue
  • 源码定位:L112
  • 返回类型: void
  • 修饰符:private

参数:

  • rule: GameRule
  • valueStr: String

说明:

TODO

public void onGamemasterPermissionChanged(boolean hasGamemasterPermission) @ L119

  • 方法名:onGamemasterPermissionChanged
  • 源码定位:L119
  • 返回类型:void
  • 修饰符:public

参数:

  • hasGamemasterPermission: boolean

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public class InWorldGameRulesScreen extends AbstractGameRulesScreen implements HasGamemasterPermissionReaction {
    private static final Component PENDING_TEXT = Component.translatable("editGamerule.inGame.downloadingGamerules");
    private final GameRuleMap initialValues = GameRuleMap.of();
    private final List<GameRule<?>> serverProvidedRules = new ArrayList<>();
    private final ClientPacketListener connection;
    private final Screen lastScreen;
    private @Nullable LoadingDotsWidget loadingDotsWidget;
    private boolean receivedServerValues = false;
 
    public InWorldGameRulesScreen(ClientPacketListener connection, Consumer<Optional<GameRules>> exitCallback, Screen lastScreen) {
        super(new GameRules(connection.enabledFeatures()), exitCallback);
        this.connection = connection;
        this.lastScreen = lastScreen;
    }
 
    @Override
    protected void initContent() {
        this.loadingDotsWidget = new LoadingDotsWidget(this.font, PENDING_TEXT);
        this.layout.addToContents(this.loadingDotsWidget);
        this.connection.send(new ServerboundClientCommandPacket(ServerboundClientCommandPacket.Action.REQUEST_GAMERULE_VALUES));
    }
 
    @Override
    protected void onDone() {
        List<ServerboundSetGameRulePacket.Entry> changedEntries = new ArrayList<>();
        this.initialValues.keySet().forEach(rule -> this.collectChangedGameRule((GameRule<?>)rule, changedEntries));
        if (!changedEntries.isEmpty()) {
            this.connection.send(new ServerboundSetGameRulePacket(changedEntries));
        }
 
        this.closeAndApplyChanges();
    }
 
    private <T> void collectChangedGameRule(GameRule<T> rule, List<ServerboundSetGameRulePacket.Entry> entries) {
        if (this.hasGameRuleChanged(rule)) {
            T currentValue = this.gameRules.get(rule);
            BuiltInRegistries.GAME_RULE
                .getResourceKey(rule)
                .ifPresent(key -> entries.add(new ServerboundSetGameRulePacket.Entry((ResourceKey<GameRule<?>>)key, rule.serialize(currentValue))));
        }
    }
 
    @Override
    public void onClose() {
        if (this.hasPendingChanges()) {
            this.minecraft.setScreen(new ConfirmScreen(confirmed -> {
                if (confirmed) {
                    this.closeAndDiscardChanges();
                } else {
                    this.minecraft.setScreen(this);
                }
            }, Component.translatable("editGamerule.inGame.discardChanges.title"), Component.translatable("editGamerule.inGame.discardChanges.message")));
        } else {
            this.closeAndDiscardChanges();
        }
    }
 
    private boolean hasPendingChanges() {
        return this.initialValues.keySet().stream().anyMatch(this::hasGameRuleChanged);
    }
 
    private <T> boolean hasGameRuleChanged(GameRule<T> rule) {
        return !this.gameRules.get(rule).equals(this.initialValues.get(rule));
    }
 
    public void onGameRuleValuesUpdated(Map<ResourceKey<GameRule<?>>, String> values) {
        if (!this.receivedServerValues) {
            this.receivedServerValues = true;
            values.forEach((key, valueStr) -> {
                GameRule<?> rule = BuiltInRegistries.GAME_RULE.getValue((ResourceKey<GameRule<?>>)key);
                if (rule != null) {
                    this.serverProvidedRules.add(rule);
                    this.initializeGameRuleValue(rule, valueStr);
                }
            });
            if (this.loadingDotsWidget != null) {
                this.removeWidget(this.loadingDotsWidget);
            }
 
            GameRules serverGameRules = new GameRules(this.serverProvidedRules);
            this.ruleList = this.layout.addToContents(new AbstractGameRulesScreen.RuleList(serverGameRules));
            this.addRenderableWidget(this.ruleList);
            this.repositionElements();
        }
    }
 
    private <T> void initializeGameRuleValue(GameRule<T> rule, String valueStr) {
        rule.deserialize(valueStr).result().ifPresent(value -> {
            this.initialValues.set(rule, (T)value);
            this.gameRules.set(rule, (T)value, null);
        });
    }
 
    @Override
    public void onGamemasterPermissionChanged(boolean hasGamemasterPermission) {
        if (!hasGamemasterPermission) {
            this.minecraft.setScreen(this.lastScreen);
            if (this.minecraft.screen instanceof HasGamemasterPermissionReaction screen) {
                screen.onGamemasterPermissionChanged(hasGamemasterPermission);
            }
        }
    }
}

引用的其他类