IDEA软件的markdown工具的破解

前言
想找一下IDEA工具的markdown插件,一开始找到名叫markdown的,但居然不支持latex,然后又找到Texify,但不是我想的那种效果(能直接在左边查看效果的),它是利用另外的程序生成了pdf文件,虽然也能显示latex了,但是太慢,而且也不支持中文,所以放弃了,后来根据https://github.com/vsch/idea-multimarkdown/issues/467才发现有Markdown Navigator也就是multimarkdown,并且也不能跟markdown兼容,然后禁用markdown后就能将
![LaTex Embedded Image](http://latex.codecogs.com/svg.latex?
egin{matrix}
 f &= &2 + x + 3 \
 &= &5 + x \
end{matrix}
)

显示为图片了,但还发现下面更好用的方法,就是获得15天license后填写如下js脚本就能直接显示$frac{1}{2}$这样的公式,

 就是添加下面这段

<script type="text/x-mathjax-config">
    MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$'], ['\(','\)']]}});
</script>
<script type="text/javascript"
        src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-MML-AM_CHTML">
</script>

搞好之后,效果如下:

虽然感觉这插件好用,但居然需要License,总想骂一下作者,然后想找找有没大佬已经破解过了,后来找到他
才发现原来multimarkdown的作者也不算善良,居然留下源码,之后通过上面的大佬的文章一步一步做
1.先将C:Usersxxx(需要修改为你的路径).PyCharm2019.3configpluginsidea-multimarkdownlibidea-multimarkdown.jar 复制到自己的一个地方,并且用解压缩软件直接解压,得到如下文件

 如本想直接复制上面破解大佬的https://github.com/CrazyBunQnQ/multimarkdown/tree/master/releases/2.7.0的LicenseAgent.class文件然后直接用压缩打包的或者直接替换idea-multimarkdown.jar文件(因为不懂java),貌似试了一下,发现好像不行,之后只能硬着头皮自己修改代码编译,幸好手头有IntelliJ,就将用IntelliJ直接打开此目录,如下

 开始修改代码,按照上面大佬的文件,至于怎么生成呢,不懂(java小白),然后发现右键此文件,有个Recompile,就点击之,发现如大佬所说,有依赖未添加,分别是IDEA的和MultiMarkdownPlugin,还有json,

 找了一下怎么添加依赖,后来找到,在File->Project Structure->Liraries

 

 

 然后发现IDEA的依赖OK了,不红了,但MultiMarkdownPlugin和Json仍然红,然后留意到上面的"Problems"里面有说我的MultiMarkdownPlugin有问题,需配置为Modules什么的,直接点击一下,就帮我搞好,然后就OK了

 就能编译了,然鹅,当我编译出LicenseAgent.class后(在out目录里会有),替换,然后根据破解大佬的做法,用jar生成jar文件

rem del /s/q cvf idea-multimarkdown.jar
cd idea-multimarkdown
jar cvf idea-multimarkdown.jar *
move idea-multimarkdown.jar ../

然后替换掉

C:Usersxxx(需要修改为你的路径).PyCharm2019.3configpluginsidea-multimarkdownlibidea-multimarkdown.jar

重启pycharm,我用的是pycharm,然后好像没什么感觉,不知道是不是成功了,但仍然有我的15天激活,看来可能没成功,毕竟比起破解大佬的,现在更新的1.5.0版本,有些代码也有修改,那么继续改一些代码,最后我修改了这些代码:

 LicenseAgent.java

/*
 * Copyright (c) 2015-2015 Vladimir Schneider <vladimir.schneider@gmail.com>, all rights reserved.
 *
 * This code is private property of the copyright holder and cannot be used without
 * having obtained a license or prior written permission of the of the copyright holder.
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * break by pamxy
 * www.pamxy.com
 *
 */
package com.vladsch.idea.multimarkdown.license;

import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.util.containers.HashMap;
import com.intellij.util.net.HttpConfigurable;
import com.vladsch.idea.multimarkdown.MultiMarkdownPlugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.crypto.NoSuchPaddingException;
import javax.json.*;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

public class LicenseAgent {
    private static final Logger logger = Logger.getInstance("com.vladsch.idea.multimarkdown.license.agent");

