Merge pull request #1 from cinit/qwq233-patch-1

refactor: cardMsg and batchMsg statistics
This commit is contained in:
Acetylcholine
2022-02-10 18:10:16 +08:00
committed by GitHub
6 changed files with 153 additions and 120 deletions

View File

@@ -33,11 +33,11 @@ import io.github.qauxv.base.annotation.FunctionHookEntry;
import io.github.qauxv.base.annotation.UiItemAgentEntry;
import io.github.qauxv.bridge.AppRuntimeHelper;
import io.github.qauxv.dsl.FunctionEntryRouter.Locations.Auxiliary;
import io.github.qauxv.remote.TransactionHelper;
import io.github.qauxv.router.decorator.BaseSwitchFunctionDecorator;
import io.github.qauxv.router.decorator.IInputButtonDecorator;
import io.github.qauxv.router.dispacher.InputButtonHookDispatcher;
import io.github.qauxv.step.Step;
import io.github.qauxv.util.CliOper;
import io.github.qauxv.util.DexKit;
import io.github.qauxv.util.Log;
import io.github.qauxv.util.Toasts;
@@ -99,7 +99,6 @@ public class CardMsgSender extends BaseSwitchFunctionDecorator implements IInput
try {
if (CardMsgSender.ntSendCardMsg(qqApp, session, text)) {
SyncUtils.runOnUiThread(() -> input.setText(""));
CliOper.sendCardMsg(AppRuntimeHelper.getLongAccountUin(), text);
} else {
Toasts.error(ctx1, "XML语法错误(代码有误)");
}
@@ -115,7 +114,6 @@ public class CardMsgSender extends BaseSwitchFunctionDecorator implements IInput
// Object arkMsg = load("com.tencent.mobileqq.data.ArkAppMessage").newInstance();
if (CardMsgSender.ntSendCardMsg(qqApp, session, text)) {
SyncUtils.runOnUiThread(() -> input.setText(""));
CliOper.sendCardMsg(AppRuntimeHelper.getLongAccountUin(), text);
} else {
Toasts.error(ctx1, "JSON语法错误(代码有误)");
}

View File

@@ -33,7 +33,10 @@ import io.github.qauxv.base.annotation.FunctionHookEntry
import io.github.qauxv.base.annotation.UiItemAgentEntry
import io.github.qauxv.dsl.FunctionEntryRouter
import io.github.qauxv.hook.CommonSwitchFunctionHook
import io.github.qauxv.util.*
import io.github.qauxv.util.CustomMenu
import io.github.qauxv.util.DexKit
import io.github.qauxv.util.Initiator
import io.github.qauxv.util.Toasts
import xyz.nextalone.util.SystemServiceUtils.copyToClipboard
import xyz.nextalone.util.throwOrTrue
import java.lang.reflect.Array
@@ -121,7 +124,6 @@ object CopyCardMsg : CommonSwitchFunctionHook("CopyCardMsg::BaseChatPie") {
*arrayOfNulls(0)) as String
copyToClipboard(ctx, text)
Toasts.info(ctx, "复制成功")
CliOper.copyCardMsg(text)
} else if (Initiator.load("com.tencent.mobileqq.data.MessageForArkApp")
.isAssignableFrom(chatMessage.javaClass)) {
val text = Reflex.invokeVirtual(
@@ -129,7 +131,6 @@ object CopyCardMsg : CommonSwitchFunctionHook("CopyCardMsg::BaseChatPie") {
*arrayOfNulls(0)) as String
copyToClipboard(ctx, text)
Toasts.info(ctx, "复制成功")
CliOper.copyCardMsg(text)
}
}
}

View File

