package org.granitemc.granite.reflect;

import javassist.*;
import javassist.expr.ExprEditor;
import javassist.expr.NewExpr;

import java.util.Objects;

/**
 * **************************************************************************************
 * License (MIT)
 * <p/>
 * Copyright (c) 2014. Granite Team
 * <p/>
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this
 * software and associated documentation files (the "Software"), to deal in the
 * Software without restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so, subject to the
 * following conditions:
 * <p/>
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * <p/>
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 * **************************************************************************************
 */

public class BytecodeModifier {
    // This stuff has to be updated by hand, and doesn't involve mappings

    public static void modify() {
        try {
            ClassPool pool = new ClassPool(true);

            modifyServer(pool);
            modifyScm(pool);
        } catch (CannotCompileException | NotFoundException e) {
            e.printStackTrace();
        }
    }

    public static void modifyServer(ClassPool pool) throws NotFoundException, CannotCompileException {
        CtClass cc = pool.get("po");
        CtMethod m = cc.getDeclaredMethod("i");

        m.instrument(new ExprEditor() {
            @Override
            public void edit(NewExpr e) throws CannotCompileException {
                if (Objects.equals(e.getClassName(), "pn")) {
                    // replace pn constructor with null - we'll set it to something in a proxy later
                    e.replace("$_ = null;");
                }
                super.edit(e);
            }
        });

        // Save everything
        cc.toClass();
    }

    public static void modifyScm(ClassPool pool) throws NotFoundException, CannotCompileException {
        CtClass cc = pool.get("sn");
        // Find the method
        final CtMethod method = cc.getDeclaredMethod("a", new CtClass[]{pool.get("gr"), pool.get("qw")});

        // Add a field to the class (we'll write to that just before this method is called)
        cc.addField(new CtField(pool.get("rj"), "_playServerArgument", cc));

        // Modify method to use the field
        method.instrument(new ExprEditor() {
            @Override
            public void edit(NewExpr e) throws CannotCompileException {
                if (Objects.equals(e.getClassName(), "rj")) {
                    // Replace new rj() with the field
                    e.replace("$_ = _playServerArgument;");
                }
            }
        });

        // Save it
        cc.toClass();
    }
}

@@ -113,17 +113,85 @@
 xpr.
-NewExpr;%0A
+FieldAccess;%0Aimport javassist.expr.NewExpr;%0A%0Aimport java.lang.reflect.Method;
 %0Aimp
@@ -1813,24 +1813,53 @@
 fyScm(pool);
+%0A%0A            modifyPi(pool);
 %0A        %7D c
@@ -1954,32 +1954,518 @@
        %7D%0A    %7D%0A%0A
+    public static void modifyPi(ClassPool pool) throws NotFoundException, CannotCompileException %7B%0A        // Neutralize %22pi%22 spam.%0A        // It would spam nothing but %22pi%22 in the console, constantly%0A        // I don't know the cause but this removes the spam.%0A        // This may come back and bite me in the ass later :)%0A        CtClass cc = pool.get(%22ig%22);%0A        CtMethod m = cc.getDeclaredMethod(%22a%22);%0A        m.addCatch(%22return;%22, pool.get(%22pi%22));%0A%0A        cc.toClass();%0A    %7D%0A%0A
     public stati

Fix "pi" spam