    private static final boolean LOG_AGENT_INFO = false;

    final static private String agent_signature = "475f99b03f6ec213729d7f5d577c80aa";
    final static private String license_pub = "-----BEGIN PUBLIC KEY-----
" +
            "MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlnefMGqNu1Q9hcI2Rd8G
" +
            "xyKlXQIFyXWIkYODRrLjvEwXYw0yksgjZeIC4g+hakyQNiN+TGE/xvo3fqB0CU4A
" +
            "aE33Mu7jB27dt1IItcmBhJBwIhmZDc0SWNj6ywvnLeUU/NSWWbJ1SaXzPQJ2Mm5T
" +
            "Mr3wDFhCTp80pN4svOQmdQPFSKXwdGI+n8gJvc28vRgD8As2XxgkYsZPNjefOsla
" +
            "GHS8CNw6uI8Ijcf9hfX22twQZ+auYNL/vqtBEKq2jNLwoHTo68s+0JWJu2YILlIe
" +
            "VQzXcXZyhhAVdZrMNGhBPiXUia6YrJpqZNDZ35CE+Y6ecs9c5AG2wpFJHnic2cjZ
" +
            "Kh+ba83DpA3GxYa1OGMGZNaIqCjuK7A82ZPriXsoxL6YJzqSlbF/2l2x4Y3VoVTF
" +
            "LWKEpjvLOuDOev0CH41nzkGD4Yo5CwHPZFun/WekqUBUXtxR/uH0ThoxV93exTLc
" +
            "YwWC5GqVZfN38Ye7iDljIFVzxxP3unBy0FItg52407CZyH/gTB+Zm++fZJdKbZcl
" +
            "UFvxtACEJvdgdM30FHuQlvS53mEXOMAzpJPVZu2gRoTl8cSO3GKxaNP9dmPCzD4a
" +
            "gO/kVrO/c6DerwWvCJJhifKlDc6CfjM3FfWsVI2gw3WduFPJcIsLxlUqzBh95rA1
" +
            "R+BTr2n3DV41OK5AwtCQO40CAwEAAQ==
" +
            "-----END PUBLIC KEY-----
";

    final static private String licenseHeader = "-----BEGIN IDEA-MULTIMARKDOWN LICENSE-----";
    final static private String licenseFooter = "-----END IDEA-MULTIMARKDOWN LICENSE-----";
    final static private String activationHeader = "-----BEGIN IDEA-MULTIMARKDOWN ACTIVATION-----";
    final static private String activationFooter = "-----END IDEA-MULTIMARKDOWN ACTIVATION-----";

    // RELEASE : comment out DEV LICENSE SERVER
    final static public String siteURL = "https://vladsch.com";
    //final static public String siteURL = "https://dev.vladsch.com";
    //final static public String siteURL = "http://vladsch.dev";

    final static public String patchRelease = siteURL + "/product/multimarkdown/patch-release";
    final static public String eapRelease = siteURL + "/product/multimarkdown/eap-release";

    final static private String trialURL = siteURL + "/product/multimarkdown/json/trial";
    final static private String licenseURL = siteURL + "/product/multimarkdown/json/license";
    final static private String tryPageURL = siteURL + "/product/multimarkdown/try";
    final static private String buyPageURL = siteURL + "/product/multimarkdown/buy";
    private static final String ACTIVATION_EXPIRES = "activation_expires";
    private static final String LICENSE_EXPIRES = "license_expires";
    private static final String PRODUCT_VERSION = "product_version";
    private static final String AGENT_SIGNATURE = "agent_signature";
    private static final String LICENSE_CODE = "license_code";
    private static final String LICENSE_TYPE = "license_type";
    private static final String LICENSE_FEATURES = "license_features";
    private static final String LICENSE_FEATURE_LIST = "feature_list";
    private static final String ACTIVATION_CODE = "activation_code";
    private static final String HOST_PRODUCT = "host_product";
    private static final String HOST_NAME = "host_name";
    private static final String ACTIVATED_ON = "activated_on";
    private static final String STATUS = "status";
    private static final String MESSAGE = "message";
    private static final String STATUS_DISABLE = "disable";
    private static final String STATUS_OK = "ok";
    private static final String STATUS_ERROR = "error";
    private static final String DATE_FORMAT = "yyyy-MM-dd";