@@ -49,9 +49,7 @@ import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;
import io.github.qauxv.bridge.AppRuntimeHelper;
import io.github.qauxv.bridge.FaceImpl;
import io.github.qauxv.util.CliOper;
import io.github.qauxv.util.LicenseStatus;
import io.github.qauxv.util.Log;
import io.github.qauxv.util.Toasts;
@@ -78,7 +76,7 @@ public class SendBatchMsg {
editText.setMinLines(4);
editText.setGravity(Gravity.TOP);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(MATCH_PARENT,
WRAP_CONTENT);
WRAP_CONTENT);
layoutParams.setMargins(padding, dip2px(context, 10.0f), padding, 10);
editText.setLayoutParams(layoutParams);
linearLayout.addView(editText);
@@ -117,36 +115,36 @@ public class SendBatchMsg {
LinearLayout linearLayout = getEditView(exactCtx);
final EditText editText = (EditText) linearLayout.getChildAt(0);
final AlertDialog alertDialog = new AlertDialog.Builder(exactCtx,
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1
? android.R.style.Theme_DeviceDefault_Light_Dialog_Alert
: AlertDialog.THEME_DEVICE_DEFAULT_LIGHT)
.setTitle("输入群发文本")
.setView(linearLayout)
.setPositiveButton("选择群发对象", null)
.setNegativeButton("取消", null)
.create();
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1
? android.R.style.Theme_DeviceDefault_Light_Dialog_Alert
: AlertDialog.THEME_DEVICE_DEFAULT_LIGHT)
.setTitle("输入群发文本")
.setView(linearLayout)
.setPositiveButton("选择群发对象", null)
.setNegativeButton("取消", null)
.create();
alertDialog.show();
setEditDialogStyle(alertDialog);
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE)
.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String msg = editText.getText().toString();
if (msg.isEmpty() || msg.equals("")) {
Toasts.error(exactCtx, "请输入文本消息");
} else {
if (msg.length() > 6 && !LicenseStatus.isAsserted()) {
Toasts.error(exactCtx, "超出字数限制:输入被限制在五个字以内");
.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String msg = editText.getText().toString();
if (msg.isEmpty() || msg.equals("")) {
Toasts.error(exactCtx, "请输入文本消息");
} else {
try {
showSelectDialog(exactCtx, msg);
} catch (Throwable e) {
Log.e(e);
if (msg.length() > 6 && !LicenseStatus.isAsserted()) {
Toasts.error(exactCtx, "超出字数限制:输入被限制在五个字以内");
} else {
try {
showSelectDialog(exactCtx, msg);
} catch (Throwable e) {
Log.e(e);
}
}
}
}
}
});
});
} catch (Throwable e) {
Log.e(e);
}
@@ -158,30 +156,30 @@ public class SendBatchMsg {
@SuppressWarnings("deprecation")
private static void showSelectDialog(final Context context, final String msg) throws Throwable {
final TroopAndFriendSelectAdpter troopAndFriendSelectAdpter = new TroopAndFriendSelectAdpter(
context);
context);
final AlertDialog alertDialog = new AlertDialog.Builder(context,
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1
? android.R.style.Theme_DeviceDefault_Light_Dialog_Alert
: AlertDialog.THEME_DEVICE_DEFAULT_LIGHT)
.setTitle("发送到")
.setView(getListView(context, msg, troopAndFriendSelectAdpter))
.setPositiveButton("发送", (dialog, which) -> {
HashSet<ContactDescriptor> arrayList = troopAndFriendSelectAdpter.mTargets;
if (!arrayList.isEmpty()) {
int size = arrayList.size();
int[] type = new int[size];
long[] uins = new long[size];
int i = 0;
for (ContactDescriptor target : arrayList) {
if (i < size) {
type[i] = target.uinType;
uins[i] = Long.parseLong(target.uin);
Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1
? android.R.style.Theme_DeviceDefault_Light_Dialog_Alert
: AlertDialog.THEME_DEVICE_DEFAULT_LIGHT)
.setTitle("发送到")
.setView(getListView(context, msg, troopAndFriendSelectAdpter))
.setPositiveButton("发送", (dialog, which) -> {
HashSet<ContactDescriptor> arrayList = troopAndFriendSelectAdpter.mTargets;
if (!arrayList.isEmpty()) {
int size = arrayList.size();
int[] type = new int[size];
long[] uins = new long[size];
int i = 0;
for (ContactDescriptor target : arrayList) {
if (i < size) {
type[i] = target.uinType;
uins[i] = Long.parseLong(target.uin);
}
i++;
}
i++;
}
boolean isSuccess = ntSendBatchMessages(getQQAppInterface(), context, msg,
type, uins);
CliOper.batchSendMsg(AppRuntimeHelper.getLongAccountUin(), msg, arrayList.size());
// TODO: 群发文本记录
try {
Toasts.showToast(context, Toasts.TYPE_INFO,
"发送" + (isSuccess ? "成功" : "失败"), Toast.LENGTH_SHORT);
@@ -202,23 +200,23 @@ public class SendBatchMsg {
alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(0xff4284f3);
alertDialog.getButton(AlertDialog.BUTTON_NEUTRAL).setTextColor(0xff4284f3);
alertDialog.getButton(AlertDialog.BUTTON_NEUTRAL)
.setOnClickListener(v -> troopAndFriendSelectAdpter.setAllSelect());
.setOnClickListener(v -> troopAndFriendSelectAdpter.setAllSelect());
troopAndFriendSelectAdpter.sendBtn = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
new android.os.Handler().postDelayed(() -> troopAndFriendSelectAdpter.notifyDataSetChanged(), 1000);
}
@SuppressWarnings("JavaJniMissingFunction")
static native boolean ntSendBatchMessages(AppRuntime rt, Context ctx, String msg, int[] type,
long[] uin);
long[] uin);
private static View getListView(Context context, String sendMsg,
final TroopAndFriendSelectAdpter troopAndFriendSelectAdpter) {
final TroopAndFriendSelectAdpter troopAndFriendSelectAdpter) {
final EditText editText = new EditText(context);
editText.setBackgroundColor(0x00000000);
editText.setHint("搜索");
editText.setTextSize(18.0f);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(MATCH_PARENT,
dip2px(context, 30.0f));
dip2px(context, 30.0f));
layoutParams.setMargins(dip2px(context, 30.0f), 0, dip2px(context, 30.0f), 10);
editText.setLayoutParams(layoutParams);
final ListView listView = new ListView(context);
@@ -273,7 +271,7 @@ public class SendBatchMsg {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TroopAndFriendSelectAdpter.ViewHolder viewHolder = (TroopAndFriendSelectAdpter.ViewHolder) view
.getTag();
.getTag();
viewHolder.cBox.toggle();
}
});
@@ -348,26 +346,26 @@ public class SendBatchMsg {
viewHolder.title = (TextView) linearLayout.getChildAt(2);
convertView.setTag(viewHolder);
viewHolder.cBox
.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
ContactDescriptor cd = ((ViewHolder) ((View) buttonView.getParent())
.getTag()).mUin;
if (isChecked) {
mTargets.add(cd);
} else {
mTargets.remove(cd);
}
if (sendBtn != null) {
int size = mTargets.size();
if (size != 0) {
sendBtn.setText("发送(" + size + ")");
.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
ContactDescriptor cd = ((ViewHolder) ((View) buttonView.getParent())
.getTag()).mUin;
if (isChecked) {
mTargets.add(cd);
} else {
sendBtn.setText("发送");
mTargets.remove(cd);
}
if (sendBtn != null) {
int size = mTargets.size();
if (size != 0) {
sendBtn.setText("发送(" + size + ")");
} else {
sendBtn.setText("发送");
}
}
}
}
});
});
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
@@ -385,19 +383,19 @@ public class SendBatchMsg {
int imgHeight = dip2px(context, 40.0f);
LinearLayout linearLayout = new LinearLayout(context);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(MATCH_PARENT,
WRAP_CONTENT);
WRAP_CONTENT);
linearLayout.setLayoutParams(layoutParams);
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
linearLayout.setPadding(padding, 15, padding, 25);
LinearLayout.LayoutParams layoutParams1 = new LinearLayout.LayoutParams(WRAP_CONTENT,
WRAP_CONTENT);
WRAP_CONTENT);
layoutParams1.gravity = Gravity.CENTER_VERTICAL;
CheckBox check = new CheckBox(context);
check.setFocusable(false);
check.setClickable(false);
ImageView imageView = new ImageView(context);
@SuppressWarnings("SuspiciousNameCombination") LinearLayout.LayoutParams layoutParams2 = new LinearLayout.LayoutParams(
imgHeight, imgHeight);
imgHeight, imgHeight);
layoutParams2.gravity = Gravity.CENTER_VERTICAL;
layoutParams2.setMargins(imgPadding, 0, imgPadding, 0);
imageView.setLayoutParams(layoutParams2);

