Newer
Older
void-pack-super-server / work / nms.old.1585251758016 / minecraft / server / CustomFunctionData.java
package net.minecraft.server;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import javax.annotation.Nullable;
import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class CustomFunctionData implements IResourcePackListener {

    private static final Logger LOGGER = LogManager.getLogger();
    private static final MinecraftKey d = new MinecraftKey("tick");
    private static final MinecraftKey e = new MinecraftKey("load");
    public static final int a = "functions/".length();
    public static final int b = ".mcfunction".length();
    private final MinecraftServer server;
    private final Map<MinecraftKey, CustomFunction> g = Maps.newHashMap();
    private boolean h;
    private final ArrayDeque<CustomFunctionData.a> i = new ArrayDeque();
    private final List<CustomFunctionData.a> j = Lists.newArrayList();
    private final Tags<CustomFunction> k = new Tags<>(this::a, "tags/functions", true, "function");
    private final List<CustomFunction> l = Lists.newArrayList();
    private boolean m;

    public CustomFunctionData(MinecraftServer minecraftserver) {
        this.server = minecraftserver;
    }

    public Optional<CustomFunction> a(MinecraftKey minecraftkey) {
        return Optional.ofNullable(this.g.get(minecraftkey));
    }

    public MinecraftServer getServer() {
        return this.server;
    }

    public int b() {
        return this.server.getGameRules().getInt(GameRules.MAX_COMMAND_CHAIN_LENGTH);
    }

    public Map<MinecraftKey, CustomFunction> c() {
        return this.g;
    }

    public com.mojang.brigadier.CommandDispatcher<CommandListenerWrapper> getCommandDispatcher() {
        return this.server.vanillaCommandDispatcher.a(); // CraftBukkit
    }

    public void tick() {
        GameProfiler gameprofiler = this.server.getMethodProfiler();
        MinecraftKey minecraftkey = CustomFunctionData.d;

        gameprofiler.a(minecraftkey::toString);
        Iterator iterator = this.l.iterator();

        while (iterator.hasNext()) {
            CustomFunction customfunction = (CustomFunction) iterator.next();

            this.a(customfunction, this.f());
        }

        this.server.getMethodProfiler().exit();
        if (this.m) {
            this.m = false;
            Collection<CustomFunction> collection = this.h().b(CustomFunctionData.e).a();

            gameprofiler = this.server.getMethodProfiler();
            minecraftkey = CustomFunctionData.e;
            gameprofiler.a(minecraftkey::toString);
            Iterator iterator1 = collection.iterator();

            while (iterator1.hasNext()) {
                CustomFunction customfunction1 = (CustomFunction) iterator1.next();

                this.a(customfunction1, this.f());
            }

            this.server.getMethodProfiler().exit();
        }

    }

    public int a(CustomFunction customfunction, CommandListenerWrapper commandlistenerwrapper) {
        int i = this.b();

        if (this.h) {
            if (this.i.size() + this.j.size() < i) {
                this.j.add(new CustomFunctionData.a(this, commandlistenerwrapper, new CustomFunction.d(customfunction)));
            }

            return 0;
        } else {
            int j;

            try {
                this.h = true;
                int k = 0;
                CustomFunction.c[] acustomfunction_c = customfunction.b();

                for (j = acustomfunction_c.length - 1; j >= 0; --j) {
                    this.i.push(new CustomFunctionData.a(this, commandlistenerwrapper, acustomfunction_c[j]));
                }

                do {
                    if (this.i.isEmpty()) {
                        j = k;
                        return j;
                    }

                    try {
                        CustomFunctionData.a customfunctiondata_a = (CustomFunctionData.a) this.i.removeFirst();

                        this.server.getMethodProfiler().a(customfunctiondata_a::toString);
                        customfunctiondata_a.a(this.i, i);
                        if (!this.j.isEmpty()) {
                            List list = Lists.reverse(this.j);
                            ArrayDeque arraydeque = this.i;

                            this.i.getClass();
                            list.forEach(arraydeque::addFirst);
                            this.j.clear();
                        }
                    } finally {
                        this.server.getMethodProfiler().exit();
                    }

                    ++k;
                } while (k < i);

                j = k;
            } finally {
                this.i.clear();
                this.j.clear();
                this.h = false;
            }

            return j;
        }
    }

    @Override
    public void a(IResourceManager iresourcemanager) {
        this.g.clear();
        this.l.clear();
        Collection<MinecraftKey> collection = iresourcemanager.a("functions", (s) -> {
            return s.endsWith(".mcfunction");
        });
        List<CompletableFuture<CustomFunction>> list = Lists.newArrayList();
        Iterator iterator = collection.iterator();

        while (iterator.hasNext()) {
            MinecraftKey minecraftkey = (MinecraftKey) iterator.next();
            String s = minecraftkey.getKey();
            MinecraftKey minecraftkey1 = new MinecraftKey(minecraftkey.getNamespace(), s.substring(CustomFunctionData.a, s.length() - CustomFunctionData.b));

            list.add(CompletableFuture.supplyAsync(() -> {
                return a(iresourcemanager, minecraftkey);
            }, Resource.a).thenApplyAsync((list1) -> {
                return CustomFunction.a(minecraftkey1, this, list1);
            }, this.server.aX()).handle((customfunction, throwable) -> {
                return this.a(customfunction, throwable, minecraftkey);
            }));
        }

        CompletableFuture.allOf((CompletableFuture[]) list.toArray(new CompletableFuture[0])).join();
        if (!this.g.isEmpty()) {
            CustomFunctionData.LOGGER.info("Loaded {} custom command functions", this.g.size());
        }

        this.k.a((Map) this.k.a(iresourcemanager, this.server.aX()).join());
        this.l.addAll(this.k.b(CustomFunctionData.d).a());
        this.m = true;
    }

    @Nullable
    private CustomFunction a(CustomFunction customfunction, @Nullable Throwable throwable, MinecraftKey minecraftkey) {
        if (throwable != null) {
            CustomFunctionData.LOGGER.error("Couldn't load function at {}", minecraftkey, throwable);
            return null;
        } else {
            Map map = this.g;

            synchronized (this.g) {
                this.g.put(customfunction.a(), customfunction);
                return customfunction;
            }
        }
    }

    private static List<String> a(IResourceManager iresourcemanager, MinecraftKey minecraftkey) {
        try {
            IResource iresource = iresourcemanager.a(minecraftkey);
            Throwable throwable = null;

            List list;

            try {
                list = IOUtils.readLines(iresource.b(), StandardCharsets.UTF_8);
            } catch (Throwable throwable1) {
                throwable = throwable1;
                throw throwable1;
            } finally {
                if (iresource != null) {
                    if (throwable != null) {
                        try {
                            iresource.close();
                        } catch (Throwable throwable2) {
                            throwable.addSuppressed(throwable2);
                        }
                    } else {
                        iresource.close();
                    }
                }

            }

            return list;
        } catch (IOException ioexception) {
            throw new CompletionException(ioexception);
        }
    }

    public CommandListenerWrapper f() {
        return this.server.getServerCommandListener().a(2).a();
    }

    public CommandListenerWrapper g() {
        return new CommandListenerWrapper(ICommandListener.DUMMY, Vec3D.a, Vec2F.a, (WorldServer) null, this.server.k(), "", new ChatComponentText(""), this.server, (Entity) null);
    }

    public Tags<CustomFunction> h() {
        return this.k;
    }

    public static class a {

        private final CustomFunctionData a;
        private final CommandListenerWrapper b;
        private final CustomFunction.c c;

        public a(CustomFunctionData customfunctiondata, CommandListenerWrapper commandlistenerwrapper, CustomFunction.c customfunction_c) {
            this.a = customfunctiondata;
            this.b = commandlistenerwrapper;
            this.c = customfunction_c;
        }

        public void a(ArrayDeque<CustomFunctionData.a> arraydeque, int i) {
            try {
                this.c.a(this.a, this.b, arraydeque, i);
            } catch (Throwable throwable) {
                ;
            }

        }

        public String toString() {
            return this.c.toString();
        }
    }
}