    public static final String LICENSE_TYPE_TRIAL = "trial";
    public static final String LICENSE_TYPE_SUBSCRIPTION = "subscription";
    public static final String LICENSE_TYPE_LICENSE = "license";

    private String license_code;
    private String activation_code;
    private JsonObject activation;
    private String license_expires;
    private String product_version;
    private JsonObject json; // last server response
    private boolean remove_license;
    private String license_type;
    private int license_features;
    private Map<String, Integer> featureList = new HashMap<String, Integer>();
    private String lastCommunicationsError = null;

    public Map<String, Integer> getFeatureList() {
        return featureList;
    }

    /**
     * 修改
     */
    public LicenseAgent(LicenseAgent other) {
        this();
        updateFrom(other);
    }

    public void updateFrom(LicenseAgent other) {
        this.license_code = other.license_code;
        this.activation_code = other.activation_code;
        this.activation = other.activation;
        this.license_expires = other.license_expires;
        this.product_version = other.product_version;
        this.json = other.json;
        this.remove_license = other.remove_license;
        this.license_type = other.license_type;
        this.license_features = other.license_features;
        this.featureList = other.featureList;
    }

    public boolean isRemoveLicense() {
        return remove_license;
    }

    @NotNull
    public static String getTrialLicenseURL() {
        return tryPageURL;
    }

    /**
     * 不设置任何东西
     */
    public void setLicenseCode(String license_code) {
//        String trimmed = license_code.trim();
//        if (!trimmed.equals(this.license_code == null ? "" : this.license_code)) {
//            this.license_code = trimmed;
//            setActivationCode(null);
//        }
    }

    /**
     * 不设置任何东西
     */
    public void setLicenseActivationCodes(String license_code, String activation_code) {
//        String trimmed = license_code.trim();
//        if (!trimmed.equals(this.license_code == null ? "" : this.license_code)) {
//            this.license_code = trimmed;
//            setActivationCode(activation_code);
//        } else {
//            setActivationCode(activation_code);
//        }
    }

    /**
     * 不设置任何东西
     */
    public void setActivationCode(String activation_code) {
//        if (activation_code != null) {
//            String trimmed = activation_code.trim();
//            if (!trimmed.equals(this.activation_code == null ? "" : this.activation_code)) {
//                this.activation_code = trimmed;
//                this.json = null;
//                this.activation = null;
//
//                if (!isValidActivation()) {
//                    this.activation_code = null;
//                    this.json = null;
//                    this.activation = null;
//                }
//            }
//        } else {
//            this.activation_code = null;
//            this.json = null;
//            this.activation = null;
//        }
    }

    @NotNull
    public static String getLicenseURL() {
        return buyPageURL;
    }

    @NotNull
    public String licenseCode() {
        return license_code != null ? license_code : "";
    }

    /**
     * 改过期时间
     * @return
     */
    @Nullable
    public String getLicenseExpires() {
//        return license_expires;
        return "9999-12-31";
    }

    @Nullable
    public String getProductVersion() {
        return product_version;
    }

    @NotNull
    public String getMessage() {
        String message;
        return json != null ? ((message = json.getString(MESSAGE)) != null ? message : "") : "";
    }

    @Nullable
    public String getStatus() {
        return json != null ? json.getString(STATUS) : null;
    }

    @NotNull
    public String activationCode() {
        return activation_code != null ? activation_code : "";
    }

    @Nullable
    public JsonObject getActivation() {
        return activation;
    }

    @Nullable
    public String getLastCommunicationsError() {
        return lastCommunicationsError;
    }

    /**
     * 添加功能
     */
    public LicenseAgent() {
        featureList = new HashMap<>();
        featureList.put("enhanced", 1);
        featureList.put("development", 2);
    }

