3 Commits

Author SHA1 Message Date
MoonLeeeaf
248cca908f new feature
Some checks failed
Android CI / build (push) Failing after 14m58s
2024-07-16 13:17:03 +08:00
MoonLeeeaf
b8246657d1 feat: 谋权篡位 & 强制置顶评论
Some checks failed
Android CI / build (push) Failing after 14m58s
2024-07-07 21:01:02 +08:00
满月叶
6b886b3182 docs: docs
Some checks failed
Android CI / build (push) Failing after 19m57s
2024-06-29 22:06:53 +08:00
7 changed files with 324 additions and 27 deletions

View File

@@ -1,35 +1,35 @@
{ {
"allFiles": [ "allFiles": [
{ {
"file": "/storage/emulated/0/铃芽の文件/Projects/FuckMaoNemo/app/src/main/res/xml/config.xml", "file": "/storage/emulated/0/MoonLeaf/Projects/FuckMaoNemo/app/src/main/java/io/github/moonleeeaf/fuckmaonemo/Hook.java",
"selection": { "selection": {
"end": { "end": {
"column": 36, "column": 17,
"index": 1031, "index": 6820,
"line": 30 "line": 170
}, },
"start": { "start": {
"column": 36, "column": 17,
"index": 1031, "index": 6820,
"line": 30 "line": 170
} }
} }
}, },
{ {
"file": "/storage/emulated/0/铃芽の文件/Projects/FuckMaoNemo/app/build.gradle", "file": "/storage/emulated/0/MoonLeaf/Projects/FuckMaoNemo/app/src/main/res/xml/config.xml",
"selection": { "selection": {
"end": { "end": {
"column": 26, "column": 66,
"index": 302, "index": 3096,
"line": 15 "line": 88
}, },
"start": { "start": {
"column": 26, "column": 52,
"index": 302, "index": 3082,
"line": 15 "line": 88
} }
} }
} }
], ],
"selectedFile": "/storage/emulated/0/铃芽の文件/Projects/FuckMaoNemo/app/build.gradle" "selectedFile": "/storage/emulated/0/MoonLeaf/Projects/FuckMaoNemo/app/src/main/java/io/github/moonleeeaf/fuckmaonemo/Hook.java"
} }

View File

@@ -12,8 +12,8 @@ android {
applicationId "io.github.moonleeeaf.fuckmaonemo" applicationId "io.github.moonleeeaf.fuckmaonemo"
minSdk 21 minSdk 21
targetSdk 33 targetSdk 33
versionCode 12100 versionCode 14000
versionName "1.2.1" versionName "1.4.0"
vectorDrawables { vectorDrawables {
useSupportLibrary true useSupportLibrary true

View File

@@ -0,0 +1,11 @@
我操 我‌操
他妈 他‌妈
你妈 你‌妈
妈的 妈‌的
傻逼 傻‌逼
智障 智‌障
傻子 傻‌子
CP CP
NM NM
TM TM
MD MD

View File

@@ -8,7 +8,9 @@ import android.preference.PreferenceManager;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.Toast;
import android.widget.Toolbar; import android.widget.Toolbar;
import java.io.FileOutputStream;
public class ConfigActivity extends PreferenceActivity { public class ConfigActivity extends PreferenceActivity {
@@ -31,6 +33,23 @@ public class ConfigActivity extends PreferenceActivity {
return false; return false;
}); });
findPreference("see_miao").setOnPreferenceClickListener((p) -> {
new AlertDialog.Builder(this)
.setTitle("屏蔽词列表")
.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();
}
} }
} }

View File

