diff --git a/.androidide/editor/openedFiles.json b/.androidide/editor/openedFiles.json index a7cb09e..3248f8a 100644 --- a/.androidide/editor/openedFiles.json +++ b/.androidide/editor/openedFiles.json @@ -4,14 +4,14 @@ "file": "/storage/emulated/0/MoonLeaf/Projects/FuckMaoNemo/app/src/main/java/io/github/moonleeeaf/fuckmaonemo/Hook.java", "selection": { "end": { - "column": 59, - "index": 9189, - "line": 224 + "column": 17, + "index": 6820, + "line": 170 }, "start": { - "column": 59, - "index": 9189, - "line": 224 + "column": 17, + "index": 6820, + "line": 170 } } }, @@ -19,14 +19,14 @@ "file": "/storage/emulated/0/MoonLeaf/Projects/FuckMaoNemo/app/src/main/res/xml/config.xml", "selection": { "end": { - "column": 0, - "index": 0, - "line": 0 + "column": 66, + "index": 3096, + "line": 88 }, "start": { - "column": 0, - "index": 0, - "line": 0 + "column": 52, + "index": 3082, + "line": 88 } } } diff --git a/app/build.gradle b/app/build.gradle index 10e751c..a8cc85f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -12,8 +12,8 @@ android { applicationId "io.github.moonleeeaf.fuckmaonemo" minSdk 21 targetSdk 33 - versionCode 13000 - versionName "1.3.p" + versionCode 14000 + versionName "1.4.0" vectorDrawables { useSupportLibrary true diff --git a/app/src/main/assets/屏蔽词.txt b/app/src/main/assets/屏蔽词.txt new file mode 100644 index 0000000..c3e0c92 --- /dev/null +++ b/app/src/main/assets/屏蔽词.txt @@ -0,0 +1,11 @@ +我操 我‌操 +他妈 他‌妈 +你妈 你‌妈 +妈的 妈‌的 +傻逼 傻‌逼 +智障 智‌障 +傻子 傻‌子 +CP C‌P +NM N‌M +TM T‌M +MD M‌D \ No newline at end of file diff --git a/app/src/main/java/io/github/moonleeeaf/fuckmaonemo/ConfigActivity.java b/app/src/main/java/io/github/moonleeeaf/fuckmaonemo/ConfigActivity.java index fbcdb60..dc2e3b6 100644 --- a/app/src/main/java/io/github/moonleeeaf/fuckmaonemo/ConfigActivity.java +++ b/app/src/main/java/io/github/moonleeeaf/fuckmaonemo/ConfigActivity.java @@ -8,7 +8,9 @@ import android.preference.PreferenceManager; import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.LinearLayout; +import android.widget.Toast; import android.widget.Toolbar; +import java.io.FileOutputStream; public class ConfigActivity extends PreferenceActivity { @@ -35,11 +37,19 @@ public class ConfigActivity extends PreferenceActivity { findPreference("see_miao").setOnPreferenceClickListener((p) -> { new AlertDialog.Builder(this) .setTitle("屏蔽词列表") - .setMessage("当期列表:\n" + Hook.MIAO_LIST) + .setMessage("当期列表:\n" + getPreferenceManager().getSharedPreferences().getString("MIAO_LIST_SHARED", "获取失败!")) .show(); return false; }); + + try { + FileOutputStream fos = openFileOutput("fuck_miao.txt", MODE_WORLD_READABLE); + String s = new String(getAssets().open("屏蔽词.txt").readAllBytes()); + getPreferenceManager().getSharedPreferences().edit().putString("MIAO_LIST_SHARED", s).apply(); + } catch(Exception e) { + Toast.makeText(this, "更新屏蔽词列表失败!" + e, Toast.LENGTH_LONG).show(); + } } } diff --git a/app/src/main/java/io/github/moonleeeaf/fuckmaonemo/Hook.java b/app/src/main/java/io/github/moonleeeaf/fuckmaonemo/Hook.java index a1513a2..301d49b 100644 --- a/app/src/main/java/io/github/moonleeeaf/fuckmaonemo/Hook.java +++ b/app/src/main/java/io/github/moonleeeaf/fuckmaonemo/Hook.java @@ -3,7 +3,10 @@ import android.app.Activity; import android.app.Application; import android.content.Context; import android.content.Intent; +import android.content.res.AssetManager; +import android.content.res.loader.AssetsProvider; import android.os.Bundle; +import android.util.Pair; import android.widget.Toast; import de.robv.android.xposed.IXposedHookLoadPackage; import de.robv.android.xposed.XC_MethodHook; @@ -14,7 +17,10 @@ import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.callbacks.XC_LoadPackage; import java.lang.reflect.Method; import java.net.Proxy; +import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; public class Hook implements IXposedHookLoadPackage { @@ -24,14 +30,24 @@ public class Hook implements IXposedHookLoadPackage { private int nohengheng; private int aaaa; - public static final String MIAO_LIST = "妈 马 操 草 傻 艹 牛 逼 P 槽 涩 色 m"; - public static final String[] MIAO = MIAO_LIST.split(" "); + public static String MIAO_LIST; + public static String[][] MIAO; private XC_MethodHook.Unhook force_set_work_myown_unhook; + private static String[][] demo(String[] array, String split) { + ArrayList ls = new ArrayList<>(); + for (String i : array) { + String[] b = i.split(split); + ls.add(new String[] {b[0], b[1]}); + } + return ls.toArray(new String[][]{}); + } + @Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam param) throws Throwable { - if ("com.codemao.nemo".equals(param.packageName)) { + xsp = new XSharedPreferences("io.github.moonleeeaf.fuckmaonemo", "config"); + if ("com.codemao.nemo".equals(param.packageName) || xsp.getBoolean("force_enable", false)) { XposedBridge.log("[FuckMaoNemo] 开始注入..."); // 感谢 安宁 提供取加固程序的 ClassLoader 的代码 XposedBridge.hookAllMethods( @@ -58,11 +74,16 @@ public class Hook implements IXposedHookLoadPackage { return (Application) XposedHelpers.callStaticMethod(Class.forName("android.app.ActivityThread"), "currentApplication"); } - public static String fuck屏蔽词(String str) { - for (String i : MIAO) { - str = str.replaceAll(i, "‌" + i + "‌"); + public static Pair fuck屏蔽词(String str) { + String after = str; + String a = ""; + for (String[] i : MIAO) { + after = str.replaceAll(i[0], i[1]); + if (!after.equals(str)) + a += i[0]; + str = after; } - return str; + return new Pair<>(str, a); } public void hook(XC_LoadPackage.LoadPackageParam param) throws Exception { @@ -71,9 +92,7 @@ public class Hook implements IXposedHookLoadPackage { nohengheng = 0; aaaa = 0; - - xsp = new XSharedPreferences("io.github.moonleeeaf.fuckmaonemo", "config"); - + XposedBridge.log("[FuckMaoNemo] 注入中..."); // 拦截40x码 @@ -111,6 +130,16 @@ public class Hook implements IXposedHookLoadPackage { ); }); + load("test", () -> { + methodToVoid( + getMethod( + XposedHelpers.findClass("com.codemao.nemo.bean.AuthorInfo", classLoader), + "setFork_user", + boolean.class + ) + ); + }); + // 绕过防沉迷 load("fuck_fcm", () -> { XposedBridge.log("[FuckMaoNemo] Hook_绕过防沉迷"); @@ -121,6 +150,82 @@ public class Hook implements IXposedHookLoadPackage { )); }); + // 修复KN作品播放 + load("fix_kn_player", () -> { + XposedBridge.log("[FuckMaoNemo] Hook_修复KN作品播放"); + XposedBridge.hookMethod( + getMethod( + XposedHelpers.findClass("com.codemao.nemo.view.X5DWebView", classLoader), + "loadUrl", + String.class + ), + new XC_MethodHook() { + @Override + protected void beforeHookedMethod(MethodHookParam mp) throws Throwable { + String url = (String) mp.args[0]; + if (url != null && url.contains("kn.codemao.cn")) + url = url.substring(0, url.lastIndexOf("?")) + "&is_nemo_player=true"; + mp.args[0] = url; + XposedBridge.log("KN作品替换链接:" + url); + } + } + ); + XposedBridge.hookMethod( + getMethod( + XposedHelpers.findClass("com.codemao.creativestore.dsbridge.DWebView", classLoader), + "loadUrl", + String.class + ), + new XC_MethodHook() { + @Override + protected void beforeHookedMethod(MethodHookParam mp) throws Throwable { + String url = (String) mp.args[0]; + if (url != null && url.contains("kn.codemao.cn")) + url = url.substring(0, url.lastIndexOf("?")) + "&is_nemo_player=true"; + mp.args[0] = url; + XposedBridge.log("KN作品替换链接:" + url); + } + } + ); + }); + + // 作品没有失效 + load("work_is_valid", () -> { + XposedBridge.log("[FuckMaoNemo] Hook_作品没有失效"); + XposedBridge.hookMethod(getMethod( + XposedHelpers.findClass("com.codemao.nemo.bean.CollectWorkInfo", classLoader), + "getPublish_time", + null + ),new XC_MethodReplacement() { + @Override + protected Object replaceHookedMethod(MethodHookParam mp) throws Throwable { + long time = XposedHelpers.getLongField(mp.thisObject, "publish_time"); + if (time <= 0) + time = 114514; + return time; + } + }); + }); + + // 岛3我推荐你吗 + load("fuck_box3recommend", () -> { + XposedBridge.log("[FuckMaoNemo] Hook_岛3我推荐你吗"); + + Object mgr = XposedHelpers.findClass("com.giu.xzz.http.RetrofitManager",classLoader).getDeclaredMethod("get", null).invoke(null, null); + Object example = mgr.getClass().getDeclaredMethod("create", new Class[] { Class.class }).invoke(mgr, XposedHelpers.findClass("com.codemao.nemo.retrofit.api.DiscoveryService", classLoader)); + + XposedBridge.hookAllMethods( + example.getClass(), + "getRecommendBoxData", + new XC_MethodReplacement() { + @Override + protected Object replaceHookedMethod(MethodHookParam mp) throws Throwable { + return XposedHelpers.findClass("io.reactivex.Observable", classLoader).getConstructor(null).newInstance(null); + } + } + ); + }); + // 强制显示再创作按钮 load("force_show_rework", () -> { XposedBridge.log("[FuckMaoNemo] Hook_强制显示再创作按钮"); @@ -234,10 +339,18 @@ public class Hook implements IXposedHookLoadPackage { // 防止屏蔽屏蔽词 load("fuck_miao", () -> { XposedBridge.log("[FuckMaoNemo] Hook_反屏蔽"); + + MIAO_LIST = xsp.getString("MIAO_LIST_SHARED", null); + + MIAO = demo(MIAO_LIST.split("\n"), " "); + XC_MethodHook hook = new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam mp) throws Throwable { - XposedHelpers.setObjectField(mp.thisObject, "content", fuck屏蔽词((String) XposedHelpers.getObjectField(mp.thisObject, "content"))); + Pair sb = fuck屏蔽词((String) XposedHelpers.getObjectField(mp.thisObject, "content")); + XposedHelpers.setObjectField(mp.thisObject, "content", sb.first); + if (!"".equals(sb.second)) + Toast.makeText(getApplication(), "[FuckMaoNemo] 发送内容已尝试防止屏蔽下列字符词语:" + sb.second, Toast.LENGTH_LONG).show(); } }; XposedBridge.hookMethod( diff --git a/app/src/main/res/xml/config.xml b/app/src/main/res/xml/config.xml index 29bb6fa..d12b30c 100644 --- a/app/src/main/res/xml/config.xml +++ b/app/src/main/res/xml/config.xml @@ -9,7 +9,12 @@ - + + + @@ -68,9 +73,30 @@ android:title="谋权篡位" android:summary="伪装任意作品是你自己的,可以:\n直接编辑作品源码\n其他用途" /> + + + + + + + + +