    /**
     *直接返回true
     */
    public boolean getLicenseCode(LicenseRequest licenseRequest) {
//        licenseRequest.agent_signature = agent_signature;
//        try {
//            final URL url = new URL(licenseURL);
//            final HttpConfigurable httpConfigurable = (HttpConfigurable) ApplicationManager.getApplication().getComponent("HttpConfigurable");
//
//            final URLConnection urlConnection = httpConfigurable != null ? httpConfigurable.openConnection(licenseURL) : url.openConnection();
//
//            urlConnection.setDoOutput(true);
//            urlConnection.setRequestProperty("Content-Type", "application/json; charset=utf-8");
//            urlConnection.connect();
//            final OutputStream outputStream = urlConnection.getOutputStream();
//            if (LOG_AGENT_INFO) logger.debug(licenseRequest.toJsonString());
//            outputStream.write((licenseRequest.toJsonString()).getBytes("UTF-8"));
//            outputStream.flush();
//            InputStream inputStream;
//            remove_license = false;
//
//            try {
//                inputStream = urlConnection.getInputStream();
//                lastCommunicationsError = null;
//            } catch (IOException e) {
//                lastCommunicationsError = e.getMessage();
//                return false;
//            }
//
//            lastCommunicationsError = null;
//
//            //BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
//            //StringBuilder sb = new StringBuilder();
//            //
//            //String line = null;
//            //try {
//            //    while ((line = reader.readLine()) != null) {
//            //        sb.append(line).append('
');
//            //    }
//            //} catch (IOException e) {
//            //    e.printStackTrace();
//            //} finally {
//            //    try {
//            //        inputStream.close();
//            //    } catch (IOException e) {
//            //        e.printStackTrace();
//            //    }
//            //}
//            JsonReader jsonReader = Json.createReader(inputStream);
//            json = jsonReader.readObject();
//            String status = json.getString(STATUS, "");
//            String message = json.getString(MESSAGE, "");
//            if (status.equals(STATUS_OK)) {
//                if ((licenseRequest.hasLicenseCode() || json.containsKey(LICENSE_CODE)) && json.containsKey(ACTIVATION_CODE)) {
//                    if (json.containsKey(LICENSE_CODE)) this.license_code = json.getString(LICENSE_CODE);
//                    this.activation_code = json.getString(ACTIVATION_CODE);
//                    return true;
//                } else {
//                    if (LOG_AGENT_INFO) logger.debug("License server did not reply with a valid response");
//                }
//            } else {
//                if (status.equals(STATUS_DISABLE)) {
//                    // remove license information from this plugin
//                    if (LOG_AGENT_INFO) logger.debug("License server requested license removal from this host");
//                    license_code = null;
//                    activation_code = null;
//                    activation = null;
//                    remove_license = true;
//                    status = STATUS_ERROR;
//                }
//                if (LOG_AGENT_INFO) logger.debug("License server replied with status: " + status + ", message: " + message);
//            }
//        } catch (MalformedURLException e) {
//            e.printStackTrace();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//
//        return false;
        return true;
    }

    /**
     * 直接返回true
     */
    public boolean isValidLicense() {
        return true;
//        if (license_code != null) {
//            int headerPos = license_code.indexOf(licenseHeader);
//            int footerPos = license_code.lastIndexOf(licenseFooter);
//            if (headerPos >= 0 && footerPos > headerPos) {
//                return true;
//            }
//        }
//        return false;
    }