@@ -3,7 +3,10 @@ import android.app.Activity;
import android.app.Application; import android.app.Application;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.res.AssetManager;
import android.content.res.loader.AssetsProvider;
import android.os.Bundle; import android.os.Bundle;
import android.util.Pair;
import android.widget.Toast; import android.widget.Toast;
import de.robv.android.xposed.IXposedHookLoadPackage; import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook; 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 de.robv.android.xposed.callbacks.XC_LoadPackage;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.net.Proxy; import java.net.Proxy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
public class Hook implements IXposedHookLoadPackage { public class Hook implements IXposedHookLoadPackage {
@@ -24,9 +30,24 @@ public class Hook implements IXposedHookLoadPackage {
private int nohengheng; private int nohengheng;
private int aaaa; private int aaaa;
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<String[]> 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 @Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam param) throws Throwable { 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] 开始注入..."); XposedBridge.log("[FuckMaoNemo] 开始注入...");
// 感谢 安宁 提供取加固程序的 ClassLoader 的代码 // 感谢 安宁 提供取加固程序的 ClassLoader 的代码
XposedBridge.hookAllMethods( XposedBridge.hookAllMethods(
@@ -53,6 +74,18 @@ public class Hook implements IXposedHookLoadPackage {
return (Application) XposedHelpers.callStaticMethod(Class.forName("android.app.ActivityThread"), "currentApplication"); return (Application) XposedHelpers.callStaticMethod(Class.forName("android.app.ActivityThread"), "currentApplication");
} }
public static Pair<String, String> 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 new Pair<>(str, a);
}
public void hook(XC_LoadPackage.LoadPackageParam param) throws Exception { public void hook(XC_LoadPackage.LoadPackageParam param) throws Exception {
if (isHooked) return; if (isHooked) return;
else isHooked = true; else isHooked = true;
@@ -60,8 +93,6 @@ public class Hook implements IXposedHookLoadPackage {
nohengheng = 0; nohengheng = 0;
aaaa = 0; aaaa = 0;
xsp = new XSharedPreferences("io.github.moonleeeaf.fuckmaonemo", "config");
XposedBridge.log("[FuckMaoNemo] 注入中..."); XposedBridge.log("[FuckMaoNemo] 注入中...");
// 拦截40x码 // 拦截40x码
@@ -99,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", () -> { load("fuck_fcm", () -> {
XposedBridge.log("[FuckMaoNemo] Hook_绕过防沉迷"); XposedBridge.log("[FuckMaoNemo] Hook_绕过防沉迷");
@@ -109,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", () -> { load("force_show_rework", () -> {
XposedBridge.log("[FuckMaoNemo] Hook_强制显示再创作按钮"); XposedBridge.log("[FuckMaoNemo] Hook_强制显示再创作按钮");
@@ -164,6 +281,104 @@ public class Hook implements IXposedHookLoadPackage {
); );
}); });
// 强制置顶评论
load("force_top_comment", () -> {
XposedBridge.log("[FuckMaoNemo] Hook_强制置顶评论");
XposedBridge.hookMethod(
getMethod(
XposedHelpers.findClass("com.codemao.nemo.view.CommentOptionDialogV2", classLoader),
"checkIsSelf",
null
),
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam mp) throws Throwable {
XposedHelpers.setBooleanField(mp.thisObject, "isOwnWork", true);
}
}
);
});
// 谋权篡位
load("force_set_work_myown", () -> {
XposedBridge.log("[FuckMaoNemo] Hook_谋权篡位");
XposedBridge.hookMethod(
getMethod(
XposedHelpers.findClass("com.codemao.nemo.activity.WorkDetailActivity", classLoader),
"setWorkDetailData",
null
),
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam mp) throws Throwable {
force_set_work_myown_unhook = XposedBridge.hookMethod(
getMethod(
XposedHelpers.findClass("com.codemao.creativecenter.utils.bcm.bean.AuthorInfo", classLoader),
"getId",
null
),
new XC_MethodReplacement() {
@Override
protected Object replaceHookedMethod(MethodHookParam hp) throws Throwable {
Method m = getMethod(XposedHelpers.findClass("com.codemao.nemo.util.LocalUserHelper", classLoader), "getUserInfo", null);
m.setAccessible(true);
Object usrInfo = m.invoke(null, null);
m = getMethod(usrInfo.getClass(), "getId", null);
m.setAccessible(true);
force_set_work_myown_unhook.unhook(); // 希望人没事
return m.invoke(usrInfo, null); // long 类型
}
});
}
}
);
});
// 防止屏蔽屏蔽词
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 {
Pair<String, String> 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(
getMethod(
XposedHelpers.findClass("com.codemao.nemo.fragment.WorkCommentFragment", classLoader),
"sendReply",
null
),
hook
);
XposedBridge.hookMethod(
getMethod(
XposedHelpers.findClass("com.codemao.nemo.fragment.WorkCommentFragment", classLoader),
"sendComment",
null
),
hook
);
XposedBridge.hookMethod(
getMethod(
XposedHelpers.findClass("com.codemao.nemo.activity.CommentDetailActivity", classLoader),
"send",
null
),
hook
);
});
XposedBridge.log("[FuckMaoNemo] 执行完毕"); XposedBridge.log("[FuckMaoNemo] 执行完毕");
Toast.makeText(getApplication(), "[FuckMaoNemo] 加载成功 (≧▽≦)\n" + nohengheng + " 个功能加载成功, " + aaaa + " 个失败", Toast.LENGTH_LONG).show(); Toast.makeText(getApplication(), "[FuckMaoNemo] 加载成功 (≧▽≦)\n" + nohengheng + " 个功能加载成功, " + aaaa + " 个失败", Toast.LENGTH_LONG).show();

View File