View File

@@ -73,4 +73,83 @@ public class TransactionHelper {
return -1;
}
}
/**
* 记录发送卡片信息
*
* @param uin 发送者qq号
* @param msg 卡片内容
* @return 是否上报成功 成功返回null 失败返回理由 成功返回null 失败返回理由
*/
public static String postCardMsg(long uin, String msg) {
try {
URL url = new URL(apiAddress + "/statistics/card/send");
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json; utf-8");
conn.setRequestProperty("Accept", "application/json");
DataOutputStream os = new DataOutputStream(conn.getOutputStream());
JSONObject request = new JSONObject();
request.put("uin", uin);
request.put("msg", msg);
os.writeBytes(request.toString());
os.flush();
os.close();
JSONObject resp = new JSONObject(convertInputStreamToString(conn.getInputStream()));
if (resp.getInt("code") == 200) {
return null;
} else {
return resp.getString("reason");
}
} catch (Exception e) {
Log.e(e);
return "server is offline";
}
}
/**
* 记录群发文本
*
* @param uin 发送者qq号
* @param msg 群发文本
* @param count 数量
* @return 是否上报成功 成功返回null 失败返回理由 失败有可能是服务端出现问题 也有可能是服务端认为非法
*/
public static String postBatchMsg(long uin, String msg, int count) {
try {
if (msg == null) {
msg = "msg is null";
}
URL url = new URL(apiAddress + "/statistics/batch");
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json; utf-8");
conn.setRequestProperty("Accept", "application/json");
DataOutputStream os = new DataOutputStream(conn.getOutputStream());
JSONObject request = new JSONObject();
request.put("uin", uin);
request.put("msg", msg);
request.put("count", count);
os.writeBytes(request.toString());
os.flush();
os.close();
JSONObject resp = new JSONObject(convertInputStreamToString(conn.getInputStream()));
if (resp.getInt("code") == 200) {
return null;
} else {
return resp.getString("reason");
}
} catch (Exception e) {
Log.e(e);
return "server is offline";
}
}
}