    /**
     * 直接返回true
     */
    public boolean isValidActivation() {
        return true;
//        if (activation_code != null) {
//            if (activation != null) {
//                if (isActivationExpired()) {
//                    activation = null;
//                    activation_code = null;
//                    return false;
//                }
//            }
//
//            if (activation == null) {
//                int headerPos = activation_code.indexOf(activationHeader);
//                int footerPos = activation_code.lastIndexOf(activationFooter);
//                if (headerPos >= 0 && footerPos > headerPos) {
//                    try {
//                        LicenseKey licenseKey = new LicenseKey(license_pub);
//                        String activationJson = licenseKey.decrypt(activation_code.substring(headerPos + activationHeader.length(), footerPos));
//
//                        if (activationJson != null) {
//                            byte[] bytes = activationJson.getBytes("UTF-8");
//                            InputStream stream = new ByteArrayInputStream(bytes);
//                            JsonReader jsonReader = Json.createReader(stream);
//                            activation = jsonReader.readObject();
//                        }
//                    } catch (NoSuchPaddingException ignored) {
//                    } catch (NoSuchAlgorithmException ignored) {
//                    } catch (IOException ignored) {
//                    } catch (InvalidKeySpecException ignored) {
//                    } catch (Exception ignored) {
//                    }
//                }
//            }
//
//            if (activation != null && activation.containsKey(AGENT_SIGNATURE) && activation.getString(AGENT_SIGNATURE, "").equals(agent_signature)
//                    && activation.containsKey(LICENSE_EXPIRES)
//                    && activation.containsKey(LICENSE_TYPE)
//                    && activation.containsKey(LICENSE_FEATURES)
//                    && activation.containsKey(LICENSE_FEATURE_LIST)
//                    && activation.containsKey(PRODUCT_VERSION)
//                    && activation.containsKey(HOST_NAME)
//                    && activation.containsKey(HOST_PRODUCT)
//                    && activation.getString(LICENSE_TYPE) != null
//                    && activation.getInt(LICENSE_FEATURES) != 0
//                    ) {
//                try {
//                    license_expires = activation.getString(LICENSE_EXPIRES);
//                    product_version = activation.getString(PRODUCT_VERSION);
//                    license_type = activation.getString(LICENSE_TYPE);
//                    license_features = activation.getInt(LICENSE_FEATURES);
//                    JsonObject feature_list = activation.getJsonObject(LICENSE_FEATURE_LIST);
//                    featureList = new HashMap<String, Integer>();
//                    for (Map.Entry<String, JsonValue> feature : feature_list.entrySet()) {
//                        if (feature.getValue() instanceof JsonNumber) {
//                            featureList.put(feature.getKey(), ((JsonNumber) feature.getValue()).intValue());
//                        }
//                    }
//                    return true;
//                } catch (JsonException ignored) {
//                    if (LOG_AGENT_INFO) logger.debug("Activation JsonException " + ignored);
//                } catch (ClassCastException ignored) {
//                    if (LOG_AGENT_INFO) logger.debug("Activation ClassCastException " + ignored);
//                } catch (Exception ignored) {
//                    if (LOG_AGENT_INFO) logger.debug("Activation Exception " + ignored);
//                }
//            }
//        }
//        return false;
    }

    /**
     * 修改为具体值
     */
    @NotNull
    public String getLicenseType() {
//        return license_type;
        return LICENSE_TYPE_LICENSE;
    }

    /**
     * 修改为具体值
     */
    public int getLicenseFeatures() {
        return LicensedFeature.Feature.LICENSE.getLicenseFlags();//其实就是4
//        return license_features;
    }

    /**
     * 设置到期日
     */
    @NotNull
    public String getLicenseExpiration() {
        return "9999-12-31";

//        if (activation != null && activation.containsKey(LICENSE_EXPIRES)) {
//            return activation.getString(LICENSE_EXPIRES);
//        }
//        return "";
    }

    @NotNull
    public String getHostName() {
        if (activation != null && activation.containsKey(HOST_NAME)) {
            return activation.getString(HOST_NAME);
        }
        return "";
    }

    @NotNull
    public String getHostProduct() {
        if (activation != null && activation.containsKey(HOST_PRODUCT)) {
            return activation.getString(HOST_PRODUCT);
        }
        return "";
    }

    /**
     *设置注册日期
     */
    @NotNull
    public String getActivatedOn() {
        return "0001-01-01";
//        if (activation != null && activation.containsKey(ACTIVATED_ON)) {
//            return activation.getString(ACTIVATED_ON);
//        }
//        return "";
    }

    /**
     *修改还有多少天到期
     */
    public int getLicenseExpiringIn() {
        return 0;
//        // see if the license expiration is more than i days away
//        if (activation != null && activation.containsKey(LICENSE_EXPIRES)) {
//            DateFormat df = new SimpleDateFormat(DATE_FORMAT);
//            try {
//                String expires = activation.getString(LICENSE_EXPIRES);
//                Date expiration = df.parse(expires);
//                Date today = new Date();
//                int days = (int) Math.floor((expiration.getTime() - today.getTime()) / (1000 * 60 * 60 * 24));
//                return days + 1;
//            } catch (ParseException ignored) {
//            }
//        }
//        return 0;
    }