@@ -10,6 +10,11 @@
android:title="作者" android:title="作者"
android:summary="编程猫 @满月叶\nGitHub @MoonLeeeaf\n喵呜~" /> android:summary="编程猫 @满月叶\nGitHub @MoonLeeeaf\n喵呜~" />
<SwitchPreference
android:key="force_enable"
android:title="强制启用"
android:summary="如果你正在使用基于官方 Nemo 修改的客户端,那么可以打开此选项(记得配置模块作用域哦)" />
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory android:title="网络"> <PreferenceCategory android:title="网络">
@@ -28,12 +33,31 @@
<SwitchPreference <SwitchPreference
android:key="fuck_update" android:key="fuck_update"
android:title="屏蔽更新" android:title="屏蔽更新"
android:summary="主页不会弹更新对话框" /> android:summary="主页不会弹更新对话框,不会拦截设置里手动查看的更新" />
<SwitchPreference <SwitchPreference
android:key="fuck_no_proxy" android:key="fuck_no_proxy"
android:title="反防抓包" android:title="反防抓包"
android:summary="效果不太明显,目前只发现账号相关的有反防抓包" /> android:summary="目前只发现账号相关的有反防抓包,真无法抓包就去刷原生安卓吧,亲测有效" />
</PreferenceCategory>
<PreferenceCategory android:title="评论">
<SwitchPreference
android:key="force_top_comment"
android:title="强制置顶评论"
android:summary="灵感来源于 CodeCat可以无视作品作者直接置顶评论注意只支持 Nemo 作品其它无效响应406码" />
<SwitchPreference
android:key="fuck_miao"
android:title="别屏蔽我词语!"
android:summary="让部分屏蔽词无法再被屏蔽,请勿用于恶语相向,否则被举报不要来找我!!\n可能会导致缩短评论字数上限算法有待优化" />
<Preference
android:key="see_miao"
android:title="查看支持防屏蔽的词汇"
android:summary="对应上面的 防屏蔽" />
</PreferenceCategory> </PreferenceCategory>
@@ -42,15 +66,41 @@
<SwitchPreference <SwitchPreference
android:key="fuck_fcm" android:key="fuck_fcm"
android:title="绕过防沉迷" android:title="绕过防沉迷"
android:summary="滞空防沉迷检测方法的调用实现无伤速通破解防沉迷,无需 Player 链接" /> android:summary="滞空防沉迷检测方法的调用实现无伤速通破解防沉迷,无需 Player 链接不支持叽叽猫砸进里面的岛3不支持内嵌社区网页的防沉迷那不属于我的能力范围" />
<SwitchPreference
android:key="force_set_work_myown"
android:title="谋权篡位"
android:summary="伪装任意作品是你自己的,可以:\n直接编辑作品源码\n其他用途" />
<SwitchPreference
android:key="fuck_box3recommend"
android:title="岛3我推荐你吗"
android:summary="机吧猫砸进里面的玩意实际上还不如去研究如何优化 Nemo 客户端,打开后主页将没有四个岛三作品引流\n提示还没修好等我修修不然你会进不去主页的哦" />
<SwitchPreference
android:key="work_is_valid"
android:title="作品没有失效"
android:summary="让作品的发布时间大于0可以绕过收藏作品的“失效”状态" />
<SwitchPreference
android:key="fix_kn_player"
android:title="修复 KN 作品无法打开"
android:summary="去你吗的Nemo推广(UA检测),去你妈的 ?is_nemo_player 害得我无法打开我直接把它机吧割了QSWL\n本功能仅需要时启用5.0.0用户请不要启用" />
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory android:title="已弃用"> <PreferenceCategory android:title="实验">
<SwitchPreference
android:key="test"
android:title="未命名实验功能"
android:summary="实验" />
<SwitchPreference <SwitchPreference
android:key="force_show_rework" android:key="force_show_rework"
android:title="强制显示再创作图标" android:title="强制显示再创作图标"
android:summary="使作品的 再创作 按钮永远显示,即使作品并未设置为开放源代码(显示了也没啥用,服务端给你拦截了:作品未开源" /> android:summary="使作品的 再创作 按钮永远显示,即使作品并未设置为开放源代码(显示了也没啥用,服务端给你拦截了,报错信息为 作品未开源,亲测无效" />
</PreferenceCategory> </PreferenceCategory>
</PreferenceScreen> </PreferenceScreen>

View File

@@ -2,6 +2,8 @@
弥补 编程猫Nemo/点个猫 的不合理特性,功能增强等特性(。・ω・。) 弥补 编程猫Nemo/点个猫 的不合理特性,功能增强等特性(。・ω・。)
提示:本项目只在 GitHub 存在, **严禁任何人或任何组织在没有得到我的书面许可、公告明示许可及社交账号发帖许可的情况下照搬本仓库** <!-- GitCode, 说的就是你, 到时候如果被我发现你搬我仓库我迟早要找你算账 -->
### For non-Chinese users ### For non-Chinese users
This project is for Codemao Nemo. Most of the time, you needn't use this Xposed module. This project is for Codemao Nemo. Most of the time, you needn't use this Xposed module.