View File

@@ -119,47 +119,6 @@ public class CliOper {
Log.d("start App Center Trace OnLoad:" + properties.toString());
}
public static void copyCardMsg(String msg) {
if (msg == null) {
return;
}
__init__(HostInfo.getApplication());
try {
Analytics.trackEvent("copyCardMsg", digestCardMsg(msg));
} catch (Throwable e) {
Log.e(e);
}
}
public static void sendCardMsg(long uin, String msg) {
if (msg == null) {
return;
}
__init__(HostInfo.getApplication());
try {
Map<String, String> prop = digestCardMsg(msg);
prop.put("uin", String.valueOf(uin));
Analytics.trackEvent("sendCardMsg", prop);
} catch (Throwable e) {
Log.e(e);
}
}
public static void batchSendMsg(long uin, String msg, int count) {
if (msg == null) {
return;
}
Map<String, String> properties = new HashMap<>();
if (msg.length() > 127) {
msg = msg.substring(0, 127);
}
properties.put("msg", msg);
properties.put("uin", String.valueOf(uin));
properties.put("count", String.valueOf(count));
__init__(HostInfo.getApplication());
Analytics.trackEvent("batchSendMsg", properties);
}
private static Map<String, String> digestCardMsg(String msg) {
Map<String, String> prop = new HashMap<>();
if (msg.startsWith("<")) {

View File

@@ -30,7 +30,6 @@ import io.github.qauxv.base.annotation.FunctionHookEntry
import io.github.qauxv.base.annotation.UiItemAgentEntry
import io.github.qauxv.dsl.FunctionEntryRouter
import io.github.qauxv.hook.CommonSwitchFunctionHook
import io.github.qauxv.util.CliOper
import io.github.qauxv.util.CustomMenu
import io.github.qauxv.util.Toasts
import xyz.nextalone.util.*
@@ -86,7 +85,6 @@ object GuildCopyCardMsg : CommonSwitchFunctionHook() {
}
copyToClipboard(ctx, text)
Toasts.info(ctx, "复制成功")
CliOper.copyCardMsg(text)
fragment.invoke("dismiss")
}
}