    public static int floorDiv(int var0, int var1) {
        int var2 = var0 / var1;
        if ((var0 ^ var1) < 0 && var2 * var1 != var0) {
            --var2;
        }

        return var2;
    }

    public static long floorDiv(long var0, long var2) {
        long var4 = var0 / var2;
        if ((var0 ^ var2) < 0L && var4 * var2 != var0) {
            --var4;
        }

        return var4;
    }

    /**
     * 直接返回否:未过期
     * @return
     */
    public boolean isActivationExpired() {
        return false;
//        // see if the activation has expired
//        if (activation != null) {
//            if (product_version == null || !product_version.equals(MultiMarkdownPlugin.getProductVersion())
//                    //|| !getHostName().equals(LicenseRequest.getHostName())
//                    || !getHostProduct().equals(LicenseRequest.getHostProduct())
//                    ) {
//                return true;
//            }
//
//            if (activation.containsKey(ACTIVATION_EXPIRES)) {
//                DateFormat df = new SimpleDateFormat(DATE_FORMAT);
//                try {
//                    String expires = activation.getString(ACTIVATION_EXPIRES);
//                    Date expiration = df.parse(expires);
//                    Date today = new Date();
//                    int days = (int) floorDiv(expiration.getTime() - today.getTime(), (1000 * 60 * 60 * 24));
//                    return days < 0;
//                } catch (ParseException ignored) {
//                    return true;
//                }
//            }
//            return false;
//        }
//        return true;
    }
}

LicensedFeature.java

/*
 * Copyright (c) 2015-2015 Vladimir Schneider <vladimir.schneider@gmail.com>, all rights reserved.
 *
 * This code is private property of the copyright holder and cannot be used without
 * having obtained a license or prior written permission of the of the copyright holder.
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * break by pamxy
 * www.pamxy.com
 *
 */
package com.vladsch.idea.multimarkdown.license;

import org.jetbrains.annotations.NotNull;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE, ElementType.FIELD })
//@Repeatable(LicensedFeatures.class)
public @interface LicensedFeature {
    enum Feature {
        ALL(null, 0xffffffff),
        TRIAL(LicenseAgent.LICENSE_TYPE_TRIAL, 1),
        SUBSCRIPTION(LicenseAgent.LICENSE_TYPE_SUBSCRIPTION, 2),
        LICENSE(LicenseAgent.LICENSE_TYPE_LICENSE, 4);

        private final String type;
        private final int flags;

        Feature(String type, int flags) {
            this.type = type;
            this.flags = flags;
        }

        boolean isLicensedFor(@NotNull String type) {
            return this.type == null || this.type.equals(type);
        }

        int getLicenseFlags() {
            return flags;
        }
    }

    /**
     * 默认就是已授权版本
     * @return
     */
    Feature type() default Feature.LICENSE;
}

LicensedFeaturesImpl.java

/*
 * Copyright (c) 2015-2015 Vladimir Schneider <vladimir.schneider@gmail.com>, all rights reserved.
 *
 * This code is private property of the copyright holder and cannot be used without
 * having obtained a license or prior written permission of the of the copyright holder.
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * break by pamxy
 * www.pamxy.com
 *
 */
package com.vladsch.idea.multimarkdown.license;

import com.intellij.util.ReflectionUtil;
import com.vladsch.idea.multimarkdown.MultiMarkdownPlugin;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class LicensedFeaturesImpl {
    final protected Class forClass;
    final protected Map<String, Integer> licensedFeaturesMap = new HashMap<String, Integer>();
    final protected Map<String, Method> unlicensedValuesMap = new HashMap<String, Method>();

    public LicensedFeaturesImpl(Class forClass) {
        this.forClass = forClass;

        // load the methods labeled with annotations
        // for now no method overloading is checked, all licensed annotations for a method name form a combined set of licensing
        // that these support. Since only Feature.ALL will be used for now this is not a problem. Really need to create
        // a compile time processor that will wrap the function and do all processing at compile time with no runtime overhead
        List<Method> methods = ReflectionUtil.getClassDeclaredMethods(forClass);
        Map<String, ArrayList<Method>> methodMap = new HashMap<String, ArrayList<Method>>();

        for (Method method : methods) {
            Annotation[] annotations = method.getDeclaredAnnotations();
            for (final Annotation annotation : annotations) {
                String methodName = method.getName();
                boolean addMethod = false;
                if (annotation instanceof LicensedFeatures) {
                    addMethod = true;
                    LicensedFeatures licensedFeatures = (LicensedFeatures) annotation;

                    int typeFlags = licenseTypeFlags(licensedFeatures.value());
                    if (!licensedFeaturesMap.containsKey(methodName)) {
                        licensedFeaturesMap.put(methodName, typeFlags);
                    } else {
                        licensedFeaturesMap.put(methodName, licensedFeaturesMap.get(methodName) | typeFlags);
                    }
                } else if (annotation instanceof LicensedFeature) {
                    addMethod = true;
                    LicensedFeature licensedFeature = (LicensedFeature) annotation;
                    int typeFlags = licenseTypeFlags(licensedFeature);
                    if (!licensedFeaturesMap.containsKey(methodName)) {
                        licensedFeaturesMap.put(methodName, typeFlags);
                    } else {
                        licensedFeaturesMap.put(methodName, licensedFeaturesMap.get(methodName) | typeFlags);
                    }
                } else if (annotation instanceof UnlicensedValue) {
                    addMethod = true;
                    String forMethod = ((UnlicensedValue) annotation).method();
                    assert !unlicensedValuesMap.containsKey(forMethod) : methodName + "annotated with @UnlicensedValue for " + forMethod + " is already defined by " + unlicensedValuesMap.get(forMethod);

                    // these should take no parameters and have a return type that is not void
                    assert method.getParameterTypes().length == 0 : methodName + "annotated with @UnlicensedValue for " + forMethod + " should take no parameters ";

                    unlicensedValuesMap.put(forMethod, method);
                }

                if (addMethod) {
                    if (!methodMap.containsKey(methodName)) {
                        methodMap.put(methodName, new ArrayList<Method>(1));
                    }
                    methodMap.get(methodName).add(method);
                }
            }
        }

        // validate that all forMethods are contained in licensedMethods and that they all return compatible types with functions that they shadow
        for (String forMethodName : unlicensedValuesMap.keySet()) {
            Method unlicensedValue = unlicensedValuesMap.get(forMethodName);
            assert licensedFeaturesMap.containsKey(forMethodName) : "method " + forMethodName + " not annotated with @LicensedFeature, but is target for @UnlicensedValue " + unlicensedValue.getName();
            ArrayList<Method> forMethods = methodMap.get(forMethodName);

            for (Method forMethod : forMethods) {
                assert unlicensedValue.getReturnType().isAssignableFrom(forMethod.getReturnType()) : unlicensedValue.getName() + " @UnlicensedValue for " + forMethodName + " has incompatible return type";
            }
        }
    }

    protected int licenseTypeFlags(LicensedFeature... licensedFeatures) {
        int flags = 0;
        for (LicensedFeature licensedFeature : licensedFeatures) {
            flags |= licensedFeature.type().getLicenseFlags();
        }
        return flags;
    }

    /**
     * 返回true
     * @return
     */
    public boolean isLicensed() {
        return true;
//        StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
//        String methodName = stackTraceElements[1].getMethodName();
//        assert licensedFeaturesMap.containsKey(methodName) : "isLicensed called from method " + methodName + " not annotated with @Licensed";
//        return MultiMarkdownPlugin.areAllLicensed(licensedFeaturesMap.get(methodName));
    }

    // this really needs to be implemented in a processor so that code is generated according to types
    Object unlicensedValue(Object thizz) {
        StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
        String methodName = stackTraceElements[1].getMethodName();
        assert unlicensedValuesMap.containsKey(methodName) : "unlicensedValue called from method " + methodName + " which does not an associated @UnlicensedValue function";
        Method unlicensedValue = unlicensedValuesMap.get(methodName);

        Object result = null;
        try {
            result = unlicensedValue.invoke(thizz);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        return result;
    }
}

LicenseRequest.java

/*
 * Copyright (c) 2015-2015 Vladimir Schneider <vladimir.schneider@gmail.com>, all rights reserved.
 *
 * This code is private property of the copyright holder and cannot be used without
 * having obtained a license or prior written permission of the of the copyright holder.
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * break by pamxy
 * www.pamxy.com
 */
package com.vladsch.idea.multimarkdown.license;

import com.intellij.openapi.application.ApplicationInfo;
import com.intellij.openapi.diagnostic.Logger;

import java.net.InetAddress;
import java.net.UnknownHostException;

public class LicenseRequest {
    //private static String host_system_name;
    private static final Logger logger = Logger.getInstance("com.vladsch.idea.multimarkdown.license.request");

    final public String product_name;
    final public String product_version;
    public String email;
    public String name;
    public String password;
    public String agent_signature;
    public String license_code;
    public String host_name;
    public String host_os;
    public String host_product;
    public String host_jre;

    public String toJsonString() {
        JsonStringer json = new JsonStringer();
        if (product_name != null) json.add("product_name", product_name);
        if (product_version != null) json.add("product_version", product_version);
        if (email != null) json.add("email", email);
        if (name != null) json.add("name", name);
        if (password != null) json.add("password", password);
        if (license_code != null) json.add("license_code", license_code);
        if (agent_signature != null) json.add("agent_signature", agent_signature);
        if (host_name != null) json.add("host_name", host_name);
        if (host_os != null) json.add("host_os", host_os);
        if (host_product != null) json.add("host_product", host_product);
        if (host_jre != null) json.add("host_jre", host_jre);
        return json.toString();
    }

    //interface RunnableTest {
    //    String result();
    //}
    //
    //public static void TestMethods(String name, RunnableTest canFail) {
    //    String result = "";
    //
    //    try {
    //        result = canFail.result();
    //    } catch (NoSuchMethodError ignored) {
    //        result = "NoSuchMethodError";
    //    }
    //    logger.info("getBuild()."+ name + " = " + ;
    //}
    //
    //    try {
    //        return ApplicationInfo.getInstance().getBuild().asStringWithAllDetails();
    //    } catch (NoSuchMethodError ignored) {
    //
    //    }
    //}

    public static String getHostProduct() {
        try {
            return ApplicationInfo.getInstance().getBuild().asString();
        } catch (NoSuchMethodError ignored) {

        }
        return "<unknown>";
    }

    public LicenseRequest(String product_name, String product_version) {
        this.product_name = product_name;
        this.product_version = product_version;
        this.host_name = getHostName();
        this.host_product = getHostProduct();
        this.host_os = System.getProperty("os.name");
        this.host_jre = System.getProperty("java.version");
    }

    public static String getHostName() {
        //if (host_system_name != null) {
        //    return host_system_name;
        //}

        // try InetAddress.LocalHost first;
        //      NOTE -- InetAddress.getLocalHost().getHostName() will not work in certain environments.
        String host = null;

        try {
            String result = InetAddress.getLocalHost().getHostName();
            if (result != null && !result.isEmpty()) {
                host = result;
            }
        } catch (UnknownHostException e) {
            // failed;  try alternate means.
        }

        // try environment properties.
        if (host == null) {
            host = System.getenv("COMPUTERNAME");

            if (host == null) {
                host = System.getenv("HOSTNAME");
                if (host == null) {
                    host = "undetermined";
                }
            }
        }

        // undetermined.
        //host_system_name = host;
        //return host + "_test";
        return host;
    }

    /**
     * 修改
     * @return
     */
    public boolean hasLicenseCode() {
        return true;
//        return license_code != null && !license_code.isEmpty();
    }
}

然后继续生成jar,替换,再次打开pycharm,结果OK了,效果如下

至于真正哪句代码生效了目前不清楚,因为没仔细看代码。

 jar文件在这里,如果跟我同一版本的,估计可以直接替换使用

idea-multimarkdown.zip

终于,首次成功po jie(修改)IDEA的插件!!!
 
作者:pamxy
 
需转载请在下面留下留言并添加转载连接:https://www.cnblogs.com/pamxy/articles/12036042.html
 
如此文章对您有所帮助,请我饮杯咖啡呗T^T
 
此致敬礼,谢谢大佬的收看!
原文地址:https://www.cnblogs.com/pamxy/p/12036042.html