项目更新
This commit is contained in:
parent
82158467f9
commit
c72667123f
15
.vscode/launch.json
vendored
Normal file
15
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
// 使用 IntelliSense 了解相关属性。
|
||||
// 悬停以查看现有属性的描述。
|
||||
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "kafka comsumer",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"program": "${workspaceFolder}/kafka/main.go"
|
||||
}
|
||||
]
|
||||
}
|
||||
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@ -1,4 +1,4 @@
|
||||
{
|
||||
"ansible.python.interpreterPath": "c:\\Users\\U\\AppData\\Local\\Microsoft\\WindowsApps\\python3.12.exe",
|
||||
"workbench.colorTheme":"Quiet Light"
|
||||
"workbench.colorTheme":"GitHub Dark Colorblind (Beta)"
|
||||
}
|
||||
8
README.md
Normal file
8
README.md
Normal file
@ -0,0 +1,8 @@
|
||||
# 生成一个新的脚本文件
|
||||
## 生成步骤
|
||||
1.脚本语言使用python3
|
||||
2.脚本文件名为`script.py`
|
||||
3.备份mysql数据库的数据
|
||||
4.清空mysql数据库的数据
|
||||
5.清空redis数据库的数据
|
||||
|
||||
1
access_token.txt
Normal file
1
access_token.txt
Normal file
@ -0,0 +1 @@
|
||||
ya29.a0ARW5m75vC6Xu3uPbWDPkCFnfJ20ppzCFfblGfKlCdBxqWvKnMP1w1TX3GO6ylh7IbRrBqh83mSZyS9-fNxjPmI0eynjAH8Z6O-2rcJtaI_s-pBWRJV3FI5rkLeDiMahq7HAHVhJsnIJAqOKZ1M9zL43zrwjUJPxTrMLxzXNdMgaCgYKAdESARISFQHGX2Mis6ycpB32JnANYYLmP25gxA0177
|
||||
280
backups/Merge_Pet_1_20250709_024705.sql
Normal file
280
backups/Merge_Pet_1_20250709_024705.sql
Normal file
@ -0,0 +1,280 @@
|
||||
-- MySQL dump 10.13 Distrib 8.0.42, for Linux (x86_64)
|
||||
--
|
||||
-- Host: 172.20.0.5 Database: Merge_Pet_1
|
||||
-- ------------------------------------------------------
|
||||
-- Server version 8.4.5
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!50503 SET NAMES utf8mb4 */;
|
||||
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
||||
/*!40103 SET TIME_ZONE='+00:00' */;
|
||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||
|
||||
--
|
||||
-- Table structure for table `db_version`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `db_version`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `db_version` (
|
||||
`version_2018_02_06_13` int unsigned NOT NULL COMMENT 'version'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='数据库版本号';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `db_version`
|
||||
--
|
||||
|
||||
LOCK TABLES `db_version` WRITE;
|
||||
/*!40000 ALTER TABLE `db_version` DISABLE KEYS */;
|
||||
/*!40000 ALTER TABLE `db_version` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `system_mail_info`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `system_mail_info`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `system_mail_info` (
|
||||
`mail_id` bigint NOT NULL AUTO_INCREMENT COMMENT '邮件ID',
|
||||
`title` varchar(128) DEFAULT '' COMMENT '邮件标题',
|
||||
`content` varchar(2048) DEFAULT '' COMMENT '邮件内容',
|
||||
`title_en` varchar(128) DEFAULT '' COMMENT '英文邮件标题',
|
||||
`content_en` varchar(2048) DEFAULT '' COMMENT '英文邮件内容',
|
||||
`items` varchar(2048) DEFAULT '{}' COMMENT '邮件附件',
|
||||
`start_time` int unsigned NOT NULL DEFAULT '0' COMMENT '开始时间',
|
||||
`register_time` int unsigned NOT NULL DEFAULT '0' COMMENT '注册时间',
|
||||
`end_time` int unsigned NOT NULL DEFAULT '0' COMMENT '结束时间',
|
||||
`mail_type` int unsigned NOT NULL DEFAULT '0' COMMENT '邮件类型',
|
||||
`send_type` int unsigned NOT NULL DEFAULT '0' COMMENT '发送类型',
|
||||
`to_uids` varchar(2048) DEFAULT '' COMMENT '发送者ID',
|
||||
`create_time` int unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
|
||||
PRIMARY KEY (`mail_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='系统邮件';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `system_mail_info`
|
||||
--
|
||||
|
||||
LOCK TABLES `system_mail_info` WRITE;
|
||||
/*!40000 ALTER TABLE `system_mail_info` DISABLE KEYS */;
|
||||
/*!40000 ALTER TABLE `system_mail_info` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `t_account`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `t_account`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `t_account` (
|
||||
`user_name` varchar(50) COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`user_password` varchar(128) COLLATE utf8mb4_general_ci NOT NULL,
|
||||
`login_time` int unsigned DEFAULT '0' COMMENT '上次登录时间',
|
||||
`logout_time` int unsigned DEFAULT '0' COMMENT '上次下线时间',
|
||||
`ip_address` char(24) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '上次登录的ip地址',
|
||||
`gm_level` int DEFAULT '0' COMMENT 'gm等级',
|
||||
`platform` varchar(50) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '平台',
|
||||
`is_online` int unsigned DEFAULT '0' COMMENT '角色是否在线',
|
||||
`channel` varchar(50) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '渠道号',
|
||||
`device_id` varchar(256) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '是否为刷榜账号',
|
||||
`auto_id` bigint NOT NULL AUTO_INCREMENT COMMENT '自增id',
|
||||
`id_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '""',
|
||||
`id_num` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '""',
|
||||
PRIMARY KEY (`auto_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='账号密码对照表';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `t_account`
|
||||
--
|
||||
|
||||
LOCK TABLES `t_account` WRITE;
|
||||
/*!40000 ALTER TABLE `t_account` DISABLE KEYS */;
|
||||
/*!40000 ALTER TABLE `t_account` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `t_gameserver`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `t_gameserver`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `t_gameserver` (
|
||||
`id` int unsigned NOT NULL COMMENT '服务器id',
|
||||
`start_time` int unsigned DEFAULT NULL COMMENT '开服时间',
|
||||
`close_time` int unsigned DEFAULT NULL COMMENT '关服时间',
|
||||
`is_close` int unsigned DEFAULT NULL COMMENT '是否关服',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='服务器设置';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `t_gameserver`
|
||||
--
|
||||
|
||||
LOCK TABLES `t_gameserver` WRITE;
|
||||
/*!40000 ALTER TABLE `t_gameserver` DISABLE KEYS */;
|
||||
/*!40000 ALTER TABLE `t_gameserver` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `t_player_baseinfo`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `t_player_baseinfo`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `t_player_baseinfo` (
|
||||
`dwUin` bigint unsigned NOT NULL COMMENT '对应玩家account表中的dwUin',
|
||||
`energy` int unsigned NOT NULL DEFAULT '0' COMMENT '能量',
|
||||
`star` int unsigned NOT NULL DEFAULT '0' COMMENT '星星',
|
||||
`recover_time` int unsigned NOT NULL DEFAULT '0' COMMENT '能量开始恢复时间',
|
||||
`diamond` int unsigned NOT NULL DEFAULT '1' COMMENT '钻石',
|
||||
`level` int unsigned NOT NULL DEFAULT '0' COMMENT '玩家等级',
|
||||
`exp` int(10) unsigned zerofill NOT NULL DEFAULT '0000000000' COMMENT '玩家经验',
|
||||
`start_order_id` varchar(50) DEFAULT NULL COMMENT '配置订单进度',
|
||||
`music_code` int unsigned NOT NULL DEFAULT '0' COMMENT '音效状态码改为GUID免费改名状态',
|
||||
`guild` int unsigned NOT NULL DEFAULT '0' COMMENT '引导进度 ',
|
||||
`pack_unlock_count` int unsigned NOT NULL DEFAULT '0' COMMENT '背包解锁数量',
|
||||
`last_play_time` int NOT NULL DEFAULT '0' COMMENT '广告能量购买时间',
|
||||
`EnergyBuyCount` int NOT NULL DEFAULT '0' COMMENT '能量购买次数',
|
||||
`user_name` varchar(50) NOT NULL DEFAULT '' COMMENT '玩家账号',
|
||||
`nick_name` varchar(50) NOT NULL DEFAULT '' COMMENT '玩家昵称',
|
||||
`login_time` int unsigned NOT NULL DEFAULT '0' COMMENT '上次登录时间',
|
||||
`logout_time` int unsigned NOT NULL DEFAULT '0' COMMENT '上次下线时间',
|
||||
`todayolinetime` int unsigned NOT NULL DEFAULT '0' COMMENT '当天的累计在线时间',
|
||||
`rolecreatetime` int unsigned NOT NULL DEFAULT '0' COMMENT '注册帐号时间',
|
||||
`EmitOrderCnt` int unsigned NOT NULL DEFAULT '0' COMMENT '注册帐号时间',
|
||||
`DailyRenewTime` int unsigned NOT NULL DEFAULT '0' COMMENT '注册帐号时间',
|
||||
`NoAd` int unsigned NOT NULL DEFAULT '0' COMMENT '注册帐号时间',
|
||||
`ChampshipsGroupID` int unsigned NOT NULL DEFAULT '0' COMMENT '注册帐号时间',
|
||||
`LastChampGroupID` int unsigned NOT NULL DEFAULT '0' COMMENT '注册帐号时间',
|
||||
`FaceBookId` varchar(128) DEFAULT '' COMMENT '玩家账号',
|
||||
PRIMARY KEY (`dwUin`),
|
||||
KEY `nick_name` (`nick_name`),
|
||||
KEY `user_name` (`user_name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='存储玩家基本信息';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `t_player_baseinfo`
|
||||
--
|
||||
|
||||
LOCK TABLES `t_player_baseinfo` WRITE;
|
||||
/*!40000 ALTER TABLE `t_player_baseinfo` DISABLE KEYS */;
|
||||
/*!40000 ALTER TABLE `t_player_baseinfo` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `t_player_charge`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `t_player_charge`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `t_player_charge` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '订单id',
|
||||
`Uid` bigint unsigned NOT NULL COMMENT '玩家id',
|
||||
`OrderId` varchar(128) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '订单号',
|
||||
`ProductId` int unsigned NOT NULL DEFAULT '0' COMMENT '商品id',
|
||||
`ProductName` varchar(128) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '商品名称',
|
||||
`ProductDesc` varchar(128) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '商品描述',
|
||||
`Price` float NOT NULL DEFAULT '0' COMMENT '价格',
|
||||
`Currency` varchar(128) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '货币',
|
||||
`CreateTime` int unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
|
||||
`PayTime` int unsigned NOT NULL DEFAULT '0' COMMENT '支付时间',
|
||||
`PayStatus` int unsigned NOT NULL DEFAULT '0' COMMENT '支付状态 0 未支付 1 已支付 2 支付失败 3 已发货',
|
||||
`PayType` int unsigned NOT NULL DEFAULT '0' COMMENT '支付类型',
|
||||
`PayPlatform` varchar(128) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '支付平台',
|
||||
`PayChannel` varchar(128) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '支付渠道',
|
||||
`PayChannelOrderId` varchar(512) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '支付渠道订单号',
|
||||
`PayChannelUserId` varchar(128) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '支付渠道用户id',
|
||||
`PayChannelExtra` varchar(128) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '支付渠道额外信息',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='玩家订单表';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `t_player_charge`
|
||||
--
|
||||
|
||||
LOCK TABLES `t_player_charge` WRITE;
|
||||
/*!40000 ALTER TABLE `t_player_charge` DISABLE KEYS */;
|
||||
/*!40000 ALTER TABLE `t_player_charge` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `t_player_mod`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `t_player_mod`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `t_player_mod` (
|
||||
`dwUin` bigint unsigned NOT NULL COMMENT '玩家uid',
|
||||
`mData` blob COMMENT '数据',
|
||||
`updateTime` int unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
|
||||
PRIMARY KEY (`dwUin`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='玩家模块表';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `t_player_mod`
|
||||
--
|
||||
|
||||
LOCK TABLES `t_player_mod` WRITE;
|
||||
/*!40000 ALTER TABLE `t_player_mod` DISABLE KEYS */;
|
||||
/*!40000 ALTER TABLE `t_player_mod` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Table structure for table `t_server_mod`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `t_server_mod`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!50503 SET character_set_client = utf8mb4 */;
|
||||
CREATE TABLE `t_server_mod` (
|
||||
`id` int NOT NULL AUTO_INCREMENT,
|
||||
`key` varchar(128) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '模块key',
|
||||
`mData` mediumblob COMMENT '数据',
|
||||
`updateTime` int unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='系统模块表';
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Dumping data for table `t_server_mod`
|
||||
--
|
||||
|
||||
LOCK TABLES `t_server_mod` WRITE;
|
||||
/*!40000 ALTER TABLE `t_server_mod` DISABLE KEYS */;
|
||||
/*!40000 ALTER TABLE `t_server_mod` ENABLE KEYS */;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--
|
||||
-- Dumping routines for database 'Merge_Pet_1'
|
||||
--
|
||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||
|
||||
-- Dump completed on 2025-07-09 2:47:05
|
||||
4
backups/redis_20250709_024705.txt
Normal file
4
backups/redis_20250709_024705.txt
Normal file
@ -0,0 +1,4 @@
|
||||
# Redis数据导出
|
||||
# 导出时间: 2025-07-09 02:47:06.709571
|
||||
|
||||
# Redis数据库为空
|
||||
BIN
dist/verifyOrder
vendored
Normal file
BIN
dist/verifyOrder
vendored
Normal file
Binary file not shown.
BIN
dist/verifyOrder.exe
vendored
Normal file
BIN
dist/verifyOrder.exe
vendored
Normal file
Binary file not shown.
BIN
dynamicLv_output.xlsx
Normal file
BIN
dynamicLv_output.xlsx
Normal file
Binary file not shown.
59
format_language_csv.py
Normal file
59
format_language_csv.py
Normal file
@ -0,0 +1,59 @@
|
||||
import re
|
||||
import csv
|
||||
from pathlib import Path
|
||||
|
||||
SRC = Path(r"d:\Github\docs\config\LanguageDataTwo.csv")
|
||||
if not SRC.exists():
|
||||
print(f"Source not found: {SRC}")
|
||||
raise SystemExit(1)
|
||||
|
||||
# 备份原文件
|
||||
bak = SRC.with_suffix(SRC.suffix + ".bak")
|
||||
if not bak.exists():
|
||||
bak.write_bytes(SRC.read_bytes())
|
||||
|
||||
out_rows = []
|
||||
with SRC.open("r", encoding="utf-8") as f:
|
||||
for raw in f:
|
||||
line = raw.rstrip("\n")
|
||||
if not line.strip():
|
||||
continue
|
||||
# 跳过首部注释行(以#开头)
|
||||
if line.lstrip().startswith("#"):
|
||||
continue
|
||||
# 将连续两个或以上空格替换为制表符,便于分割(原文件里有制表或多空格分隔)
|
||||
norm = re.sub(r"[ \u00A0]{2,}", "\t", line)
|
||||
# 以制表符分割(如果没有制表符,会退化为按任意空格分割)
|
||||
parts = [p.strip() for p in re.split(r"\t+", norm)]
|
||||
# 如果分割后超过4列,则把第0,1固定,剩下的尽量合并为 English 和 Chinese 两列
|
||||
if len(parts) >= 4:
|
||||
id_, key = parts[0], parts[1]
|
||||
# English 可能包含制表/空格,取中间所有并把最后一列当作中文
|
||||
eng = " ".join(parts[2:-1]).strip()
|
||||
chi = parts[-1].strip()
|
||||
out_rows.append((id_, key, eng, chi))
|
||||
elif len(parts) == 3:
|
||||
id_, key, rest = parts
|
||||
# 无法区分 English / Chinese,尝试按中文字符后半部分切分(保守策略)
|
||||
m = re.search(r"[\u4e00-\u9fff]+", rest)
|
||||
if m:
|
||||
idx = m.start()
|
||||
eng = rest[:idx].strip()
|
||||
chi = rest[idx:].strip()
|
||||
else:
|
||||
eng = rest
|
||||
chi = ""
|
||||
out_rows.append((id_, key, eng, chi))
|
||||
else:
|
||||
# 无法解析的行,跳过或记录为备注行
|
||||
# 记录为空的键以便人工检查
|
||||
out_rows.append(("", "", line.strip(), ""))
|
||||
|
||||
# 写入标准 CSV(全部字段用双引号包裹)
|
||||
with SRC.open("w", encoding="utf-8", newline="") as out:
|
||||
writer = csv.writer(out, quoting=csv.QUOTE_ALL)
|
||||
writer.writerow(["Id", "key", "English", "ChineseSimplified"])
|
||||
for r in out_rows:
|
||||
writer.writerow(r)
|
||||
|
||||
print(f"Formatted CSV written to {SRC} (backup at {bak})")
|
||||
38
getToken.spec
Normal file
38
getToken.spec
Normal file
@ -0,0 +1,38 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
|
||||
a = Analysis(
|
||||
['script\\test.py'],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=[],
|
||||
hiddenimports=[],
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
noarchive=False,
|
||||
optimize=0,
|
||||
)
|
||||
pyz = PYZ(a.pure)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.datas,
|
||||
[],
|
||||
name='getToken',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=True,
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
)
|
||||
@ -53,7 +53,7 @@ func ProcessMsg(SqlDb *sqlx.DB, m kafka.Message) error {
|
||||
default:
|
||||
go event(SqlDb, m)
|
||||
}
|
||||
|
||||
offset(SqlDb, m)
|
||||
// if err != nil {
|
||||
// tx.Rollback()
|
||||
// return err
|
||||
@ -105,3 +105,10 @@ func pay(SqlDb *sqlx.DB, m kafka.Message) error {
|
||||
}
|
||||
return err
|
||||
}
|
||||
func offset(SqlDb *sqlx.DB, m kafka.Message) error {
|
||||
sql := " INSERT INTO `log_var` (`Key` , `Value`, `Timestamp`) Values (?,?,?) ON DUPLICATE KEY UPDATE `key` = ? , `Value` = ? ,`Timestamp`=?"
|
||||
Value := strconv.FormatInt(m.Offset+1, 10)
|
||||
Timestamp := util.GetNowTime()
|
||||
_, err := SqlDb.Exec(sql, "offset", Value, Timestamp, "offset", Value, Timestamp)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -1,57 +1,62 @@
|
||||
|
||||
services:
|
||||
# zoo1:
|
||||
# image: zookeeper
|
||||
# hostname: zoo1
|
||||
# container_name: zoo1
|
||||
# kafka1:
|
||||
# image: bitnami/kafka:latest
|
||||
# hostname: kafka-server-1
|
||||
# container_name: kafka-server-1
|
||||
# ports:
|
||||
# - "2181:2181"
|
||||
# - "9092:9092"
|
||||
# - "9093:9093"
|
||||
# volumes:
|
||||
# - zoo1_data:/data
|
||||
# - kafka1_data:/bitnami/kafka
|
||||
# environment:
|
||||
# ZOOKEEPER_CLIENT_PORT: 2181
|
||||
# ZOOKEEPER_SERVER_ID: 1
|
||||
# ZOOKEEPER_SERVERS: zoo1:2888:3888
|
||||
|
||||
kafka1:
|
||||
# KAFKA_CFG_NODE_ID: 0
|
||||
# KAFKA_KRAFT_CLUSTER_ID: kafka-cluster
|
||||
# KAFKA_CFG_BROKER_ID: 0
|
||||
# KAFKA_CFG_PROCESS_ROLES: controller,broker
|
||||
# KAFKA_CFG_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093
|
||||
# KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
|
||||
# KAFKA_CFG_CONTROLLER_QUORUM_VOTERS: 0@kafka-server-1:9093
|
||||
# KAFKA_CFG_CONTROLLER_LISTENER_NAMES: CONTROLLER
|
||||
kafka2:
|
||||
image: bitnami/kafka:latest
|
||||
hostname: kafka-server
|
||||
container_name: kafka-server
|
||||
restart: always
|
||||
hostname: kafka-server-3
|
||||
container_name: kafka-server-3
|
||||
ports:
|
||||
- "9092:9092"
|
||||
- "9093:9093"
|
||||
volumes:
|
||||
- kafka1_data:/bitnami/kafka
|
||||
- /data/kafka_data:/bitnami/kafka
|
||||
- /etc/hosts:/etc/hosts:ro # 只读方式挂载 hosts 文件
|
||||
environment:
|
||||
KAFKA_CFG_NODE_ID: 0
|
||||
KAFKA_CFG_PROCESS_ROLES: controller,broker
|
||||
KAFKA_CFG_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093
|
||||
KAFKA_CFG_NODE_ID: 3
|
||||
KAFKA_CFG_PROCESS_ROLES: broker
|
||||
KAFKA_CFG_BROKER_ID: 3
|
||||
KAFKA_KRAFT_CLUSTER_ID: 5abhbnhATXqNFrXsjiSmKw
|
||||
KAFKA_CFG_LISTENERS: PLAINTEXT://kafka-server-2:9092
|
||||
KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
|
||||
KAFKA_CFG_CONTROLLER_QUORUM_VOTERS: 0@kafka-server:9093
|
||||
KAFKA_CFG_CONTROLLER_QUORUM_VOTERS: 0@8.155.14.94:9093
|
||||
KAFKA_CFG_CONTROLLER_LISTENER_NAMES: CONTROLLER
|
||||
# KAFKA_CFG_ZOOKEEPER_CONNECT: zoo1:2181
|
||||
# depends_on:
|
||||
# - zoo1
|
||||
kafka-ui:
|
||||
container_name: kafka-ui
|
||||
restart: always
|
||||
image: provectuslabs/kafka-ui:latest
|
||||
ports:
|
||||
- 500:8080
|
||||
depends_on:
|
||||
- kafka1
|
||||
environment:
|
||||
DYNAMIC_CONFIG_ENABLED: "TRUE"
|
||||
|
||||
networks:
|
||||
default:
|
||||
name: kafka-network
|
||||
external: true
|
||||
# - kafka1
|
||||
|
||||
# kafka-ui:
|
||||
# container_name: kafka-ui
|
||||
# image: provectuslabs/kafka-ui:latest
|
||||
# ports:
|
||||
# - "500:8080"
|
||||
# depends_on:
|
||||
# - kafka1
|
||||
# - kafka2
|
||||
# environment:
|
||||
# DYNAMIC_CONFIG_ENABLED: "TRUE"
|
||||
|
||||
# networks:
|
||||
# default:
|
||||
# name: bridage
|
||||
# external: true
|
||||
|
||||
#volumes:
|
||||
# kafka4_data:
|
||||
# driver: local
|
||||
|
||||
volumes:
|
||||
zoo1_data:
|
||||
driver: local
|
||||
kafka1_data:
|
||||
driver: local
|
||||
|
||||
|
||||
12835
kafka/log/comsume.2025-12-04.log
Normal file
12835
kafka/log/comsume.2025-12-04.log
Normal file
File diff suppressed because it is too large
Load Diff
157
kafka/log/comsume.log
Normal file
157
kafka/log/comsume.log
Normal file
@ -0,0 +1,157 @@
|
||||
2025/12/04 14:58:58 comsumer start merge_pet_sdk
|
||||
2025/12/04 14:58:58 comsumer start pet_home
|
||||
2025/12/04 14:58:58 comsumer start Merge_Pet_online
|
||||
2025/12/04 14:58:58 comsumer start merge_pet_london
|
||||
2025/12/04 14:59:13 comsumer Merge_Pet_online received message: {"Uid":103348,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"45.172.146.93:53930","change_after":34,"change_num":1,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673638}
|
||||
2025/12/04 14:59:13 comsumer Merge_Pet_online received message: {"Uid":103348,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"45.172.146.93:53930","change_after":107,"change_num":1,"change_reason":"HandleChess","change_type":"gain","item_id":100002},"TimeStamp":1764673651}
|
||||
2025/12/04 14:59:13 comsumer Merge_Pet_online received message: {"Uid":103353,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"187.19.255.171:19132","change_after":14,"change_num":1,"change_reason":"recover_server","change_type":"gain","item_id":100001},"TimeStamp":1764673635}
|
||||
2025/12/04 14:59:13 comsumer Merge_Pet_online received message: {"Uid":102286,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"173.40.240.152:38188","change_after":25,"change_num":17,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673608}
|
||||
2025/12/04 14:59:13 comsumer Merge_Pet_online received message: {"Uid":103353,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"187.19.255.171:19132","change_after":13,"change_num":9,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673632}
|
||||
2025/12/04 14:59:13 comsumer Merge_Pet_online received message: {"Uid":103279,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"189.6.248.68:19583","change_after":100,"change_num":43,"change_reason":"recover_server","change_type":"gain","item_id":100001},"TimeStamp":1764673648}
|
||||
2025/12/04 14:59:13 comsumer Merge_Pet_online received message: {"Uid":103348,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"45.172.146.93:53930","change_after":38,"change_num":1,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673635}
|
||||
2025/12/04 14:59:13 comsumer Merge_Pet_online received message: {"Uid":103289,"AppId":0,"ServerId":1,"EventName":"sell_item","Param":{"#zone_offset":-5,"Ip":"170.239.38.36:53963","get_star_num":1,"merge_item_id":521,"product_name":"A Star"},"TimeStamp":1764673624}
|
||||
2025/12/04 14:59:15 comsumer Merge_Pet_online received message: {"Uid":103355,"AppId":0,"ServerId":1,"EventName":"ReqGetChessFromBuff","Param":{"#zone_offset":-5,"Ip":"177.173.235.32:29071","chess_id":85},"TimeStamp":1764673625}
|
||||
2025/12/04 14:59:15 comsumer Merge_Pet_online received message: {"Uid":100004,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"120.41.146.28:16858","change_after":167079,"change_num":3,"change_reason":"HandleChess","change_type":"gain","item_id":100002},"TimeStamp":1764673622}
|
||||
2025/12/04 14:59:15 comsumer Merge_Pet_online received message: {"Uid":103354,"AppId":0,"ServerId":1,"EventName":"order_finish","Param":{"#zone_offset":-5,"Ip":"138.36.7.60:37201","order_id":2,"order_item_id":[7],"order_item_reward":[],"order_star_reward":10,"order_star_value":149,"order_type":13,"preset_order_group":1,"preset_order_step":2},"TimeStamp":1764673617}
|
||||
2025/12/04 14:59:15 comsumer Merge_Pet_online received message: {"Uid":103357,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"45.4.57.69:43723","change_after":98,"change_num":1,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673640}
|
||||
2025/12/04 14:59:15 comsumer Merge_Pet_online received message: {"Uid":103289,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"170.239.38.36:53963","change_after":98,"change_num":1,"change_reason":"HandleChess","change_type":"gain","item_id":100002},"TimeStamp":1764673624}
|
||||
2025/12/04 14:59:15 comsumer Merge_Pet_online received message: {"Uid":102974,"AppId":0,"ServerId":1,"EventName":"ReqGetChessFromBuff","Param":{"#zone_offset":-5,"Ip":"200.138.90.205:39080","chess_id":1511},"TimeStamp":1764673644}
|
||||
2025/12/04 14:59:15 comsumer Merge_Pet_online received message: {"Uid":102974,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"200.138.90.205:39080","change_after":233,"change_num":40,"change_reason":"HandleChess","change_type":"gain","item_id":100001},"TimeStamp":1764673634}
|
||||
2025/12/04 14:59:15 comsumer Merge_Pet_online received message: {"Uid":103348,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"45.172.146.93:53930","change_after":32,"change_num":1,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673646}
|
||||
2025/12/04 14:59:15 comsumer Merge_Pet_online received message: {"Uid":103357,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"45.4.57.69:43723","change_after":99,"change_num":1,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673637}
|
||||
2025/12/04 14:59:15 comsumer Merge_Pet_online received message: {"Uid":102974,"AppId":0,"ServerId":1,"EventName":"ReqGetChessFromBuff","Param":{"#zone_offset":-5,"Ip":"200.138.90.205:39080","chess_id":565},"TimeStamp":1764673637}
|
||||
2025/12/04 14:59:16 comsumer Merge_Pet_online received message: {"Uid":103357,"AppId":0,"ServerId":1,"EventName":"collection_add","Param":{"#zone_offset":-5,"Ip":"45.4.57.69:43723","item_id":1,"item_name":"Fish-shaped Treats"},"TimeStamp":1764673637}
|
||||
2025/12/04 14:59:16 comsumer Merge_Pet_online received message: {"Uid":103348,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"45.172.146.93:53930","change_after":106,"change_num":1,"change_reason":"HandleChess","change_type":"gain","item_id":100002},"TimeStamp":1764673633}
|
||||
2025/12/04 14:59:16 comsumer Merge_Pet_online received message: {"Uid":103348,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"45.172.146.93:53930","change_after":35,"change_num":1,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673637}
|
||||
2025/12/04 14:59:16 comsumer Merge_Pet_online received message: {"Uid":103348,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"45.172.146.93:53930","change_after":40,"change_num":1,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673623}
|
||||
2025/12/04 14:59:16 comsumer Merge_Pet_online received message: {"Uid":103355,"AppId":0,"ServerId":1,"EventName":"collection_add","Param":{"#zone_offset":-5,"Ip":"177.173.235.32:29071","item_id":21,"item_name":"Cat Snack"},"TimeStamp":1764673636}
|
||||
2025/12/04 14:59:16 comsumer Merge_Pet_online received message: {"Uid":102974,"AppId":0,"ServerId":1,"EventName":"ReqGetChessFromBuff","Param":{"#zone_offset":-5,"Ip":"200.138.90.205:39080","chess_id":125},"TimeStamp":1764673611}
|
||||
2025/12/04 14:59:16 comsumer Merge_Pet_online received message: {"Uid":102286,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"173.40.240.152:38188","change_after":5104,"change_num":1,"change_reason":"HandleChess","change_type":"gain","item_id":100002},"TimeStamp":1764673625}
|
||||
2025/12/04 14:59:16 comsumer Merge_Pet_online received message: {"Uid":103354,"AppId":0,"ServerId":1,"EventName":"preset_order_birth","Param":{"#zone_offset":-5,"Ip":"138.36.7.60:37201","order_id":4,"order_item_id":[5],"preset_order_group":1,"preset_order_step":4},"TimeStamp":1764673642}
|
||||
2025/12/04 14:59:16 comsumer Merge_Pet_online received message: {"Uid":103357,"AppId":0,"ServerId":1,"EventName":"order_finish","Param":{"#zone_offset":-5,"Ip":"45.4.57.69:43723","order_id":1,"order_item_id":[3],"order_item_reward":[],"order_star_reward":2,"order_star_value":15,"order_type":13,"preset_order_group":1,"preset_order_step":1},"TimeStamp":1764673643}
|
||||
2025/12/04 14:59:16 comsumer Merge_Pet_online received message: {"Uid":103357,"AppId":0,"ServerId":1,"EventName":"preset_order_birth","Param":{"#zone_offset":-5,"Ip":"45.4.57.69:43723","order_id":2,"order_item_id":[7],"preset_order_group":1,"preset_order_step":2},"TimeStamp":1764673643}
|
||||
2025/12/04 14:59:16 comsumer Merge_Pet_online received message: {"Uid":103348,"AppId":0,"ServerId":1,"EventName":"sell_item","Param":{"#zone_offset":-5,"Ip":"45.172.146.93:53930","get_star_num":1,"merge_item_id":521,"product_name":"A Star"},"TimeStamp":1764673651}
|
||||
2025/12/04 14:59:16 comsumer Merge_Pet_online received message: {"Uid":103357,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"45.4.57.69:43723","change_after":2,"change_num":2,"change_reason":"OrderReward","change_type":"gain","item_id":100002},"TimeStamp":1764673643}
|
||||
2025/12/04 14:59:16 comsumer Merge_Pet_online received message: {"Uid":103348,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"45.172.146.93:53930","change_after":54,"change_num":1,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673586}
|
||||
2025/12/04 14:59:16 comsumer Merge_Pet_online received message: {"Uid":103289,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"170.239.38.36:53963","change_after":44,"change_num":10,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673607}
|
||||
2025/12/04 14:59:16 comsumer Merge_Pet_online received message: {"Uid":103275,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"177.33.30.37:36272","change_after":99,"change_num":1,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673631}
|
||||
2025/12/04 14:59:16 comsumer Merge_Pet_online received message: {"Uid":103354,"AppId":0,"ServerId":1,"EventName":"order_finish","Param":{"#zone_offset":-5,"Ip":"138.36.7.60:37201","order_id":3,"order_item_id":[4],"order_item_reward":[],"order_star_reward":4,"order_star_value":27,"order_type":13,"preset_order_group":1,"preset_order_step":3},"TimeStamp":1764673642}
|
||||
2025/12/04 14:59:16 comsumer Merge_Pet_online received message: {"Uid":102974,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"200.138.90.205:39080","change_after":193,"change_num":5,"change_reason":"HandleChess","change_type":"gain","item_id":100001},"TimeStamp":1764673633}
|
||||
2025/12/04 14:59:16 comsumer Merge_Pet_online received message: {"Uid":103348,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"45.172.146.93:53930","change_after":39,"change_num":1,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673623}
|
||||
2025/12/04 14:59:16 comsumer Merge_Pet_online received message: {"Uid":103010,"AppId":0,"ServerId":1,"EventName":"ReqGetChessFromBuff","Param":{"#zone_offset":-5,"Ip":"186.249.151.60:23262","chess_id":1602},"TimeStamp":1764673652}
|
||||
2025/12/04 14:59:17 comsumer Merge_Pet_online received message: {"Uid":100004,"AppId":0,"ServerId":1,"EventName":"ReqGetChessFromBuff","Param":{"#zone_offset":-5,"Ip":"120.41.146.28:16858","chess_id":561},"TimeStamp":1764673613}
|
||||
2025/12/04 14:59:17 comsumer Merge_Pet_online received message: {"Uid":103355,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"177.173.235.32:29071","change_after":56,"change_num":7,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673648}
|
||||
2025/12/04 14:59:22 comsumer Merge_Pet_online received message: {"Uid":103348,"AppId":0,"ServerId":1,"EventName":"sell_item","Param":{"#zone_offset":-5,"Ip":"45.172.146.93:53930","get_star_num":1,"merge_item_id":521,"product_name":"A Star"},"TimeStamp":1764673630}
|
||||
2025/12/04 14:59:22 comsumer Merge_Pet_online received message: {"Uid":103348,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"45.172.146.93:53930","change_after":36,"change_num":1,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673635}
|
||||
2025/12/04 14:59:22 comsumer Merge_Pet_online received message: {"Uid":103355,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"177.173.235.32:29071","change_after":63,"change_num":4,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673636}
|
||||
2025/12/04 14:59:23 comsumer Merge_Pet_online received message: {"Uid":100004,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"120.41.146.28:16858","change_after":2747,"change_num":2,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673639}
|
||||
2025/12/04 14:59:23 comsumer Merge_Pet_online received message: {"Uid":103348,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"45.172.146.93:53930","change_after":37,"change_num":1,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673635}
|
||||
2025/12/04 14:59:49 comsumer Merge_Pet_online received message: {"Uid":103348,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"45.172.146.93:53930","change_after":29,"change_num":1,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673647}
|
||||
2025/12/04 14:59:49 comsumer Merge_Pet_online received message: {"Uid":103348,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"45.172.146.93:53930","change_after":33,"change_num":1,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673638}
|
||||
2025/12/04 14:59:49 comsumer Merge_Pet_online received message: {"Uid":103105,"AppId":0,"ServerId":1,"EventName":"logout","Param":{"#zone_offset":-5,"after_level":10,"order_list":{"45":{"MergeId":[246],"Diff":0,"Type":13,"Timestamp":1764638272,"Q":0,"S":0,"Items":[{"Id":100002,"Num":60},{"Id":708,"Num":1}]},"49":{"MergeId":[227],"Diff":0,"Type":13,"Timestamp":1764653111,"Q":0,"S":0,"Items":[{"Id":100002,"Num":236},{"Id":1514,"Num":1}]},"55":{"MergeId":[48],"Diff":0,"Type":13,"Timestamp":1764653277,"Q":0,"S":0,"Items":[{"Id":100002,"Num":134},{"Id":1514,"Num":2}]},"59":{"MergeId":[64,65],"Diff":0,"Type":13,"Timestamp":1764653564,"Q":0,"S":0,"Items":[{"Id":100002,"Num":300}]},"65":{"MergeId":[11],"Diff":0,"Type":13,"Timestamp":1764669362,"Q":0,"S":0,"Items":[{"Id":100002,"Num":800},{"Id":1602,"Num":1}]},"70":{"MergeId":[25,25,25],"Diff":0,"Type":13,"Timestamp":1764653411,"Q":0,"S":0,"Items":[{"Id":100002,"Num":700}]}},"tmp_diamond":57,"tmp_energy":197},"TimeStamp":1764673652}
|
||||
2025/12/04 14:59:50 comsumer Merge_Pet_online received message: {"Uid":100004,"AppId":0,"ServerId":1,"EventName":"sell_item","Param":{"#zone_offset":-5,"Ip":"120.41.146.28:16858","get_star_num":3,"merge_item_id":522,"product_name":"A Few Star"},"TimeStamp":1764673650}
|
||||
2025/12/04 14:59:50 comsumer pet_home received message: {"Uid":100100013,"AppId":1,"ServerId":1,"EventName":"Login_log","Param":null,"TimeStamp":1764831582}
|
||||
2025/12/04 14:59:50 comsumer Merge_Pet_online received message: {"Uid":103355,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"177.173.235.32:29071","change_after":5,"change_num":5,"change_reason":"OrderReward","change_type":"gain","item_id":100002},"TimeStamp":1764673653}
|
||||
2025/12/04 14:59:50 comsumer Merge_Pet_online received message: {"Uid":102286,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"173.40.240.152:38188","change_after":26,"change_num":1,"change_reason":"recover_server","change_type":"gain","item_id":100001},"TimeStamp":1764673654}
|
||||
2025/12/04 14:59:58 comsumer Merge_Pet_online received message: {"Uid":103279,"AppId":0,"ServerId":1,"EventName":"Login_log","Param":null,"TimeStamp":1764673648}
|
||||
2025/12/04 14:59:58 comsumer Merge_Pet_online received message: {"Uid":100004,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"120.41.146.28:16858","change_after":2731,"change_num":6,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673655}
|
||||
2025/12/04 14:59:58 comsumer Merge_Pet_online received message: {"Uid":103279,"AppId":0,"ServerId":1,"EventName":"Login_log","Param":null,"TimeStamp":1764673648}
|
||||
2025/12/04 14:59:58 comsumer Merge_Pet_online received message: {"Uid":102974,"AppId":0,"ServerId":1,"EventName":"sell_item","Param":{"#zone_offset":-5,"Ip":"200.138.90.205:39080","get_star_num":3,"merge_item_id":522,"product_name":"A Few Star"},"TimeStamp":1764673655}
|
||||
2025/12/04 14:59:58 comsumer Merge_Pet_online received message: {"Uid":103105,"AppId":0,"ServerId":1,"EventName":"Login_Out","Param":null,"TimeStamp":1764673652}
|
||||
2025/12/04 14:59:58 comsumer Merge_Pet_online received message: {"Uid":103355,"AppId":0,"ServerId":1,"EventName":"order_finish","Param":{"#zone_offset":-5,"Ip":"177.173.235.32:29071","order_id":6,"order_item_id":[5],"order_item_reward":[],"order_star_reward":5,"order_star_value":48,"order_type":13,"preset_order_group":2,"preset_order_step":1},"TimeStamp":1764673653}
|
||||
2025/12/04 14:59:58 comsumer Merge_Pet_online received message: {"Uid":103348,"AppId":0,"ServerId":1,"EventName":"order_finish","Param":{"#zone_offset":-5,"Ip":"45.172.146.93:53930","order_id":23,"order_item_id":[25],"order_item_reward":[],"order_star_reward":6,"order_star_value":50,"order_type":13,"preset_order_group":4,"preset_order_step":6},"TimeStamp":1764673656}
|
||||
2025/12/04 14:59:58 comsumer Merge_Pet_online received message: {"Uid":102974,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"200.138.90.205:39080","change_after":104,"change_num":3,"change_reason":"HandleChess","change_type":"gain","item_id":100002},"TimeStamp":1764673655}
|
||||
2025/12/04 14:59:58 comsumer Merge_Pet_online received message: {"Uid":103289,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"170.239.38.36:53963","change_after":31,"change_num":5,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673656}
|
||||
2025/12/04 14:59:59 comsumer Merge_Pet_online received message: {"Uid":103353,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"187.19.255.171:19132","change_after":8,"change_num":6,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673653}
|
||||
2025/12/04 15:00:04 comsumer Merge_Pet_online received message: {"Uid":103358,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"148.222.209.252:38648","change_after":97,"change_num":2,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673658}
|
||||
2025/12/04 15:00:05 comsumer Merge_Pet_online received message: {"Uid":103010,"AppId":0,"ServerId":1,"EventName":"collection_add","Param":{"#zone_offset":-5,"Ip":"186.249.151.60:23262","item_id":1531,"item_name":"one tile"},"TimeStamp":1764673656}
|
||||
2025/12/04 15:00:05 comsumer Merge_Pet_online received message: {"Uid":103353,"AppId":0,"ServerId":1,"EventName":"ReqGetChessFromBuff","Param":{"#zone_offset":-5,"Ip":"187.19.255.171:19132","chess_id":85},"TimeStamp":1764673654}
|
||||
2025/12/04 15:00:05 comsumer Merge_Pet_online received message: {"Uid":102784,"AppId":0,"ServerId":1,"EventName":"Login_Out","Param":null,"TimeStamp":1764673654}
|
||||
2025/12/04 15:00:05 comsumer Merge_Pet_online received message: {"Uid":103225,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"177.190.171.13:38620","change_after":39,"change_num":1,"change_reason":"recover_server","change_type":"gain","item_id":100001},"TimeStamp":1764673655}
|
||||
2025/12/04 15:00:08 comsumer Merge_Pet_online received message: {"Uid":103010,"AppId":0,"ServerId":1,"EventName":"collection_add","Param":{"#zone_offset":-5,"Ip":"186.249.151.60:23262","item_id":1533,"item_name":"a pile of tiles"},"TimeStamp":1764673656}
|
||||
2025/12/04 15:00:08 comsumer Merge_Pet_online received message: {"Uid":100004,"AppId":0,"ServerId":1,"EventName":"sell_item","Param":{"#zone_offset":-5,"Ip":"120.41.146.28:16858","get_star_num":1,"merge_item_id":521,"product_name":"A Star"},"TimeStamp":1764673658}
|
||||
2025/12/04 15:00:08 comsumer Merge_Pet_online received message: {"Uid":103348,"AppId":0,"ServerId":1,"EventName":"sell_item","Param":{"#zone_offset":-5,"Ip":"45.172.146.93:53930","get_star_num":1,"merge_item_id":521,"product_name":"A Star"},"TimeStamp":1764673659}
|
||||
2025/12/04 15:00:13 comsumer Merge_Pet_online received message: {"Uid":102974,"AppId":0,"ServerId":1,"EventName":"sell_item","Param":{"#zone_offset":-5,"Ip":"200.138.90.205:39080","get_star_num":0,"merge_item_id":504,"product_name":"Large Amount Energy"},"TimeStamp":1764673634}
|
||||
2025/12/04 15:00:15 comsumer Merge_Pet_online received message: {"Uid":102974,"AppId":0,"ServerId":1,"EventName":"ReqGetChessFromBuff","Param":{"#zone_offset":-5,"Ip":"200.138.90.205:39080","chess_id":1511},"TimeStamp":1764673642}
|
||||
2025/12/04 15:00:16 comsumer Merge_Pet_online received message: {"Uid":103354,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"138.36.7.60:37201","change_after":12,"change_num":10,"change_reason":"OrderReward","change_type":"gain","item_id":100002},"TimeStamp":1764673617}
|
||||
2025/12/04 15:00:19 comsumer Merge_Pet_online received message: {"Uid":100004,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"120.41.146.28:16858","change_after":167082,"change_num":3,"change_reason":"HandleChess","change_type":"gain","item_id":100002},"TimeStamp":1764673650}
|
||||
2025/12/04 15:00:20 comsumer Merge_Pet_online received message: {"Uid":103154,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"189.44.63.106:54862","change_after":48,"change_num":1,"change_reason":"recover_server","change_type":"gain","item_id":100001},"TimeStamp":1764673653}
|
||||
2025/12/04 15:00:20 comsumer Merge_Pet_online received message: {"Uid":103289,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"170.239.38.36:53963","change_after":36,"change_num":3,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673643}
|
||||
2025/12/04 15:00:22 comsumer Merge_Pet_online received message: {"Uid":103348,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"45.172.146.93:53930","change_after":30,"change_num":2,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673647}
|
||||
2025/12/04 15:00:23 comsumer Merge_Pet_online received message: {"Uid":102286,"AppId":0,"ServerId":1,"EventName":"playroom_interact","Param":{"#zone_offset":-5,"Ip":"173.40.240.152:38188","interact_id":21,"interact_type":0},"TimeStamp":1764673643}
|
||||
2025/12/04 15:00:30 comsumer Merge_Pet_online received message: {"Uid":103348,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"45.172.146.93:53930","change_after":108,"change_num":1,"change_reason":"HandleChess","change_type":"gain","item_id":100002},"TimeStamp":1764673654}
|
||||
2025/12/04 15:00:32 comsumer Merge_Pet_online received message: {"Uid":103357,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"45.4.57.69:43723","change_after":94,"change_num":4,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673658}
|
||||
2025/12/04 15:00:37 comsumer Merge_Pet_online received message: {"Uid":102974,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"200.138.90.205:39080","change_after":231,"change_num":1,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673663}
|
||||
2025/12/04 15:00:37 comsumer Merge_Pet_online received message: {"Uid":100004,"AppId":0,"ServerId":1,"EventName":"sell_item","Param":{"#zone_offset":-5,"Ip":"120.41.146.28:16858","get_star_num":7,"merge_item_id":523,"product_name":"Small Star"},"TimeStamp":1764673663}
|
||||
2025/12/04 15:00:40 comsumer Merge_Pet_online received message: {"Uid":103355,"AppId":0,"ServerId":1,"EventName":"preset_order_birth","Param":{"#zone_offset":-5,"Ip":"177.173.235.32:29071","order_id":9,"order_item_id":[4],"preset_order_group":2,"preset_order_step":3},"TimeStamp":1764673664}
|
||||
2025/12/04 15:00:43 comsumer Merge_Pet_online received message: {"Uid":102974,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"200.138.90.205:39080","change_after":230,"change_num":1,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673663}
|
||||
2025/12/04 15:00:43 comsumer Merge_Pet_online received message: {"Uid":103355,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"177.173.235.32:29071","change_after":7,"change_num":2,"change_reason":"OrderReward","change_type":"gain","item_id":100002},"TimeStamp":1764673664}
|
||||
2025/12/04 15:00:43 comsumer Merge_Pet_online received message: {"Uid":103348,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"45.172.146.93:53930","change_after":115,"change_num":1,"change_reason":"HandleChess","change_type":"gain","item_id":100002},"TimeStamp":1764673659}
|
||||
2025/12/04 15:00:43 comsumer Merge_Pet_online received message: {"Uid":103348,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"45.172.146.93:53930","change_after":100,"change_num":15,"change_reason":"DecorateCost","change_type":"consume","item_id":100002},"TimeStamp":1764673664}
|
||||
2025/12/04 15:00:45 comsumer Merge_Pet_online received message: {"Uid":103348,"AppId":0,"ServerId":1,"EventName":"finish_deco","Param":{"#zone_offset":-5,"Ip":"45.172.146.93:53930","deco_step_id":"1_8","material_cost":[]},"TimeStamp":1764673664}
|
||||
2025/12/04 15:00:45 comsumer Merge_Pet_online received message: {"Uid":103348,"AppId":0,"ServerId":1,"EventName":"scene_reward","Param":{"#zone_offset":-5,"Ip":"45.172.146.93:53930","deco_step_id":"1_8","item_list":[{"Id":87,"Num":1},{"Id":100001,"Num":2}]},"TimeStamp":1764673664}
|
||||
2025/12/04 15:00:49 comsumer Merge_Pet_online received message: {"Uid":103154,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"189.44.63.106:54862","change_after":50,"change_num":2,"change_reason":"DecorateAdd","change_type":"gain","item_id":100001},"TimeStamp":1764673667}
|
||||
2025/12/04 15:00:51 comsumer Merge_Pet_online received message: {"Uid":103154,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"189.44.63.106:54862","change_after":100,"change_num":50,"change_reason":"LevUpReward","change_type":"gain","item_id":100001},"TimeStamp":1764673667}
|
||||
2025/12/04 15:00:52 comsumer Merge_Pet_online received message: {"Uid":103154,"AppId":0,"ServerId":1,"EventName":"level_up","Param":{"#zone_offset":-5,"Ip":"189.44.63.106:54862","after_level":12},"TimeStamp":1764673667}
|
||||
2025/12/04 15:00:55 comsumer Merge_Pet_online received message: {"Uid":103289,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"170.239.38.36:53963","change_after":27,"change_num":4,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673667}
|
||||
2025/12/04 15:00:55 comsumer Merge_Pet_online received message: {"Uid":103348,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"45.172.146.93:53930","change_after":31,"change_num":2,"change_reason":"DecorateAdd","change_type":"gain","item_id":100001},"TimeStamp":1764673664}
|
||||
2025/12/04 15:00:57 comsumer Merge_Pet_online received message: {"Uid":102974,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"200.138.90.205:39080","change_after":229,"change_num":1,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673668}
|
||||
2025/12/04 15:01:02 comsumer Merge_Pet_online received message: {"Uid":103359,"AppId":0,"ServerId":1,"EventName":"register_info","Param":{"username":"3703926"},"TimeStamp":1764673669}
|
||||
2025/12/04 15:01:02 comsumer Merge_Pet_online received message: {"Uid":103359,"AppId":0,"ServerId":1,"EventName":"register","Param":null,"TimeStamp":1764673669}
|
||||
2025/12/04 15:01:04 comsumer Merge_Pet_online received message: {"Uid":102286,"AppId":0,"ServerId":1,"EventName":"playerdeco_set","Param":{"#zone_offset":-5,"Ip":"173.40.240.152:38188","playerdeco_id":0,"playerdeco_type":"emoji","set_function":"playroom_game"},"TimeStamp":1764673667}
|
||||
2025/12/04 15:01:07 comsumer Merge_Pet_online received message: {"Uid":102974,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"200.138.90.205:39080","change_after":228,"change_num":1,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673670}
|
||||
2025/12/04 15:01:11 comsumer Merge_Pet_online received message: {"Uid":103359,"AppId":0,"ServerId":1,"EventName":"Login_log","Param":null,"TimeStamp":1764673670}
|
||||
2025/12/04 15:01:12 comsumer Merge_Pet_online received message: {"Uid":100004,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"120.41.146.28:16858","change_after":2727,"change_num":2,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673671}
|
||||
2025/12/04 15:01:12 comsumer Merge_Pet_online received message: {"Uid":103360,"AppId":0,"ServerId":1,"EventName":"Login_log","Param":null,"TimeStamp":1764673670}
|
||||
2025/12/04 15:01:15 comsumer Merge_Pet_online received message: {"Uid":103289,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"170.239.38.36:53963","change_after":25,"change_num":1,"change_reason":"recover_server","change_type":"gain","item_id":100001},"TimeStamp":1764673672}
|
||||
2025/12/04 15:01:17 comsumer Merge_Pet_online received message: {"Uid":100004,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"120.41.146.28:16858","change_after":2719,"change_num":2,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673672}
|
||||
2025/12/04 15:01:23 comsumer Merge_Pet_online received message: {"Uid":103358,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"148.222.209.252:38648","change_after":99,"change_num":1,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673654}
|
||||
2025/12/04 15:01:23 comsumer Merge_Pet_online received message: {"Uid":100004,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"120.41.146.28:16858","change_after":2739,"change_num":8,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673640}
|
||||
2025/12/04 15:01:24 comsumer Merge_Pet_online received message: {"Uid":103354,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"138.36.7.60:37201","change_after":84,"change_num":7,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673642}
|
||||
2025/12/04 15:01:24 comsumer Merge_Pet_online received message: {"Uid":102784,"AppId":0,"ServerId":1,"EventName":"logout","Param":{"#zone_offset":-5,"after_level":16,"order_list":{"10007":{"MergeId":[248,287],"Diff":1,"Type":15,"Timestamp":1764643436,"Q":0,"S":0,"Items":[{"Id":1602,"Num":2}]},"52":{"MergeId":[229],"Diff":0,"Type":13,"Timestamp":1764622727,"Q":0,"S":0,"Items":[{"Id":100002,"Num":800},{"Id":1602,"Num":1}]},"60":{"MergeId":[65,65,65],"Diff":0,"Type":13,"Timestamp":1764593624,"Q":0,"S":0,"Items":[{"Id":100002,"Num":600}]},"66":{"MergeId":[12],"Diff":0,"Type":13,"Timestamp":1764608546,"Q":0,"S":0,"Items":[{"Id":100002,"Num":1300},{"Id":1602,"Num":2}]}},"tmp_diamond":15,"tmp_energy":3},"TimeStamp":1764673654}
|
||||
2025/12/04 15:01:25 comsumer Merge_Pet_online received message: {"Uid":102974,"AppId":0,"ServerId":1,"EventName":"sell_item","Param":{"#zone_offset":-5,"Ip":"200.138.90.205:39080","get_star_num":0,"merge_item_id":502,"product_name":"Small Amount Energy"},"TimeStamp":1764673633}
|
||||
2025/12/04 15:01:27 comsumer Merge_Pet_online received message: {"Uid":103348,"AppId":0,"ServerId":1,"EventName":"sell_item","Param":{"#zone_offset":-5,"Ip":"45.172.146.93:53930","get_star_num":1,"merge_item_id":521,"product_name":"A Star"},"TimeStamp":1764673654}
|
||||
2025/12/04 15:01:27 comsumer Merge_Pet_online received message: {"Uid":103348,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"45.172.146.93:53930","change_after":114,"change_num":6,"change_reason":"OrderReward","change_type":"gain","item_id":100002},"TimeStamp":1764673656}
|
||||
2025/12/04 15:01:30 comsumer Merge_Pet_online received message: {"Uid":102974,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"200.138.90.205:39080","change_after":232,"change_num":1,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673658}
|
||||
2025/12/04 15:01:33 comsumer Merge_Pet_online received message: {"Uid":103154,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"189.44.63.106:54862","change_after":1557,"change_num":300,"change_reason":"DecorateCost","change_type":"consume","item_id":100002},"TimeStamp":1764673667}
|
||||
2025/12/04 15:01:37 comsumer Merge_Pet_online received message: {"Uid":103154,"AppId":0,"ServerId":1,"EventName":"finish_deco","Param":{"#zone_offset":-5,"Ip":"189.44.63.106:54862","deco_step_id":"1_32","material_cost":[]},"TimeStamp":1764673667}
|
||||
2025/12/04 15:01:37 comsumer Merge_Pet_online received message: {"Uid":103154,"AppId":0,"ServerId":1,"EventName":"property_level_up","Param":{"#zone_offset":-5,"Ip":"189.44.63.106:54862","pet_level":12,"property_level":12,"property_level_reward":"Pack_2_+1,","story_level":12},"TimeStamp":1764673667}
|
||||
2025/12/04 15:01:44 comsumer Merge_Pet_online received message: {"Uid":103354,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"138.36.7.60:37201","change_after":71,"change_num":1,"change_reason":"recover_server","change_type":"gain","item_id":100001},"TimeStamp":1764673669}
|
||||
2025/12/04 15:01:46 comsumer Merge_Pet_online received message: {"Uid":103354,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"138.36.7.60:37201","change_after":70,"change_num":14,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673668}
|
||||
2025/12/04 15:01:46 comsumer Merge_Pet_online received message: {"Uid":103360,"AppId":0,"ServerId":1,"EventName":"register","Param":null,"TimeStamp":1764673669}
|
||||
2025/12/04 15:01:50 comsumer Merge_Pet_online received message: {"Uid":103289,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"170.239.38.36:53963","change_after":24,"change_num":3,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673668}
|
||||
2025/12/04 15:01:51 comsumer Merge_Pet_online received message: {"Uid":102286,"AppId":0,"ServerId":1,"EventName":"finish_mini_game","Param":{"#zone_offset":-5,"Ip":"173.40.240.152:38188","is_chip":false,"item_list":[{"Id":100002,"Num":32}],"mini_game_type":1},"TimeStamp":1764673667}
|
||||
2025/12/04 15:01:52 comsumer Merge_Pet_online received message: {"Uid":102974,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"200.138.90.205:39080","change_after":227,"change_num":1,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673671}
|
||||
2025/12/04 15:01:53 comsumer Merge_Pet_online received message: {"Uid":103360,"AppId":0,"ServerId":1,"EventName":"Login_log","Param":null,"TimeStamp":1764673670}
|
||||
2025/12/04 15:01:54 comsumer Merge_Pet_online received message: {"Uid":103275,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"177.33.30.37:36272","change_after":84,"change_num":15,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673674}
|
||||
2025/12/04 15:01:58 comsumer Merge_Pet_online received message: {"Uid":102974,"AppId":0,"ServerId":1,"EventName":"preset_order_birth","Param":{"#zone_offset":-5,"Ip":"200.138.90.205:39080","order_id":58,"order_item_id":[63,64],"preset_order_group":7,"preset_order_step":3},"TimeStamp":1764673674}
|
||||
2025/12/04 15:02:03 comsumer Merge_Pet_online received message: {"Uid":103361,"AppId":0,"ServerId":1,"EventName":"register","Param":null,"TimeStamp":1764673676}
|
||||
2025/12/04 15:02:07 comsumer Merge_Pet_online received message: {"Uid":103357,"AppId":0,"ServerId":1,"EventName":"preset_order_birth","Param":{"#zone_offset":-5,"Ip":"45.4.57.69:43723","order_id":3,"order_item_id":[4],"preset_order_group":1,"preset_order_step":3},"TimeStamp":1764673676}
|
||||
2025/12/04 15:02:10 comsumer Merge_Pet_online received message: {"Uid":103279,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"189.6.248.68:19583","change_after":99,"change_num":1,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673676}
|
||||
2025/12/04 15:02:10 comsumer Merge_Pet_online received message: {"Uid":100004,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"120.41.146.28:16858","change_after":2721,"change_num":6,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673671}
|
||||
2025/12/04 15:02:11 comsumer Merge_Pet_online received message: {"Uid":100004,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"120.41.146.28:16858","change_after":167091,"change_num":1,"change_reason":"HandleChess","change_type":"gain","item_id":100002},"TimeStamp":1764673678}
|
||||
2025/12/04 15:02:11 comsumer Merge_Pet_online received message: {"Uid":103361,"AppId":0,"ServerId":1,"EventName":"Login_log","Param":null,"TimeStamp":1764673676}
|
||||
2025/12/04 15:02:13 comsumer Merge_Pet_online received message: {"Uid":103357,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"45.4.57.69:43723","change_after":12,"change_num":10,"change_reason":"OrderReward","change_type":"gain","item_id":100002},"TimeStamp":1764673676}
|
||||
2025/12/04 15:02:13 comsumer Merge_Pet_online received message: {"Uid":100004,"AppId":0,"ServerId":1,"EventName":"sell_item","Param":{"#zone_offset":-5,"Ip":"120.41.146.28:16858","get_star_num":1,"merge_item_id":521,"product_name":"A Star"},"TimeStamp":1764673678}
|
||||
2025/12/04 15:02:14 comsumer Merge_Pet_online received message: {"Uid":103354,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"138.36.7.60:37201","change_after":22,"change_num":6,"change_reason":"OrderReward","change_type":"gain","item_id":100002},"TimeStamp":1764673681}
|
||||
2025/12/04 15:02:14 comsumer Merge_Pet_online received message: {"Uid":103010,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"186.249.151.60:23262","change_after":16,"change_num":1,"change_reason":"recover_server","change_type":"gain","item_id":100001},"TimeStamp":1764673678}
|
||||
2025/12/04 15:02:16 comsumer Merge_Pet_online received message: {"Uid":103354,"AppId":0,"ServerId":1,"EventName":"order_finish","Param":{"#zone_offset":-5,"Ip":"138.36.7.60:37201","order_id":4,"order_item_id":[5],"order_item_reward":[],"order_star_reward":6,"order_star_value":48,"order_type":13,"preset_order_group":1,"preset_order_step":4},"TimeStamp":1764673681}
|
||||
2025/12/04 15:02:18 comsumer Merge_Pet_online received message: {"Uid":103154,"AppId":0,"ServerId":1,"EventName":"playroom_interact","Param":{"#zone_offset":-5,"Ip":"189.44.63.106:54862","interact_id":10,"interact_type":1},"TimeStamp":1764673682}
|
||||
2025/12/04 15:02:19 comsumer Merge_Pet_online received message: {"Uid":103354,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"138.36.7.60:37201","change_after":16,"change_num":4,"change_reason":"OrderReward","change_type":"gain","item_id":100002},"TimeStamp":1764673642}
|
||||
2025/12/04 15:02:25 comsumer Merge_Pet_online received message: {"Uid":100004,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"120.41.146.28:16858","change_after":2729,"change_num":2,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673656}
|
||||
2025/12/04 15:02:27 comsumer Merge_Pet_online received message: {"Uid":100004,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"120.41.146.28:16858","change_after":2737,"change_num":2,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673654}
|
||||
2025/12/04 15:02:28 comsumer Merge_Pet_online received message: {"Uid":100004,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"120.41.146.28:16858","change_after":167090,"change_num":7,"change_reason":"HandleChess","change_type":"gain","item_id":100002},"TimeStamp":1764673663}
|
||||
2025/12/04 15:02:28 comsumer Merge_Pet_online received message: {"Uid":103154,"AppId":0,"ServerId":1,"EventName":"scene_reward","Param":{"#zone_offset":-5,"Ip":"189.44.63.106:54862","deco_step_id":"1_32","item_list":[{"Id":100001,"Num":2}]},"TimeStamp":1764673667}
|
||||
2025/12/04 15:02:32 comsumer Merge_Pet_online received message: {"Uid":103355,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"177.173.235.32:29071","change_after":48,"change_num":4,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673670}
|
||||
2025/12/04 15:02:43 comsumer Merge_Pet_online received message: {"Uid":102827,"AppId":0,"ServerId":1,"EventName":"Login_log","Param":null,"TimeStamp":1764673675}
|
||||
2025/12/04 15:02:46 comsumer Merge_Pet_online received message: {"Uid":103357,"AppId":0,"ServerId":1,"EventName":"order_finish","Param":{"#zone_offset":-5,"Ip":"45.4.57.69:43723","order_id":2,"order_item_id":[7],"order_item_reward":[],"order_star_reward":10,"order_star_value":149,"order_type":13,"preset_order_group":1,"preset_order_step":2},"TimeStamp":1764673676}
|
||||
2025/12/04 15:02:46 comsumer Merge_Pet_online received message: {"Uid":103289,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"170.239.38.36:53963","change_after":130,"change_num":12,"change_reason":"OrderReward","change_type":"gain","item_id":100002},"TimeStamp":1764673674}
|
||||
2025/12/04 15:02:52 comsumer Merge_Pet_online received message: {"Uid":103154,"AppId":0,"ServerId":1,"EventName":"playroom_guide","Param":{"#zone_offset":-5,"Ip":"189.44.63.106:54862","Physiology":5},"TimeStamp":1764673673}
|
||||
2025/12/04 15:02:52 comsumer Merge_Pet_online received message: {"Uid":103292,"AppId":0,"ServerId":1,"EventName":"logout","Param":{"#zone_offset":-5,"after_level":10,"order_list":{"44":{"MergeId":[227],"Diff":0,"Type":13,"Timestamp":1764653742,"Q":0,"S":0,"Items":[{"Id":100002,"Num":64},{"Id":1501,"Num":2}]},"45":{"MergeId":[246],"Diff":0,"Type":13,"Timestamp":1764653742,"Q":0,"S":0,"Items":[{"Id":100002,"Num":60},{"Id":708,"Num":1}]},"50":{"MergeId":[228],"Diff":0,"Type":13,"Timestamp":1764673204,"Q":0,"S":0,"Items":[{"Id":100002,"Num":500},{"Id":1602,"Num":1}]},"55":{"MergeId":[48],"Diff":0,"Type":13,"Timestamp":1764654764,"Q":0,"S":0,"Items":[{"Id":100002,"Num":134},{"Id":1514,"Num":2}]},"58":{"MergeId":[63,64],"Diff":0,"Type":13,"Timestamp":1764654689,"Q":0,"S":0,"Items":[{"Id":100002,"Num":50},{"Id":1511,"Num":2}]},"64":{"MergeId":[9],"Diff":0,"Type":13,"Timestamp":1764654618,"Q":0,"S":0,"Items":[{"Id":100002,"Num":164},{"Id":1513,"Num":2}]},"69":{"MergeId":[23,24],"Diff":0,"Type":13,"Timestamp":1764654651,"Q":0,"S":0,"Items":[{"Id":100002,"Num":80},{"Id":1511,"Num":2}]}},"tmp_diamond":53,"tmp_energy":242},"TimeStamp":1764673677}
|
||||
2025/12/04 15:02:57 comsumer Merge_Pet_online received message: {"Uid":103289,"AppId":0,"ServerId":1,"EventName":"order_finish","Param":{"#zone_offset":-5,"Ip":"170.239.38.36:53963","order_id":41,"order_item_id":[46],"order_item_reward":[],"order_star_reward":12,"order_star_value":89,"order_type":13,"preset_order_group":6,"preset_order_step":4},"TimeStamp":1764673674}
|
||||
2025/12/04 15:02:58 comsumer Merge_Pet_online received message: {"Uid":103355,"AppId":0,"ServerId":1,"EventName":"order_finish","Param":{"#zone_offset":-5,"Ip":"177.173.235.32:29071","order_id":9,"order_item_id":[4],"order_item_reward":[],"order_star_reward":2,"order_star_value":27,"order_type":13,"preset_order_group":2,"preset_order_step":3},"TimeStamp":1764673683}
|
||||
2025/12/04 15:02:58 comsumer Merge_Pet_online received message: {"Uid":103355,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"177.173.235.32:29071","change_after":9,"change_num":2,"change_reason":"OrderReward","change_type":"gain","item_id":100002},"TimeStamp":1764673683}
|
||||
2025/12/04 15:02:59 comsumer Merge_Pet_online received message: {"Uid":103348,"AppId":0,"ServerId":1,"EventName":"finish_deco","Param":{"#zone_offset":-5,"Ip":"45.172.146.93:53930","deco_step_id":"1_9","material_cost":[]},"TimeStamp":1764673683}
|
||||
2025/12/04 15:03:02 comsumer Merge_Pet_online received message: {"Uid":103357,"AppId":0,"ServerId":1,"EventName":"asset_change","Param":{"#zone_offset":-5,"Ip":"45.4.57.69:43723","change_after":89,"change_num":5,"change_reason":"HandleChess","change_type":"consume","item_id":100001},"TimeStamp":1764673673}
|
||||
2025/12/04 15:03:02 comsumer Merge_Pet_online received message: {"Uid":103348,"AppId":0,"ServerId":1,"EventName":"scene_reward","Param":{"#zone_offset":-5,"Ip":"45.172.146.93:53930","deco_step_id":"1_9","item_list":[{"Id":88,"Num":1},{"Id":100001,"Num":2}]},"TimeStamp":1764673683}
|
||||
2025/12/04 15:03:44 comsumer Merge_Pet_online received message: {"Uid":102974,"AppId":0,"ServerId":1,"EventName":"mail_reward","Param":{"#zone_offset":-5,"Ip":"200.138.90.205:39080","item_list":[{"Id":100003,"Num":10}],"mail_id":2},"TimeStamp":1764673683}
|
||||
@ -25,7 +25,6 @@ var (
|
||||
var (
|
||||
rl *rotatelogs.RotateLogs
|
||||
logWriter io.Writer
|
||||
errWriter io.Writer
|
||||
)
|
||||
var c = make(chan os.Signal, 1)
|
||||
var d = make(chan int, 1)
|
||||
@ -52,14 +51,12 @@ func main() {
|
||||
// 打开一个普通的最新日志文件(不使用 symlink),用于提供固定路径的最新日志
|
||||
currFile, err := os.OpenFile("./log/comsume.log", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
|
||||
if err != nil {
|
||||
// 如果打开失败,仍然继续使用轮转器+控制台
|
||||
// 如果打开失败,仍然继续使用轮转器
|
||||
log.Printf("warning: failed to open current log file: %v", err)
|
||||
logWriter = io.MultiWriter(rl, os.Stdout)
|
||||
errWriter = io.MultiWriter(rl, os.Stderr)
|
||||
logWriter = io.MultiWriter(rl)
|
||||
} else {
|
||||
// 同时输出到轮转日志、固定最新日志文件和控制台
|
||||
logWriter = io.MultiWriter(rl, currFile, os.Stdout)
|
||||
errWriter = io.MultiWriter(rl, currFile, os.Stderr)
|
||||
}
|
||||
|
||||
log.SetOutput(logWriter)
|
||||
@ -102,13 +99,12 @@ func scheduleDailyTask() {
|
||||
func getKafkaReader(kafkaURL, topic, groupID string) *kafka.Reader {
|
||||
brokers := strings.Split(kafkaURL, ",")
|
||||
return kafka.NewReader(kafka.ReaderConfig{
|
||||
Brokers: brokers,
|
||||
GroupID: groupID,
|
||||
Topic: topic,
|
||||
MinBytes: 1, // 降低最小聚合字节,减少等待
|
||||
MaxBytes: 10e6, // 10MB
|
||||
MaxWait: 100 * time.Millisecond, // 缩短等待聚合时间
|
||||
QueueCapacity: 5000, // 内部预取队列容量(根据流量调整)
|
||||
Brokers: brokers,
|
||||
GroupID: groupID,
|
||||
Topic: topic,
|
||||
MinBytes: 1, // 降低最小聚合字节,减少等待
|
||||
MaxBytes: 10e6, // 10MB
|
||||
MaxWait: 100 * time.Millisecond, // 缩短等待聚合时间
|
||||
Dialer: &kafka.Dialer{
|
||||
Timeout: 3 * time.Second, // 减少建立连接超时,避免 ~9s 阻塞
|
||||
DualStack: true,
|
||||
@ -145,8 +141,7 @@ func comsumer(Game *config.Game) {
|
||||
log.Printf("comsumer %s error :%v", Game.Name, err)
|
||||
continue
|
||||
}
|
||||
jsonData := string(m.Value)
|
||||
log.Printf("comsumer %s received message: %s", Game.Name, jsonData)
|
||||
log.Printf("comsumer %s received message: %s", Game.Name, m.Value)
|
||||
r.CommitMessages(ctx, m)
|
||||
Wait.Add(1)
|
||||
err = db.ProcessMsg(sqlDb, m)
|
||||
|
||||
Binary file not shown.
31
nginx/jenkins.conf
Normal file
31
nginx/jenkins.conf
Normal file
@ -0,0 +1,31 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name jenkins.bywaystudios.com;
|
||||
|
||||
# 将 HTTP 请求重定向到 HTTPS
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name jenkins.bywaystudios.com;
|
||||
|
||||
ssl_certificate /etc/nginx/ssl/bywaystudios.com.pem;
|
||||
ssl_certificate_key /etc/nginx/ssl/bywaystudios.com.key;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:8090;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
# 可选:配置日志文件
|
||||
access_log /var/log/nginx/jenkins_access.log;
|
||||
error_log /var/log/nginx/jenkins_error.log;
|
||||
}
|
||||
31
nginx/login.conf.j2
Normal file
31
nginx/login.conf.j2
Normal file
@ -0,0 +1,31 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name {{ login_domain }};
|
||||
|
||||
# 将 HTTP 请求重定向到 HTTPS
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name {{ login_domain }};
|
||||
|
||||
ssl_certificate /etc/nginx/ssl/bywaystudios.com.pem;
|
||||
ssl_certificate_key /etc/nginx/ssl/bywaystudios.com.key;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||
|
||||
location /api {
|
||||
proxy_pass http://localhost:5240;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
# 可选:配置日志文件
|
||||
access_log /var/log/nginx/kafka_access.log;
|
||||
error_log /var/log/nginx/kafka_error.log;
|
||||
}
|
||||
33
nginx/policy.conf
Normal file
33
nginx/policy.conf
Normal file
@ -0,0 +1,33 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name policy.bywaystudios.com;
|
||||
|
||||
# 将 HTTP 请求重定向到 HTTPS
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name policy.bywaystudios.com;
|
||||
|
||||
ssl_certificate /etc/nginx/ssl/bywaystudios.com.pem;
|
||||
ssl_certificate_key /etc/nginx/ssl/bywaystudios.com.key;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||
|
||||
location = /docs {
|
||||
return 301 /docs/;
|
||||
}
|
||||
|
||||
location /docs/ {
|
||||
alias /data/policy/;
|
||||
index index.html;
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
|
||||
# 可选:配置日志文件
|
||||
access_log /var/log/nginx/dify_access.log;
|
||||
error_log /var/log/nginx/dify_error.log;
|
||||
}
|
||||
31
nginx/shipping.conf.j2
Normal file
31
nginx/shipping.conf.j2
Normal file
@ -0,0 +1,31 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name {{ shipping_domain }};
|
||||
|
||||
# 将 HTTP 请求重定向到 HTTPS
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name {{ shipping_domain }};
|
||||
|
||||
ssl_certificate /etc/nginx/ssl/bywaystudios.com.pem;
|
||||
ssl_certificate_key /etc/nginx/ssl/bywaystudios.com.key;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||
|
||||
location /api {
|
||||
proxy_pass http://localhost:5250;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
# 可选:配置日志文件
|
||||
access_log /var/log/nginx/ship_access.log;
|
||||
error_log /var/log/nginx/ship_error.log;
|
||||
}
|
||||
32
nginx/verdaccio.conf
Normal file
32
nginx/verdaccio.conf
Normal file
@ -0,0 +1,32 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name npm.bywaystudios.com;
|
||||
|
||||
# 将 HTTP 请求重定向到 HTTPS
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name npm.bywaystudios.com;
|
||||
|
||||
ssl_certificate /etc/nginx/ssl/bywaystudios.com.pem;
|
||||
ssl_certificate_key /etc/nginx/ssl/bywaystudios.com.key;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||
|
||||
location / {
|
||||
deny all;
|
||||
proxy_pass http://localhost:4873;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
# 可选:配置日志文件
|
||||
access_log /var/log/nginx/jenkins_access.log;
|
||||
error_log /var/log/nginx/jenkins_error.log;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
output/scrape_results.csv
Normal file
2
output/scrape_results.csv
Normal file
@ -0,0 +1,2 @@
|
||||
url,title,description,links_count,images_count,html_length,timestamp
|
||||
https://yixj5m42od.feishu.cn/sheets/VlAIsKxYchNABztr3RGcBnrEnYM?table=tblNs3625a9MAc89&view=vewkRuPWCL&sheet=y1FRE9,飞书 - 登录,整合即时通讯、智能日历、云端创作等功能于一体,打造高效办公方式,0,3,163481,2025-07-15 11:35:20
|
||||
|
35
output/scrape_results.json
Normal file
35
output/scrape_results.json
Normal file
File diff suppressed because one or more lines are too long
36
output/scrape_results_full.json
Normal file
36
output/scrape_results_full.json
Normal file
File diff suppressed because one or more lines are too long
25
output/scrape_results_full_logged_in.json
Normal file
25
output/scrape_results_full_logged_in.json
Normal file
File diff suppressed because one or more lines are too long
2
output/scrape_results_logged_in.csv
Normal file
2
output/scrape_results_logged_in.csv
Normal file
@ -0,0 +1,2 @@
|
||||
url,title,description,links_count,images_count,html_length,timestamp
|
||||
https://yixj5m42od.feishu.cn/sheets/VlAIsKxYchNABztr3RGcBnrEnYM?table=tblNs3625a9MAc89&view=vewkRuPWCL&sheet=y1FRE9,漏洞跟踪记录Updated - 飞书云文档,,0,2,1151746,2025-07-15 11:42:32
|
||||
|
24
output/scrape_results_logged_in.json
Normal file
24
output/scrape_results_logged_in.json
Normal file
@ -0,0 +1,24 @@
|
||||
[
|
||||
{
|
||||
"url": "https://yixj5m42od.feishu.cn/sheets/VlAIsKxYchNABztr3RGcBnrEnYM?table=tblNs3625a9MAc89&view=vewkRuPWCL&sheet=y1FRE9",
|
||||
"title": "漏洞跟踪记录Updated - 飞书云文档",
|
||||
"description": "",
|
||||
"links": [],
|
||||
"images": [
|
||||
{
|
||||
"url": "https://s1-imfile.feishucdn.com/static-resource/v1/v3_00hl_105b235e-bf60-434d-add8-897ecb4fd47g~?image_size=noop&cut_type=&quality=&format=image&sticker_format=.webp",
|
||||
"alt": "",
|
||||
"title": ""
|
||||
},
|
||||
{
|
||||
"url": "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjAiIGhlaWdodD0iNjAiIHZpZXdCb3g9IjAgMCA2MCA2MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTE2LjI1IDIwVjE4Ljc1QzE2LjI1IDExLjE1NjEgMjIuNDA2MSA1IDMwIDVDMzcuNTkzOSA1IDQzLjc1IDExLjE1NjEgNDMuNzUgMTguNzVWMjBINTBDNTIuNzYxNCAyMCA1NSAyMi4yMzg2IDU1IDI1VjUwQzU1IDUyLjc2MTQgNTIuNzYxNCA1NSA1MCA1NUgxMEM3LjIzODU4IDU1IDUgNTIuNzYxNCA1IDUwVjI1QzUgMjIuMjM4NiA3LjIzODU4IDIwIDEwIDIwSDE2LjI1Wk0zOC43NSAxOC43NUMzOC43NSAxMy45MTc1IDM0LjgzMjUgMTAgMzAgMTBDMjUuMTY3NSAxMCAyMS4yNSAxMy45MTc1IDIxLjI1IDE4Ljc1VjIwSDM4Ljc1VjE4Ljc1Wk0zNi4yNSAzNy41QzM2LjI1IDM0LjA0ODIgMzMuNDUxOCAzMS4yNSAzMCAzMS4yNUMyNi41NDgyIDMxLjI1IDIzLjc1IDM0LjA0ODIgMjMuNzUgMzcuNUMyMy43NSA0MC45NTE4IDI2LjU0ODIgNDMuNzUgMzAgNDMuNzVDMzMuNDUxOCA0My43NSAzNi4yNSA0MC45NTE4IDM2LjI1IDM3LjVaIiBmaWxsPSIjQkJCRkM0Ii8+Cjwvc3ZnPgo=",
|
||||
"alt": "",
|
||||
"title": ""
|
||||
}
|
||||
],
|
||||
"text_length": 4386,
|
||||
"html_length": 1151746,
|
||||
"script_data": {},
|
||||
"timestamp": "2025-07-15 11:42:32"
|
||||
}
|
||||
]
|
||||
27
playbook/files/ssl/bywaystudios.com.key
Normal file
27
playbook/files/ssl/bywaystudios.com.key
Normal file
@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAth2OvQ4vKkQnKzfMEW+dBUGjPXpwuzizCa5wAGOyLFTIwv2a
|
||||
WsRDSnCeAA8NsoYVzuG2+tzHi7hOulAJTWHzr/XgdpNqO7KzFoIkYXGtTjFg3gML
|
||||
R8ikRZZWMMnSHy0jDvBoeydaf/ff+a2WZjKb2FknRBIUfdmbQdFLauo9Q1/V2mSc
|
||||
/9MQT4rLk50wpbWf4zzsYClHt09BD4lDoWS1iLKLDi5Do2DELkUUbV2flaElBcqX
|
||||
D6yw1v/fqmXUM1UpV5gKBrDZp3x9k0cbudUGfYlLulC0+k+UuVhXsVWQPMNUlp0+
|
||||
s9bfUUm1BQRmSaPUvkgwtzH83EAZmiKuUMTJ0QIDAQABAoIBAAJW+uB+8Cgw2/f4
|
||||
LY0DzBanMzu0+QHOxq4XKaU3orBjHnky3OrRnrO0IrOJffmPM3SG/dzXPVEUOx61
|
||||
rIjr+z+Ffy7G0hSWRSrC3UjLNxjMFZyEmX6Am2uxdMYHscVoxQyKFi2O4eDHBH+m
|
||||
tUn22H29F34OZWkAhLghwkBLZiIZcYBJhptG0uk5mpdN7thAG+3DQXv6VYIYyLT6
|
||||
3MVFPmaxBmxhQGUzRyyd+YF3Z6DiKPpWVYL7Wk3MT+62aui7X1J9Rwh54yAaFVox
|
||||
9U6cbwJb23cccSRvYJV19Uq1WzVTc19mex5+a9IY72kV9X50s6K/xpbzHyHhW+1B
|
||||
Bf4vcIECgYEA+gSjDkK+jKN2Scr61g5eTDd398aQcChvYSjVRTb2hY5pPTTVSy5/
|
||||
PoeW7XQlWbYZRpB3gVWLh61pSY4M063E/d8IZXHvvOl8UwwktoqCkrS7y5PO7aNM
|
||||
jF0vfbK9btMm/hjK/1bNPDQjknwVXMOug153wxLuCoRkm5yf7XxZTlkCgYEAunkE
|
||||
LJgpIcHQdViWwUzdqDuF8croDFRpDi/Nm93142E5w2N6yX9RS07EnRw2HacLQWxp
|
||||
oS85s3QxukihemU/4yblhtw6PZTkXE4vUPH8OI9hUQi9SwaWfD9qS4CGhYmjbB+d
|
||||
L917QHKoaaxk0+LvNZHa93RQsPl0yTSOiSCaGDkCgYEApKnHJk5JJ2FFN8aqu65M
|
||||
5s+lgJfTazsGWCxHgkV3yXCI2VnhnJlsDqfIfG2BZ/tp3DKrso+/zMUmUd5vjj6l
|
||||
PjrVUdLffUEds6iMyXiiFLNZ9/NKVvK1KMD61UOSRdpllPaJQ/BMTXldcE2u2CC8
|
||||
4CKop97gziZyCJb4MbYzL0kCgYEAm4klOi0Q4d9PiRGDbWg32oMLjkq4ktA1cGff
|
||||
EAtrdWU7UQZA/KD9pdrllEZbvRAAC2nqEU/ayRw5/i9mwTiCuW1QNdSrn4H5mCR+
|
||||
wv2Ua3jsqzKm8VVlX+1lM+TYT7omXaFg8vPCQldgsgPhdfrrm7s08QJL69Gm38y+
|
||||
txJCdcECgYBd6HDypjiuswd6fTmdNYMZBQJ+M1ouuyoylv4m6hEp3iHhmWyGvE30
|
||||
+VLfzPDMXwjAvbk6PLIKJw6R2fA/Lh3GOjb0heAcwuGpgqe0OM0+PRo4mxlbovcx
|
||||
K0RpSiac5cgpEdO4Og+cgKzCg3g35wVLfvUYDAaZrsP26I/Xru5lUw==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
127
playbook/files/ssl/bywaystudios.com.pem
Normal file
127
playbook/files/ssl/bywaystudios.com.pem
Normal file
@ -0,0 +1,127 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIGNzCCBR+gAwIBAgIQVqPp7OLoPM3oQ1nibTAApzANBgkqhkiG9w0BAQsFADBc
|
||||
MQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29UcnVzIENBIExpbWl0ZWQxMTAvBgNV
|
||||
BAMMKFdvVHJ1cyBEViBTZXJ2ZXIgQ0EgIFtSdW4gYnkgdGhlIElzc3Vlcl0wHhcN
|
||||
MjUxMjA5MDAwMDAwWhcNMjcwMTA5MjM1OTU5WjAdMRswGQYDVQQDDBIqLmJ5d2F5
|
||||
c3R1ZGlvcy5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2HY69
|
||||
Di8qRCcrN8wRb50FQaM9enC7OLMJrnAAY7IsVMjC/ZpaxENKcJ4ADw2yhhXO4bb6
|
||||
3MeLuE66UAlNYfOv9eB2k2o7srMWgiRhca1OMWDeAwtHyKRFllYwydIfLSMO8Gh7
|
||||
J1p/99/5rZZmMpvYWSdEEhR92ZtB0Utq6j1DX9XaZJz/0xBPisuTnTCltZ/jPOxg
|
||||
KUe3T0EPiUOhZLWIsosOLkOjYMQuRRRtXZ+VoSUFypcPrLDW/9+qZdQzVSlXmAoG
|
||||
sNmnfH2TRxu51QZ9iUu6ULT6T5S5WFexVZA8w1SWnT6z1t9RSbUFBGZJo9S+SDC3
|
||||
MfzcQBmaIq5QxMnRAgMBAAGjggMyMIIDLjAfBgNVHSMEGDAWgBSZmy32i/Cj24nU
|
||||
nvvldC9o0pBP5DAdBgNVHQ4EFgQUCFKCjmFS7bzr/gxZGuYPNTLwwwYwDgYDVR0P
|
||||
AQH/BAQDAgWgMAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwSQYD
|
||||
VR0gBEIwQDA0BgsrBgEEAbIxAQICFjAlMCMGCCsGAQUFBwIBFhdodHRwczovL3Nl
|
||||
Y3RpZ28uY29tL0NQUzAIBgZngQwBAgEwPQYDVR0fBDYwNDAyoDCgLoYsaHR0cDov
|
||||
L2NybC5jcmxvY3NwLmNuL1dvVHJ1c0RWU2VydmVyQ0FfMi5jcmwwbAYIKwYBBQUH
|
||||
AQEEYDBeMDgGCCsGAQUFBzAChixodHRwOi8vYWlhLmNybG9jc3AuY24vV29UcnVz
|
||||
RFZTZXJ2ZXJDQV8yLmNydDAiBggrBgEFBQcwAYYWaHR0cDovL29jc3AuY3Jsb2Nz
|
||||
cC5jbjAvBgNVHREEKDAmghIqLmJ5d2F5c3R1ZGlvcy5jb22CEGJ5d2F5c3R1ZGlv
|
||||
cy5jb20wggGOBgorBgEEAdZ5AgQCBIIBfgSCAXoBeAB3AGBMmq96f3dfAdQG/JIN
|
||||
yJnrCxx9+MlSG/r6F3c7l4vJAAABmwG3KuMAAAQDAEgwRgIhAOApwbyVueun3xhC
|
||||
mTSOgscM+EfoyMnm4lrNEcEly4ANAiEAqkqI93x0tYyXyanzewv1mVqWt5n9jKzs
|
||||
rOVBbn89QRwAfQCOykcLrN5q86IGsKR6hLdG/h/Gv5U+JeabTuQCSPPG6AAAAZsB
|
||||
tyvaAAgAAAUAAGfcEAQDAEYwRAIgIITO+svcTRkjPRrFpuvPT0yBDrxI0to55ivE
|
||||
amsxY+ACIGyR3rLWtmunFaVO4SIFzwg8cIl9Dv3C8+gEIE+YmhNwAH4AWW5sM4aU
|
||||
sllyolbIoOjdkEp26Ag92oc7AQg4KBQ87lkAAAGbAbcsGQAIAAAFAAAA590EAwBH
|
||||
MEUCIQDa9BiAFvEFRyS2VXo1RD6NL+1LycCQfe8lwaRgANltYAIgQwclGCysMlcz
|
||||
dB0OfBnmP5yskdWL4raEoxLX5+y9OPQwDQYJKoZIhvcNAQELBQADggEBAFULS/wz
|
||||
GEE6rqG1Pdd8in6JthtVgVwwTbLsOt09RAWRs0VS/qeVEYxrqYCcuO5FIjoX6ENk
|
||||
Hf6FAnqZp65/iTv9YtSoZFbghvD8ys8kjCB8bZOcs0FROehtCzLZb02ceozYjPoz
|
||||
1S1SEsvy4TM3pkW2OCPdNqTm1+dSPHZKlfZeeMuZxYv7a3rONry/JE3kN6tQ0Wfe
|
||||
HTRjO+H7trxie+e92SQ4vCcbooHvS6A5TAgtBC4cGNWWaMga+3GJyp2kcdjPzzpI
|
||||
yuOJLZKbRba+sWY1EDZVZ8pMwYMOYbf+4/ThLHVpzignsjSMgvcnq9CnMA4MPeIW
|
||||
bUtCaexj/Mif4ww=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIF4jCCA8qgAwIBAgIRANVuJGyU7WOrsUbvwZa2T7AwDQYJKoZIhvcNAQEMBQAw
|
||||
gYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtK
|
||||
ZXJzZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMS4wLAYD
|
||||
VQQDEyVVU0VSVHJ1c3QgUlNBIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTIw
|
||||
MDEwODAwMDAwMFoXDTMwMDEwNzIzNTk1OVowXDELMAkGA1UEBhMCQ04xGjAYBgNV
|
||||
BAoTEVdvVHJ1cyBDQSBMaW1pdGVkMTEwLwYDVQQDDChXb1RydXMgRFYgU2VydmVy
|
||||
IENBICBbUnVuIGJ5IHRoZSBJc3N1ZXJdMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
|
||||
MIIBCgKCAQEA7IE0rmVTVdRdNOzK1jsR/VppyukZ/XbQgakJHOhg6XGDsiHe/l5B
|
||||
3PxyXw18jEdN+7YxP0qsGz+HlQbsQh6XlwIyjpz/2gFMiqa7y1v+dHOgj6xNOF5a
|
||||
oaPm/Qhb0N+JYQidgaC+1Zp6W+YeC736rzCMr9vL1Usa3QLzRoQEo0DzbG4sPeP1
|
||||
US0Ia/i8o6szArH+DAcvrzCZ2kkpTScQ9QfOsvkMBP1W2otICdKUyZHaBc+ztTAd
|
||||
ovSlOR+GPf29dYfGQkZAp0tffIRw/na3WB86WGZPpNFfo2QxxsHYoL3oSWKfSWTY
|
||||
FgW22J8eA03TFHYowm/NqYuJ7GW553HppQIDAQABo4IBcDCCAWwwHwYDVR0jBBgw
|
||||
FoAUU3m/WqorSs9UgOHYm8Cd8rIDZsswHQYDVR0OBBYEFJmbLfaL8KPbidSe++V0
|
||||
L2jSkE/kMA4GA1UdDwEB/wQEAwIBhjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1Ud
|
||||
JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAiBgNVHSAEGzAZMA0GCysGAQQBsjEB
|
||||
AgIWMAgGBmeBDAECATBQBgNVHR8ESTBHMEWgQ6BBhj9odHRwOi8vY3JsLnVzZXJ0
|
||||
cnVzdC5jb20vVVNFUlRydXN0UlNBQ2VydGlmaWNhdGlvbkF1dGhvcml0eS5jcmww
|
||||
cQYIKwYBBQUHAQEEZTBjMDoGCCsGAQUFBzAChi5odHRwOi8vY3J0LnVzZXJ0cnVz
|
||||
dC5jb20vVVNFUlRydXN0UlNBQUFBQ0EuY3J0MCUGCCsGAQUFBzABhhlodHRwOi8v
|
||||
b2NzcC51c2VydHJ1c3QuY29tMA0GCSqGSIb3DQEBDAUAA4ICAQB5t8v3uYzHa4EL
|
||||
0rOb9g/YAmptUbILcBMKk1x188ucsGVPaG1DG9bpVamxbmCtFA1MlrA7iUC8SGop
|
||||
KBnuWFsNKiC7jCbRoahT1/FSwFsSuDlDmOjr1MqDXE+or08UkXsJB57XxXxdVOPl
|
||||
DcZHII4qHi1XKK4iurMqb+kbdpAWadyfidRRCGPopYCVYLLYhRJgpFGtfr6Gk8N0
|
||||
j81jq/7QbN0dRSDzMNdadKTc7c3+i9fIrXj79lV5Wvva+OL7nh8MxQhG1Ekek7Rv
|
||||
en++jSZvaEhCrMsSedFTA/aIy7oJg85tfglF2ybK61HsobjYzdDNICKJlIm4chlA
|
||||
XIDDqw2mw0Kz2snrkp9dpvMBqahF/Uy1kHzPcrq1/w5OqZWAuDKxZ68PuZ/ME2hI
|
||||
YbIDG9dWT6Y7eqtjQ2TmAQbOqdAG2LeikPMl2DMrPEa4lcKJzsFbHfHAW3hVgPSQ
|
||||
hRfS4TtbNnxijbsp8GguMHxP2R7dpAAYybwfZdXP7WYAnwEr1mzIf0Y3J0m7GDyX
|
||||
JhaflN3G2wIm2HzRd39NvnDRmFEraqui/YYO9ym0pwq1d0S+bGG6876QCto0u3Cg
|
||||
ItFh3Za2ZeIY+g5mWrejSaDs9LT7eu44iCyebfgekdMRqFeCuGAsJdsun3LOHHJo
|
||||
tCVPRjyFg9NDeJeMa4Z8QuXAXLd9cw==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFgTCCBGmgAwIBAgIQOXJEOvkit1HX02wQ3TE1lTANBgkqhkiG9w0BAQwFADB7
|
||||
MQswCQYDVQQGEwJHQjEbMBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYD
|
||||
VQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UE
|
||||
AwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTE5MDMxMjAwMDAwMFoXDTI4
|
||||
MTIzMTIzNTk1OVowgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5
|
||||
MRQwEgYDVQQHEwtKZXJzZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBO
|
||||
ZXR3b3JrMS4wLAYDVQQDEyVVU0VSVHJ1c3QgUlNBIENlcnRpZmljYXRpb24gQXV0
|
||||
aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAgBJlFzYOw9sI
|
||||
s9CsVw127c0n00ytUINh4qogTQktZAnczomfzD2p7PbPwdzx07HWezcoEStH2jnG
|
||||
vDoZtF+mvX2do2NCtnbyqTsrkfjib9DsFiCQCT7i6HTJGLSR1GJk23+jBvGIGGqQ
|
||||
Ijy8/hPwhxR79uQfjtTkUcYRZ0YIUcuGFFQ/vDP+fmyc/xadGL1RjjWmp2bIcmfb
|
||||
IWax1Jt4A8BQOujM8Ny8nkz+rwWWNR9XWrf/zvk9tyy29lTdyOcSOk2uTIq3XJq0
|
||||
tyA9yn8iNK5+O2hmAUTnAU5GU5szYPeUvlM3kHND8zLDU+/bqv50TmnHa4xgk97E
|
||||
xwzf4TKuzJM7UXiVZ4vuPVb+DNBpDxsP8yUmazNt925H+nND5X4OpWaxKXwyhGNV
|
||||
icQNwZNUMBkTrNN9N6frXTpsNVzbQdcS2qlJC9/YgIoJk2KOtWbPJYjNhLixP6Q5
|
||||
D9kCnusSTJV882sFqV4Wg8y4Z+LoE53MW4LTTLPtW//e5XOsIzstAL81VXQJSdhJ
|
||||
WBp/kjbmUZIO8yZ9HE0XvMnsQybQv0FfQKlERPSZ51eHnlAfV1SoPv10Yy+xUGUJ
|
||||
5lhCLkMaTLTwJUdZ+gQek9QmRkpQgbLevni3/GcV4clXhB4PY9bpYrrWX1Uu6lzG
|
||||
KAgEJTm4Diup8kyXHAc/DVL17e8vgg8CAwEAAaOB8jCB7zAfBgNVHSMEGDAWgBSg
|
||||
EQojPpbxB+zirynvgqV/0DCktDAdBgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rID
|
||||
ZsswDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0gBAowCDAG
|
||||
BgRVHSAAMEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly9jcmwuY29tb2RvY2EuY29t
|
||||
L0FBQUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDQGCCsGAQUFBwEBBCgwJjAkBggr
|
||||
BgEFBQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2EuY29tMA0GCSqGSIb3DQEBDAUA
|
||||
A4IBAQAYh1HcdCE9nIrgJ7cz0C7M7PDmy14R3iJvm3WOnnL+5Nb+qh+cli3vA0p+
|
||||
rvSNb3I8QzvAP+u431yqqcau8vzY7qN7Q/aGNnwU4M309z/+3ri0ivCRlv79Q2R+
|
||||
/czSAaF9ffgZGclCKxO/WIu6pKJmBHaIkU4MiRTOok3JMrO66BQavHHxW/BBC5gA
|
||||
CiIDEOUMsfnNkjcZ7Tvx5Dq2+UUTJnWvu6rvP3t3O9LEApE9GQDTF1w52z97GA1F
|
||||
zZOFli9d31kWTz9RvdVFGD/tSo7oBmF0Ixa1DVBzJ0RHfxBdiSprhTEUxOipakyA
|
||||
vGp4z7h/jnZymQyd/teRCBaho1+V
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb
|
||||
MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
|
||||
GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj
|
||||
YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL
|
||||
MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
|
||||
BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM
|
||||
GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||
ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua
|
||||
BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe
|
||||
3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4
|
||||
YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR
|
||||
rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm
|
||||
ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU
|
||||
oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
|
||||
MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v
|
||||
QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t
|
||||
b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF
|
||||
AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q
|
||||
GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
|
||||
Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2
|
||||
G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi
|
||||
l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3
|
||||
smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
|
||||
-----END CERTIFICATE-----
|
||||
@ -1,58 +1,28 @@
|
||||
---
|
||||
- name: Deploy GoLeaf release
|
||||
hosts: london
|
||||
hosts: test
|
||||
gather_facts: no
|
||||
remote_user: root
|
||||
vars:
|
||||
goleaf_src: /data/devops/source/main
|
||||
goleaf_dest: /data/devops/MergePet/main
|
||||
|
||||
goleaf_dest: /usr/local/games/MergePet
|
||||
config_src: /data/docs/tool/config/
|
||||
config_dest: /data/devops/MergePet/config/
|
||||
|
||||
config_dest: /usr/local/games/MergePet/gamedata/config/
|
||||
pack_script: /data/devops/pack.sh
|
||||
|
||||
tar_file: /usr/local/MergePet.tar
|
||||
|
||||
tar_dest: /usr/local/game
|
||||
|
||||
branch: develop
|
||||
tasks:
|
||||
- name: sh pack.sh
|
||||
shell: sh /data/devops/pack_local.sh
|
||||
delegate_to: localhost
|
||||
|
||||
# - name: copy
|
||||
# copy:
|
||||
# src: /data/devops/Goleaf.tar
|
||||
# dest: /usr/local
|
||||
# - name: tar
|
||||
# command: tar -xvf /usr/local/Goleaf.tar -C /usr/local/
|
||||
# - name: 切换分支 {{branch}}
|
||||
# shell: cd /codes/pet_home_server && git checkout {{branch}} && git pull
|
||||
# delegate_to: localhost
|
||||
# register: git_result
|
||||
# - name: sh pack.sh
|
||||
# shell: sh /data/devops/pack.sh
|
||||
# delegate_to: localhost
|
||||
- name: backup goleaf
|
||||
shell: mv "{{goleaf_dest}}"/main "{{goleaf_dest}}"/main.bak
|
||||
ignore_errors: yes
|
||||
|
||||
# - name: copy goleaf
|
||||
# copy:
|
||||
# src: /data/devops/source/main
|
||||
# dest: /usr/local/MergePet/main
|
||||
- name: copy goleaf
|
||||
copy:
|
||||
src: /data/devops/script/dist/verifyOrder
|
||||
dest: /usr/local/MergePet/script
|
||||
mode: '0777'
|
||||
src: "{{ goleaf_src }}"
|
||||
dest: "{{goleaf_dest}}"
|
||||
mode: 0755
|
||||
|
||||
|
||||
# - name: copy config
|
||||
# copy:
|
||||
# src: /data/docs/tool/out/
|
||||
# dest: /usr/local/Goleaf/gamedata/config/
|
||||
# mode: '0777'
|
||||
|
||||
|
||||
# - name: restart goleaf
|
||||
# command: sh /usr/local/Goleaf/Restart.sh restart
|
||||
# register: restart_result
|
||||
|
||||
# - name: show restart result
|
||||
# debug:
|
||||
# var: restart_result.stdout_lines
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
# @format
|
||||
---
|
||||
- name: Deploy GoLeaf release
|
||||
hosts: test
|
||||
hosts: google
|
||||
remote_user: root
|
||||
|
||||
tasks:
|
||||
|
||||
|
||||
# - name: copy config
|
||||
# copy:
|
||||
# src: /data/docs/tool/out/
|
||||
@ -13,20 +12,17 @@
|
||||
# mode: '0777'
|
||||
|
||||
- name: pack tool
|
||||
shell: cd /data/devops/tool && GOOS=linux GOARCH=amd64 go build -o /data/devops/MergePet/tool/tool main.go
|
||||
shell: cd /data/devops/tools && GOOS=linux GOARCH=amd64 go build -o /data/devops/MergePet/tool/tool main.go
|
||||
delegate_to: localhost
|
||||
- name: reload tool
|
||||
copy:
|
||||
src: /data/devops/MergePet/tool/tool
|
||||
dest: /usr/local/Goleaf/tool/tool
|
||||
|
||||
- name: pack main
|
||||
shell: cd /data/pet_home_server/src/server && GOOS=linux GOARCH=amd64 go build -o /data/devops/MergePet/main main.go
|
||||
delegate_to: localhost
|
||||
- name: reload main
|
||||
copy:
|
||||
src: /data/devops/MergePet/main
|
||||
dest: /usr/local/Goleaf/main
|
||||
|
||||
|
||||
dest: /usr/local/game/tool
|
||||
|
||||
# - name: pack main
|
||||
# shell: cd /data/pet_home_server/src/server && GOOS=linux GOARCH=amd64 go build -o /data/devops/MergePet/main main.go
|
||||
# delegate_to: localhost
|
||||
# - name: reload main
|
||||
# copy:
|
||||
# src: /data/devops/MergePet/main
|
||||
# dest: /usr/local/Goleaf/main
|
||||
|
||||
@ -13,19 +13,12 @@
|
||||
tar_dest: /usr/local/Goleaf
|
||||
|
||||
tasks:
|
||||
- name: stop goleaf
|
||||
command: "{{ goleaf_dest }}/tool/tool stop node 3"
|
||||
register: stop_result
|
||||
# - name: stop goleaf
|
||||
# command: "{{ goleaf_dest }}/tool/tool stop node 3"
|
||||
# register: stop_result
|
||||
|
||||
- name: show stop_result
|
||||
debug:
|
||||
var: stop_result.stdout_lines
|
||||
- name: change git branch
|
||||
shell: cd /codes/pet_home_server && git checkout develop && git pull
|
||||
delegate_to: localhost
|
||||
register: git_result
|
||||
- name: sh pack.sh
|
||||
shell: sh /data/devops/pack.sh
|
||||
shell: sh /data/devops/pack_local.sh
|
||||
delegate_to: localhost
|
||||
|
||||
- name: copy goleaf
|
||||
@ -33,19 +26,19 @@
|
||||
src: "{{ goleaf_src }}"
|
||||
dest: "{{goleaf_dest}}"
|
||||
|
||||
- name: copy goleaf
|
||||
command: tar -cvf /usr/local/conf.tar -C /data/docs/tool/out .
|
||||
delegate_to: localhost
|
||||
- name: copy tar
|
||||
copy:
|
||||
src: /usr/local/conf.tar
|
||||
dest: /usr/local/Goleaf
|
||||
- name : untar
|
||||
command: tar -xvf /usr/local/Goleaf/conf.tar -C /usr/local/Goleaf/config/
|
||||
# - name: copy goleaf
|
||||
# command: tar -cvf /usr/local/conf.tar -C /data/docs/tool/out .
|
||||
# delegate_to: localhost
|
||||
# - name: copy tar
|
||||
# copy:
|
||||
# src: /usr/local/conf.tar
|
||||
# dest: /usr/local/Goleaf
|
||||
# - name : untar
|
||||
# command: tar -xvf /usr/local/Goleaf/conf.tar -C /usr/local/Goleaf/config/
|
||||
|
||||
|
||||
- name: start goleaf
|
||||
shell: nohup /usr/local/Goleaf/tool/tool start node 3 &
|
||||
shell: nohup /usr/local/Goleaf/tool/tool restart node 5 &
|
||||
register: restart_result
|
||||
|
||||
- name: show restart result
|
||||
|
||||
@ -13,19 +13,8 @@
|
||||
tar_dest: /usr/local/Goleaf
|
||||
|
||||
tasks:
|
||||
- name: stop goleaf
|
||||
command: "{{ goleaf_dest }}/tool/tool stop node 4"
|
||||
register: stop_result
|
||||
|
||||
- name: show stop_result
|
||||
debug:
|
||||
var: stop_result.stdout_lines
|
||||
- name: change git branch
|
||||
shell: cd /codes/pet_home_server && git checkout develop && git pull
|
||||
delegate_to: localhost
|
||||
register: git_result
|
||||
- name: sh pack.sh
|
||||
shell: sh /data/devops/pack.sh
|
||||
shell: sh /data/devops/pack_local.sh
|
||||
delegate_to: localhost
|
||||
|
||||
- name: copy goleaf
|
||||
@ -33,19 +22,19 @@
|
||||
src: "{{ goleaf_src }}"
|
||||
dest: "{{goleaf_dest}}"
|
||||
|
||||
- name: copy goleaf
|
||||
command: tar -cvf /usr/local/conf.tar -C /data/docs/tool/out .
|
||||
delegate_to: localhost
|
||||
- name: copy tar
|
||||
copy:
|
||||
src: /usr/local/conf.tar
|
||||
dest: /usr/local/Goleaf
|
||||
- name : untar
|
||||
command: tar -xvf /usr/local/Goleaf/conf.tar -C /usr/local/Goleaf/config/
|
||||
# - name: copy goleaf
|
||||
# command: tar -cvf /usr/local/conf.tar -C /data/docs/tool/out .
|
||||
# delegate_to: localhost
|
||||
# - name: copy tar
|
||||
# copy:
|
||||
# src: /usr/local/conf.tar
|
||||
# dest: /usr/local/Goleaf
|
||||
# - name : untar
|
||||
# command: tar -xvf /usr/local/Goleaf/conf.tar -C /usr/local/Goleaf/config/
|
||||
|
||||
|
||||
- name: start goleaf
|
||||
shell: nohup /usr/local/Goleaf/tool/tool start node 4 &
|
||||
shell: nohup /usr/local/Goleaf/tool/tool restart node 4 &
|
||||
register: restart_result
|
||||
|
||||
- name: show restart result
|
||||
|
||||
@ -11,7 +11,8 @@ a2 ansible_ssh_host=172.20.0.3 ansible_ssh_user="root" ansible_ssh_port=22
|
||||
|
||||
[google]
|
||||
g1 ansible_ssh_host=47.254.83.25 ansible_ssh_user="root" ansible_ssh_port=22
|
||||
|
||||
[google-sdk]
|
||||
gs1 ansible_ssh_host=47.88.106.149 ansible_ssh_user="root" ansible_ssh_port=22
|
||||
[gitea]
|
||||
gitea1 ansible_ssh_host=8.155.14.94 ansible_ssh_user="root" ansible_ssh_port=22
|
||||
|
||||
@ -21,4 +22,10 @@ g1 ansible_ssh_host=47.254.83.25 ansible_ssh_user="root" ansible_ssh_port=22
|
||||
|
||||
|
||||
[london]
|
||||
london_1 ansible_ssh_host=8.208.47.208 ansible_ssh_user="root" ansible_ssh_port=22
|
||||
london_1 ansible_ssh_host=8.208.47.208 ansible_ssh_user="root" ansible_ssh_port=22
|
||||
|
||||
[nginxservice]
|
||||
w1 ansible_ssh_host=1.15.182.107 ansible_ssh_user="root" ansible_ssh_port=22
|
||||
w2 ansible_ssh_host=47.254.83.25 ansible_ssh_user="root" ansible_ssh_port=22
|
||||
w3 ansible_ssh_host=47.88.106.149 ansible_ssh_user="root" ansible_ssh_port=22
|
||||
w4 ansible_ssh_host=8.155.14.94 ansible_ssh_user="root" ansible_ssh_port=22
|
||||
27
playbook/login_service.yml
Normal file
27
playbook/login_service.yml
Normal file
@ -0,0 +1,27 @@
|
||||
---
|
||||
- name: Deploy GoLeaf release
|
||||
hosts: gitea:google-sdk
|
||||
remote_user: root
|
||||
|
||||
tasks:
|
||||
- name: pack.sh
|
||||
shell: sh /data/admin_backend/release/login_service/login_pack.sh
|
||||
delegate_to: localhost
|
||||
- name: copy main
|
||||
copy:
|
||||
src: /data/admin_backend/release/login_service/login_service
|
||||
dest: /data/meow/login_service/login_service
|
||||
mode: 0755
|
||||
- name: copy start script
|
||||
copy:
|
||||
src: /data/admin_backend/release/login_service/start.sh
|
||||
dest: /data/meow/login_service/start.sh
|
||||
mode: 0755
|
||||
# - name: copy config
|
||||
# copy:
|
||||
# src: /data/admin_backend/release/login_service/conf
|
||||
# dest: /data/meow/login_service/
|
||||
# mode: 0644
|
||||
|
||||
- name: restart web
|
||||
shell: sh /data/meow/login_service/start.sh restart
|
||||
79
playbook/moveDockerFile.yml
Normal file
79
playbook/moveDockerFile.yml
Normal file
@ -0,0 +1,79 @@
|
||||
---
|
||||
- name: Move Docker data-root to /data/docker
|
||||
hosts: google-sdk
|
||||
become: true
|
||||
vars:
|
||||
new_docker_root: /data/docker
|
||||
old_docker_root: /var/lib/docker
|
||||
tasks:
|
||||
- name: Ensure rsync installed
|
||||
package:
|
||||
name: rsync
|
||||
state: present
|
||||
|
||||
- name: Stop Docker service
|
||||
service:
|
||||
name: docker
|
||||
state: stopped
|
||||
ignore_errors: true
|
||||
|
||||
- name: Create new data root
|
||||
file:
|
||||
path: "{{ new_docker_root }}"
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: Check old docker root exists
|
||||
stat:
|
||||
path: "{{ old_docker_root }}"
|
||||
register: old_docker_root_stat
|
||||
|
||||
- name: Sync old data to new root (if old exists)
|
||||
command: rsync -aHAX --numeric-ids --delete {{ old_docker_root }}/ {{ new_docker_root }}/
|
||||
when: old_docker_root_stat.stat.exists
|
||||
args:
|
||||
warn: false
|
||||
|
||||
- name: Backup old directory
|
||||
command: mv {{ old_docker_root }} {{ old_docker_root }}.bak
|
||||
args:
|
||||
creates: "{{ old_docker_root }}.bak"
|
||||
when: old_docker_root_stat.stat.exists
|
||||
|
||||
- name: Ensure /etc/docker exists
|
||||
file:
|
||||
path: /etc/docker
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: Write daemon.json
|
||||
copy:
|
||||
dest: /etc/docker/daemon.json
|
||||
mode: '0644'
|
||||
content: |
|
||||
{
|
||||
"data-root": "{{ new_docker_root }}",
|
||||
"storage-driver": "overlay2",
|
||||
"log-driver": "json-file",
|
||||
"log-opts": { "max-size": "10m", "max-file": "3" }
|
||||
}
|
||||
|
||||
- name: Start Docker
|
||||
service:
|
||||
name: docker
|
||||
state: started
|
||||
enabled: true
|
||||
|
||||
- name: Verify root dir
|
||||
command: docker info --format '{% raw %}{{json .DockerRootDir}}{% endraw %}'
|
||||
register: docker_root
|
||||
changed_when: false
|
||||
|
||||
- name: Show result
|
||||
debug:
|
||||
msg: "DockerRootDir = {{ docker_root.stdout }}"
|
||||
|
||||
- name: Fail if not moved
|
||||
fail:
|
||||
msg: "迁移失败,当前仍是旧目录"
|
||||
when: docker_root.stdout.find(new_docker_root) == -1
|
||||
41
playbook/nginx.yml
Normal file
41
playbook/nginx.yml
Normal file
@ -0,0 +1,41 @@
|
||||
---
|
||||
- name: 安装 nginx 并同步本地 ssl 证书到远端 /etc/nginx/ssl
|
||||
hosts: google-sdk
|
||||
become: yes
|
||||
vars:
|
||||
remote_ssl_dir: /etc/nginx/ssl
|
||||
|
||||
tasks:
|
||||
- name: 安装 nginx 包
|
||||
package:
|
||||
name: nginx
|
||||
state: present
|
||||
|
||||
- name: 确保远端 ssl 目录存在
|
||||
file:
|
||||
path: "{{ remote_ssl_dir }}"
|
||||
state: directory
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0755'
|
||||
|
||||
- name: 将本地 ssl/ 目录同步到远端 /etc/nginx/ssl
|
||||
synchronize:
|
||||
src: "../ssl/"
|
||||
dest: "{{ remote_ssl_dir }}/"
|
||||
recursive: yes
|
||||
delete: no
|
||||
rsync_opts:
|
||||
- "--chmod=D0755,F0644"
|
||||
delegate_to: localhost
|
||||
|
||||
- name: 限制私钥文件权限为 0600(匹配 *.key)
|
||||
shell: "find {{ remote_ssl_dir }} -type f -name '*.key' -exec chmod 0600 {} \\;"
|
||||
args:
|
||||
warn: false
|
||||
|
||||
- name: 确保 nginx 已启用并运行
|
||||
service:
|
||||
name: nginx
|
||||
state: restarted
|
||||
enabled: yes
|
||||
33
playbook/sdk/init.yml
Normal file
33
playbook/sdk/init.yml
Normal file
@ -0,0 +1,33 @@
|
||||
---
|
||||
- name: 同步 nginx 配置并重启 nginx
|
||||
hosts: google-sdk
|
||||
become: yes
|
||||
vars:
|
||||
login_domain: login-us.bywaystudios.com
|
||||
shipping_domain: ship-us.bywaystudios.com
|
||||
tasks:
|
||||
- name: Render login.conf from template
|
||||
template:
|
||||
src: ../../nginx/login.conf.j2
|
||||
dest: /etc/nginx/conf.d/login.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
notify: Restart nginx
|
||||
|
||||
- name: Render shipping.conf from template
|
||||
template:
|
||||
src: ../../nginx/shipping.conf.j2
|
||||
dest: /etc/nginx/conf.d/shipping.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
notify: Restart nginx
|
||||
|
||||
handlers:
|
||||
- name: Restart nginx
|
||||
shell: nginx -t && systemctl restart nginx
|
||||
args:
|
||||
warn: false
|
||||
|
||||
- import_playbook: ../login_service.yml
|
||||
32
playbook/shipping_service.yml
Normal file
32
playbook/shipping_service.yml
Normal file
@ -0,0 +1,32 @@
|
||||
---
|
||||
- name: Deploy SDK Shipping Service release
|
||||
hosts: gitea:google-sdk
|
||||
remote_user: root
|
||||
|
||||
tasks:
|
||||
- name: remove previous build output
|
||||
file:
|
||||
path: /data/admin_backend/release/shipping_service/shipping_service
|
||||
state: absent
|
||||
delegate_to: localhost
|
||||
- name: pack.sh
|
||||
shell: sh /data/admin_backend/release/shipping_service/pack.sh
|
||||
delegate_to: localhost
|
||||
- name: copy main
|
||||
copy:
|
||||
src: /data/admin_backend/release/shipping_service/shipping_service
|
||||
dest: /data/meow/shipping_service/shipping_service
|
||||
mode: 0755
|
||||
- name: copy start script
|
||||
copy:
|
||||
src: /data/admin_backend/release/shipping_service/start.sh
|
||||
dest: /data/meow/shipping_service
|
||||
mode: 0755
|
||||
# - name: copy config
|
||||
# copy:
|
||||
# src: /data/admin_backend/release/shipping_service/conf
|
||||
# dest: /data/meow/shipping_service/
|
||||
# mode: 0644
|
||||
|
||||
# - name: restart web
|
||||
# shell: sh /data/meow/shipping_service/start.sh restart
|
||||
53
playbook/ssl.yml
Normal file
53
playbook/ssl.yml
Normal file
@ -0,0 +1,53 @@
|
||||
---
|
||||
- name: Update Nginx SSL Configuration
|
||||
hosts: nginxservice
|
||||
become: yes
|
||||
vars:
|
||||
nginx_ssl_cert_path: /etc/nginx/ssl/bywaystudios.com.pem
|
||||
nginx_ssl_key_path: /etc/nginx/ssl/bywaystudios.com.key
|
||||
nginx_config_path: /etc/nginx/sites-available/default
|
||||
nginx_ssl_cert_src: ssl/bywaystudios.com.pem # 新增:证书源文件,可通过 vars/inventory/extra_vars 覆盖
|
||||
nginx_ssl_key_src: ssl/bywaystudios.com.key # 新增:私钥源文件,可通过 vars/inventory/extra_vars 覆盖
|
||||
|
||||
tasks:
|
||||
- name: Create SSL directory
|
||||
file:
|
||||
path: /etc/nginx/ssl
|
||||
state: directory
|
||||
mode: '0755'
|
||||
|
||||
- name: Copy SSL certificate
|
||||
copy:
|
||||
src: "{{ nginx_ssl_cert_src }}"
|
||||
dest: "{{ nginx_ssl_cert_path }}"
|
||||
mode: '0644'
|
||||
notify: Reload Nginx
|
||||
|
||||
- name: Copy SSL private key
|
||||
copy:
|
||||
src: "{{ nginx_ssl_key_src }}"
|
||||
dest: "{{ nginx_ssl_key_path }}"
|
||||
mode: '0600'
|
||||
notify: Reload Nginx
|
||||
|
||||
# - name: Update Nginx SSL configuration
|
||||
# template:
|
||||
# src: templates/nginx-ssl.conf.j2
|
||||
# dest: "{{ nginx_config_path }}"
|
||||
# mode: '0644'
|
||||
# notify: Reload Nginx
|
||||
|
||||
- name: Test Nginx configuration
|
||||
command: nginx -t
|
||||
register: nginx_test
|
||||
changed_when: false
|
||||
|
||||
- name: Display Nginx test result
|
||||
debug:
|
||||
msg: "{{ nginx_test.stderr }}"
|
||||
|
||||
handlers:
|
||||
- name: Reload Nginx
|
||||
service:
|
||||
name: nginx
|
||||
state: reloaded
|
||||
@ -37,5 +37,5 @@
|
||||
src: /data/admin_backend/release/backend
|
||||
dest: /usr/local/admin/backend
|
||||
|
||||
# - name: untar
|
||||
# shell: tar -xvf /usr/local/admin/backend.tar -C /usr/local/admin/backend/
|
||||
# - name: restart web
|
||||
# shell: nohup sh /usr/local/admin/backend/start.sh restart
|
||||
162
script.log
Normal file
162
script.log
Normal file
@ -0,0 +1,162 @@
|
||||
2025-07-09 10:16:50,830 - INFO - 开始执行数据库备份和清空脚本
|
||||
2025-07-09 10:16:53,033 - INFO - MySQL连接成功
|
||||
2025-07-09 10:16:53,823 - INFO - Redis连接成功
|
||||
2025-07-09 10:16:53,824 - INFO - 开始备份MySQL数据库...
|
||||
2025-07-09 10:16:59,823 - ERROR - 备份数据库 Merge_Pet_1 时发生错误: [WinError 2] 系统找不到指定的文件。
|
||||
2025-07-09 10:16:59,824 - WARNING - MySQL备份失败或没有数据库需要备份
|
||||
2025-07-09 10:16:59,824 - INFO - 开始备份Redis数据库...
|
||||
2025-07-09 10:17:00,440 - INFO - Redis后台保存已启动
|
||||
2025-07-09 10:21:24,549 - INFO - 开始执行数据库备份和清空脚本
|
||||
2025-07-09 10:21:24,843 - INFO - MySQL连接成功
|
||||
2025-07-09 10:21:24,881 - INFO - Redis连接成功
|
||||
2025-07-09 10:21:24,882 - INFO - 开始备份MySQL数据库...
|
||||
2025-07-09 10:21:25,203 - ERROR - 备份数据库 Merge_Pet_1 时发生错误: [WinError 2] 系统找不到指定的文件。
|
||||
2025-07-09 10:21:25,205 - WARNING - MySQL备份失败或没有数据库需要备份
|
||||
2025-07-09 10:21:25,205 - INFO - 开始备份Redis数据库...
|
||||
2025-07-09 10:21:25,207 - INFO - Redis后台保存已启动
|
||||
2025-07-09 10:21:25,207 - ERROR - 备份Redis数据失败: 'DatabaseManager' object has no attribute 'redis'
|
||||
2025-07-09 10:21:43,686 - INFO - 开始清空MySQL数据库...
|
||||
2025-07-09 10:21:47,306 - INFO - 用户中断了脚本执行
|
||||
2025-07-09 10:21:47,306 - INFO - MySQL连接已关闭
|
||||
2025-07-09 10:21:47,307 - INFO - Redis连接已关闭
|
||||
2025-07-09 10:22:26,089 - INFO - 开始执行数据库备份和清空脚本
|
||||
2025-07-09 10:22:26,276 - INFO - MySQL连接成功
|
||||
2025-07-09 10:22:26,301 - INFO - Redis连接成功
|
||||
2025-07-09 10:22:26,301 - INFO - 开始备份MySQL数据库...
|
||||
2025-07-09 10:26:55,757 - INFO - 开始执行数据库备份和清空脚本
|
||||
2025-07-09 10:26:55,871 - INFO - MySQL连接成功
|
||||
2025-07-09 10:26:55,924 - INFO - Redis连接成功
|
||||
2025-07-09 10:26:55,925 - INFO - 开始备份MySQL数据库...
|
||||
2025-07-09 10:26:56,192 - INFO - 准备备份数据库 Merge_Pet_1 到文件: sql\Merge_Pet_1_20250709_102656.sql
|
||||
2025-07-09 10:26:56,230 - ERROR - 备份数据库 Merge_Pet_1 时发生错误: [WinError 2] 系统找不到指定的文件。
|
||||
2025-07-09 10:26:56,230 - WARNING - MySQL备份失败或没有数据库需要备份
|
||||
2025-07-09 10:26:56,230 - INFO - 开始备份Redis数据库...
|
||||
2025-07-09 10:26:56,233 - INFO - Redis后台保存已启动
|
||||
2025-07-09 10:26:56,235 - INFO - 等待Redis数据保存完成...
|
||||
2025-07-09 10:26:57,237 - INFO - Redis数据保存完成
|
||||
2025-07-09 10:26:57,360 - INFO - Redis RDB文件路径: /data\dump.rdb
|
||||
2025-07-09 10:26:57,361 - WARNING - 找不到Redis RDB文件: /data\dump.rdb
|
||||
2025-07-09 10:26:57,362 - INFO - 创建Redis文本格式备份: sql\redis_20250709_102656.txt
|
||||
2025-07-09 10:26:57,409 - INFO - 正在导出 114 个Redis键...
|
||||
2025-07-09 10:26:57,548 - INFO - Redis文本备份创建成功: sql\redis_20250709_102656.txt
|
||||
2025-07-09 10:26:57,548 - INFO - Redis备份完成
|
||||
2025-07-09 10:27:13,328 - INFO - 用户取消清空操作
|
||||
2025-07-09 10:27:13,328 - INFO - MySQL连接已关闭
|
||||
2025-07-09 10:27:13,329 - INFO - Redis连接已关闭
|
||||
2025-07-09 10:28:18,999 - INFO - 开始执行数据库备份和清空脚本
|
||||
2025-07-09 10:28:19,067 - INFO - MySQL连接成功
|
||||
2025-07-09 10:28:19,114 - INFO - Redis连接成功
|
||||
2025-07-09 10:28:19,115 - INFO - 开始备份MySQL数据库...
|
||||
2025-07-09 10:28:19,403 - INFO - 准备备份数据库 Merge_Pet_1 到文件: sql\Merge_Pet_1_20250709_102819.sql
|
||||
2025-07-09 10:28:19,435 - ERROR - 备份数据库 Merge_Pet_1 时发生错误: [WinError 2] 系统找不到指定的文件。
|
||||
2025-07-09 10:28:19,436 - WARNING - MySQL备份失败或没有数据库需要备份
|
||||
2025-07-09 10:28:19,436 - INFO - 开始备份Redis数据库...
|
||||
2025-07-09 10:28:19,443 - INFO - Redis后台保存已启动
|
||||
2025-07-09 10:28:19,444 - INFO - 等待Redis数据保存完成...
|
||||
2025-07-09 10:28:20,446 - INFO - Redis数据保存完成
|
||||
2025-07-09 10:28:20,449 - INFO - Redis RDB文件路径: /data\dump.rdb
|
||||
2025-07-09 10:28:20,449 - WARNING - 找不到Redis RDB文件: /data\dump.rdb
|
||||
2025-07-09 10:28:20,450 - INFO - 创建Redis文本格式备份: sql\redis_20250709_102819.txt
|
||||
2025-07-09 10:28:20,465 - INFO - 正在导出 114 个Redis键...
|
||||
2025-07-09 10:28:20,618 - INFO - Redis文本备份创建成功: sql\redis_20250709_102819.txt
|
||||
2025-07-09 10:28:20,618 - INFO - Redis备份完成
|
||||
2025-07-09 10:28:40,414 - INFO - 开始执行数据库备份和清空脚本
|
||||
2025-07-09 10:28:40,473 - INFO - MySQL连接成功
|
||||
2025-07-09 10:28:40,504 - INFO - Redis连接成功
|
||||
2025-07-09 10:28:40,504 - INFO - 开始备份MySQL数据库...
|
||||
2025-07-09 10:28:40,759 - INFO - 准备备份数据库 Merge_Pet_1 到文件: sql\Merge_Pet_1_20250709_102840.sql
|
||||
2025-07-09 02:35:56,610 - INFO - 寮€濮嬫墽琛屾暟鎹<E69A9F>簱澶囦唤鍜屾竻绌鸿剼鏈<E589BC>
|
||||
2025-07-09 02:35:56,637 - ERROR - MySQL杩炴帴澶辫触: (2003, "Can't connect to MySQL server on 'localhost' ([Errno 111] Connection refused)")
|
||||
2025-07-09 02:35:56,639 - ERROR - Redis杩炴帴澶辫触: Error 111 connecting to localhost:6379. Connection refused.
|
||||
2025-07-09 02:35:56,639 - ERROR - 鏃犳硶杩炴帴鍒颁换浣曟暟鎹<E69A9F>簱锛岃剼鏈<E589BC>€€鍑<E282AC>
|
||||
2025-07-09 02:35:56,640 - INFO - Redis杩炴帴宸插叧闂<E58FA7>
|
||||
2025-07-09 02:37:14,841 - INFO - 寮€濮嬫墽琛屾暟鎹<E69A9F>簱澶囦唤鍜屾竻绌鸿剼鏈<E589BC>
|
||||
2025-07-09 02:37:15,110 - INFO - MySQL杩炴帴鎴愬姛
|
||||
2025-07-09 02:37:15,112 - INFO - Redis杩炴帴鎴愬姛
|
||||
2025-07-09 02:37:15,112 - INFO - 寮€濮嬪<E6BFAE>浠組ySQL鏁版嵁搴<E5B581>...
|
||||
2025-07-09 02:37:15,395 - INFO - 鍑嗗<E98D91>澶囦唤鏁版嵁搴<E5B581> Merge_Pet_1 鍒版枃浠<E69E83>: sql/Merge_Pet_1_20250709_023715.sql
|
||||
2025-07-09 02:37:21,737 - INFO - 鏁版嵁搴<E5B581> Merge_Pet_1 澶囦唤鎴愬姛: sql/Merge_Pet_1_20250709_023715.sql (澶у皬: 2378614 瀛楄妭)
|
||||
2025-07-09 02:37:21,738 - INFO - MySQL澶囦唤瀹屾垚锛屽叡澶囦唤 1 涓<>暟鎹<E69A9F>簱
|
||||
2025-07-09 02:37:21,738 - INFO - 寮€濮嬪<E6BFAE>浠絉edis鏁版嵁搴<E5B581>...
|
||||
2025-07-09 02:37:21,741 - INFO - Redis鍚庡彴淇濆瓨宸插惎鍔<E6838E>
|
||||
2025-07-09 02:37:21,742 - INFO - 绛夊緟Redis鏁版嵁淇濆瓨瀹屾垚...
|
||||
2025-07-09 02:37:22,743 - INFO - Redis鏁版嵁淇濆瓨瀹屾垚
|
||||
2025-07-09 02:37:22,744 - INFO - Redis RDB鏂囦欢璺<E6ACA2>緞: /data/dump.rdb
|
||||
2025-07-09 02:37:22,745 - WARNING - 鎵句笉鍒癛edis RDB鏂囦欢: /data/dump.rdb
|
||||
2025-07-09 02:37:22,747 - INFO - 鍒涘缓Redis鏂囨湰鏍煎紡澶囦唤: sql/redis_20250709_023721.txt
|
||||
2025-07-09 02:37:22,751 - INFO - 姝e湪瀵煎嚭 114 涓猂edis閿<73>...
|
||||
2025-07-09 02:37:22,804 - INFO - Redis鏂囨湰澶囦唤鍒涘缓鎴愬姛: sql/redis_20250709_023721.txt
|
||||
2025-07-09 02:37:22,804 - INFO - Redis澶囦唤瀹屾垚
|
||||
2025-07-09 02:37:35,300 - INFO - 鐢ㄦ埛鍙栨秷娓呯┖鎿嶄綔
|
||||
2025-07-09 02:37:35,301 - INFO - MySQL杩炴帴宸插叧闂<E58FA7>
|
||||
2025-07-09 02:37:35,301 - INFO - Redis杩炴帴宸插叧闂<E58FA7>
|
||||
2025-07-09 02:43:39,640 - INFO - 寮€濮嬫墽琛屾暟鎹<E69A9F>簱澶囦唤鍜屾竻绌鸿剼鏈<E589BC>
|
||||
2025-07-09 02:43:39,677 - INFO - MySQL杩炴帴鎴愬姛
|
||||
2025-07-09 02:43:39,679 - INFO - Redis杩炴帴鎴愬姛
|
||||
2025-07-09 02:43:39,680 - INFO - 寮€濮嬪<E6BFAE>浠組ySQL鏁版嵁搴<E5B581>...
|
||||
2025-07-09 02:43:39,744 - INFO - 鍑嗗<E98D91>澶囦唤鏁版嵁搴<E5B581> Merge_Pet_1 鍒版枃浠<E69E83>: sql/Merge_Pet_1_20250709_024339.sql
|
||||
2025-07-09 02:43:40,424 - INFO - 鏁版嵁搴<E5B581> Merge_Pet_1 澶囦唤鎴愬姛: sql/Merge_Pet_1_20250709_024339.sql (澶у皬: 2378612 瀛楄妭)
|
||||
2025-07-09 02:43:40,424 - INFO - MySQL澶囦唤瀹屾垚锛屽叡澶囦唤 1 涓<>暟鎹<E69A9F>簱
|
||||
2025-07-09 02:43:40,424 - INFO - 寮€濮嬪<E6BFAE>浠絉edis鏁版嵁搴<E5B581>...
|
||||
2025-07-09 02:43:40,427 - INFO - Redis鍚庡彴淇濆瓨宸插惎鍔<E6838E>
|
||||
2025-07-09 02:43:40,428 - INFO - 绛夊緟Redis鏁版嵁淇濆瓨瀹屾垚...
|
||||
2025-07-09 02:43:41,428 - INFO - Redis鏁版嵁淇濆瓨瀹屾垚
|
||||
2025-07-09 02:43:41,429 - INFO - Redis RDB鏂囦欢璺<E6ACA2>緞: /data/dump.rdb
|
||||
2025-07-09 02:43:41,430 - WARNING - 鎵句笉鍒癛edis RDB鏂囦欢: /data/dump.rdb
|
||||
2025-07-09 02:43:41,433 - INFO - 鍒涘缓Redis鏂囨湰鏍煎紡澶囦唤: sql/redis_20250709_024340.txt
|
||||
2025-07-09 02:43:41,436 - INFO - 姝e湪瀵煎嚭 114 涓猂edis閿<73>...
|
||||
2025-07-09 02:43:41,487 - INFO - Redis鏂囨湰澶囦唤鍒涘缓鎴愬姛: sql/redis_20250709_024340.txt
|
||||
2025-07-09 02:43:41,487 - INFO - Redis澶囦唤瀹屾垚
|
||||
2025-07-09 02:43:42,891 - INFO - 寮€濮嬫竻绌篗ySQL鏁版嵁搴<E5B581>...
|
||||
2025-07-09 02:43:44,155 - INFO - 宸叉竻绌鸿〃: Merge_Pet_1.db_version
|
||||
2025-07-09 02:43:45,240 - INFO - 宸叉竻绌鸿〃: Merge_Pet_1.system_mail_info
|
||||
2025-07-09 02:43:46,625 - INFO - 宸叉竻绌鸿〃: Merge_Pet_1.t_account
|
||||
2025-07-09 02:43:47,674 - INFO - 宸叉竻绌鸿〃: Merge_Pet_1.t_gameserver
|
||||
2025-07-09 02:43:49,208 - INFO - 宸叉竻绌鸿〃: Merge_Pet_1.t_player_baseinfo
|
||||
2025-07-09 02:43:50,275 - INFO - 宸叉竻绌鸿〃: Merge_Pet_1.t_player_charge
|
||||
2025-07-09 02:43:51,196 - INFO - 宸叉竻绌鸿〃: Merge_Pet_1.t_player_mod
|
||||
2025-07-09 02:43:52,310 - INFO - 宸叉竻绌鸿〃: Merge_Pet_1.t_server_mod
|
||||
2025-07-09 02:43:52,311 - INFO - 鏁版嵁搴<E5B581> Merge_Pet_1 鎵€鏈夎〃宸叉竻绌<E7ABBB>
|
||||
2025-07-09 02:43:52,312 - INFO - MySQL鏁版嵁搴撴竻绌哄畬鎴<E795AC>
|
||||
2025-07-09 02:43:52,312 - INFO - 寮€濮嬫竻绌篟edis鏁版嵁搴<E5B581>...
|
||||
2025-07-09 02:43:52,313 - INFO - Redis鏁版嵁搴撳綋鍓嶆湁 114 涓猭ey
|
||||
2025-07-09 02:43:52,512 - INFO - Redis鏁版嵁搴撳凡娓呯┖
|
||||
2025-07-09 02:43:52,513 - INFO - Redis鏁版嵁搴撴竻绌哄畬鎴<E795AC>
|
||||
2025-07-09 02:43:52,513 - INFO - 鎵€鏈夋搷浣滃畬鎴<E795AC>
|
||||
2025-07-09 02:43:52,513 - INFO - MySQL杩炴帴宸插叧闂<E58FA7>
|
||||
2025-07-09 02:43:52,514 - INFO - Redis杩炴帴宸插叧闂<E58FA7>
|
||||
2025-07-09 02:47:05,098 - INFO - 寮€濮嬫墽琛屾暟鎹<E69A9F>簱澶囦唤鍜屾竻绌鸿剼鏈<E589BC>
|
||||
2025-07-09 02:47:05,168 - INFO - MySQL杩炴帴鎴愬姛
|
||||
2025-07-09 02:47:05,180 - INFO - Redis杩炴帴鎴愬姛
|
||||
2025-07-09 02:47:05,180 - INFO - 寮€濮嬪<E6BFAE>浠組ySQL鏁版嵁搴<E5B581>...
|
||||
2025-07-09 02:47:05,250 - INFO - 鍑嗗<E98D91>澶囦唤鏁版嵁搴<E5B581> Merge_Pet_1 鍒版枃浠<E69E83>: backups/Merge_Pet_1_20250709_024705.sql
|
||||
2025-07-09 02:47:05,698 - INFO - 鏁版嵁搴<E5B581> Merge_Pet_1 澶囦唤鎴愬姛: backups/Merge_Pet_1_20250709_024705.sql (澶у皬: 12226 瀛楄妭)
|
||||
2025-07-09 02:47:05,699 - INFO - MySQL澶囦唤瀹屾垚锛屽叡澶囦唤 1 涓<>暟鎹<E69A9F>簱
|
||||
2025-07-09 02:47:05,699 - INFO - 寮€濮嬪<E6BFAE>浠絉edis鏁版嵁搴<E5B581>...
|
||||
2025-07-09 02:47:05,702 - INFO - Redis鍚庡彴淇濆瓨宸插惎鍔<E6838E>
|
||||
2025-07-09 02:47:05,703 - INFO - 绛夊緟Redis鏁版嵁淇濆瓨瀹屾垚...
|
||||
2025-07-09 02:47:06,704 - INFO - Redis鏁版嵁淇濆瓨瀹屾垚
|
||||
2025-07-09 02:47:06,705 - INFO - Redis RDB鏂囦欢璺<E6ACA2>緞: /data/dump.rdb
|
||||
2025-07-09 02:47:06,706 - WARNING - 鎵句笉鍒癛edis RDB鏂囦欢: /data/dump.rdb
|
||||
2025-07-09 02:47:06,707 - INFO - 鍒涘缓Redis鏂囨湰鏍煎紡澶囦唤: backups/redis_20250709_024705.txt
|
||||
2025-07-09 02:47:06,709 - INFO - Redis鏁版嵁搴撲负绌猴紝鍒涘缓绌哄<E7BB8C>浠芥枃浠<E69E83>
|
||||
2025-07-09 02:47:06,712 - INFO - Redis鏂囨湰澶囦唤鍒涘缓鎴愬姛: backups/redis_20250709_024705.txt
|
||||
2025-07-09 02:47:06,712 - INFO - Redis澶囦唤瀹屾垚
|
||||
2025-07-09 02:47:10,331 - INFO - 寮€濮嬫竻绌篗ySQL鏁版嵁搴<E5B581>...
|
||||
2025-07-09 02:47:11,425 - INFO - 宸叉竻绌鸿〃: Merge_Pet_1.db_version
|
||||
2025-07-09 02:47:12,500 - INFO - 宸叉竻绌鸿〃: Merge_Pet_1.system_mail_info
|
||||
2025-07-09 02:47:13,638 - INFO - 宸叉竻绌鸿〃: Merge_Pet_1.t_account
|
||||
2025-07-09 02:47:14,467 - INFO - 宸叉竻绌鸿〃: Merge_Pet_1.t_gameserver
|
||||
2025-07-09 02:47:15,614 - INFO - 宸叉竻绌鸿〃: Merge_Pet_1.t_player_baseinfo
|
||||
2025-07-09 02:47:16,548 - INFO - 宸叉竻绌鸿〃: Merge_Pet_1.t_player_charge
|
||||
2025-07-09 02:47:17,448 - INFO - 宸叉竻绌鸿〃: Merge_Pet_1.t_player_mod
|
||||
2025-07-09 02:47:18,290 - INFO - 宸叉竻绌鸿〃: Merge_Pet_1.t_server_mod
|
||||
2025-07-09 02:47:18,291 - INFO - 鏁版嵁搴<E5B581> Merge_Pet_1 鎵€鏈夎〃宸叉竻绌<E7ABBB>
|
||||
2025-07-09 02:47:18,291 - INFO - MySQL鏁版嵁搴撴竻绌哄畬鎴<E795AC>
|
||||
2025-07-09 02:47:18,291 - INFO - 寮€濮嬫竻绌篟edis鏁版嵁搴<E5B581>...
|
||||
2025-07-09 02:47:18,292 - INFO - Redis鏁版嵁搴撳綋鍓嶆湁 0 涓猭ey
|
||||
2025-07-09 02:47:18,292 - INFO - Redis鏁版嵁搴撳凡缁忔槸绌虹殑
|
||||
2025-07-09 02:47:18,293 - INFO - Redis鏁版嵁搴撴竻绌哄畬鎴<E795AC>
|
||||
2025-07-09 02:47:18,293 - INFO - 鎵€鏈夋搷浣滃畬鎴<E795AC>
|
||||
2025-07-09 02:47:18,294 - INFO - MySQL杩炴帴宸插叧闂<E58FA7>
|
||||
2025-07-09 02:47:18,294 - INFO - Redis杩炴帴宸插叧闂<E58FA7>
|
||||
217
script.py
217
script.py
@ -3,8 +3,8 @@
|
||||
"""
|
||||
数据库备份和清空脚本
|
||||
功能:
|
||||
1. 备份MySQL数据库
|
||||
2. 清空MySQL数据库
|
||||
1. 备份MySQL数据库(支持指定特定数据库)
|
||||
2. 清空MySQL数据库(支持指定特定数据库)
|
||||
3. 清空Redis数据库
|
||||
"""
|
||||
|
||||
@ -30,15 +30,15 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
# 数据库配置
|
||||
MYSQL_CONFIG = {
|
||||
'host': '172.20.0.5',
|
||||
'host': '127.0.0.1',
|
||||
'port': 3306,
|
||||
'user': 'root',
|
||||
'password': 'root',
|
||||
'password': 'Xijing1!',
|
||||
'charset': 'utf8mb4'
|
||||
}
|
||||
|
||||
REDIS_CONFIG = {
|
||||
'host': '172.20.0.6',
|
||||
'host': '127.0.0.1',
|
||||
'port': 6379,
|
||||
'password': None, # 如果有密码请设置
|
||||
'db': 0
|
||||
@ -47,12 +47,16 @@ REDIS_CONFIG = {
|
||||
# 备份目录
|
||||
BACKUP_DIR = './backups'
|
||||
|
||||
# 指定要操作的数据库列表(为空表示操作所有用户数据库)
|
||||
TARGET_DATABASES = ["merge_pet_1"] # 例如: ['database1', 'database2']
|
||||
|
||||
class DatabaseManager:
|
||||
def __init__(self):
|
||||
def __init__(self, target_databases=None):
|
||||
self.mysql_conn = None
|
||||
self.redis_conn = None
|
||||
self.backup_dir = Path(BACKUP_DIR)
|
||||
self.backup_dir.mkdir(exist_ok=True)
|
||||
self.target_databases = target_databases or []
|
||||
|
||||
def connect_mysql(self):
|
||||
"""连接MySQL数据库"""
|
||||
@ -115,7 +119,7 @@ class DatabaseManager:
|
||||
# 创建备份文件(如果不存在会自动创建)
|
||||
logger.info(f"准备备份数据库 {database_name} 到文件: {backup_file}")
|
||||
with open(backup_file, 'w', encoding='utf-8') as f:
|
||||
result = subprocess.run(cmd, stdout=f, stderr=subprocess.PIPE, text=True)
|
||||
result = subprocess.run(cmd, stdout=f, stderr=subprocess.PIPE, start_new_session=True)
|
||||
|
||||
if result.returncode == 0:
|
||||
# 检查备份文件是否创建成功并且有内容
|
||||
@ -151,6 +155,86 @@ class DatabaseManager:
|
||||
|
||||
return backup_files
|
||||
|
||||
def get_target_databases(self):
|
||||
"""获取要操作的数据库列表"""
|
||||
all_databases = self.get_mysql_databases()
|
||||
if not all_databases:
|
||||
logger.warning("没有找到用户数据库")
|
||||
return []
|
||||
|
||||
if self.target_databases:
|
||||
# 验证指定的数据库是否存在
|
||||
valid_databases = []
|
||||
for db in self.target_databases:
|
||||
if db in all_databases:
|
||||
valid_databases.append(db)
|
||||
else:
|
||||
logger.warning(f"指定的数据库 '{db}' 不存在")
|
||||
return valid_databases
|
||||
else:
|
||||
# 如果没有指定,让用户选择
|
||||
return self.select_databases_interactively(all_databases)
|
||||
|
||||
def select_databases_interactively(self, all_databases):
|
||||
"""交互式选择数据库"""
|
||||
print("\n可用的数据库列表:")
|
||||
for i, db in enumerate(all_databases, 1):
|
||||
print(f"{i}. {db}")
|
||||
|
||||
print(f"{len(all_databases) + 1}. 所有数据库")
|
||||
print("0. 退出")
|
||||
|
||||
while True:
|
||||
try:
|
||||
choice = input("\n请选择要操作的数据库(输入数字,多个数字用逗号分隔): ").strip()
|
||||
|
||||
if choice == '0':
|
||||
logger.info("用户选择退出")
|
||||
return []
|
||||
|
||||
if choice == str(len(all_databases) + 1):
|
||||
logger.info("用户选择操作所有数据库")
|
||||
return all_databases
|
||||
|
||||
# 解析用户输入的数字
|
||||
selected_indices = [int(x.strip()) for x in choice.split(',') if x.strip()]
|
||||
selected_databases = []
|
||||
|
||||
for index in selected_indices:
|
||||
if 1 <= index <= len(all_databases):
|
||||
selected_databases.append(all_databases[index - 1])
|
||||
else:
|
||||
print(f"无效的选择: {index}")
|
||||
continue
|
||||
|
||||
if selected_databases:
|
||||
logger.info(f"用户选择的数据库: {', '.join(selected_databases)}")
|
||||
return selected_databases
|
||||
else:
|
||||
print("没有有效的选择,请重新输入")
|
||||
|
||||
except ValueError:
|
||||
print("输入格式错误,请输入数字")
|
||||
except KeyboardInterrupt:
|
||||
logger.info("用户中断操作")
|
||||
return []
|
||||
|
||||
def backup_selected_mysql_databases(self):
|
||||
"""备份选定的MySQL数据库"""
|
||||
databases = self.get_target_databases()
|
||||
if not databases:
|
||||
logger.warning("没有选择要备份的数据库")
|
||||
return []
|
||||
|
||||
backup_files = []
|
||||
for db in databases:
|
||||
logger.info(f"正在备份数据库: {db}")
|
||||
backup_file = self.backup_mysql_database(db)
|
||||
if backup_file:
|
||||
backup_files.append(backup_file)
|
||||
|
||||
return backup_files
|
||||
|
||||
def clear_mysql_database(self, database_name):
|
||||
"""清空指定MySQL数据库的所有表"""
|
||||
try:
|
||||
@ -193,6 +277,24 @@ class DatabaseManager:
|
||||
for db in databases:
|
||||
self.clear_mysql_database(db)
|
||||
|
||||
def clear_selected_mysql_databases(self):
|
||||
"""清空选定的MySQL数据库"""
|
||||
databases = self.get_target_databases()
|
||||
if not databases:
|
||||
logger.warning("没有选择要清空的数据库")
|
||||
return
|
||||
|
||||
# 确认清空操作
|
||||
print(f"\n即将清空以下数据库: {', '.join(databases)}")
|
||||
confirm = input("确认要清空这些数据库吗?(y/N): ")
|
||||
if confirm.lower() != 'y':
|
||||
logger.info("用户取消清空操作")
|
||||
return
|
||||
|
||||
for db in databases:
|
||||
logger.info(f"正在清空数据库: {db}")
|
||||
self.clear_mysql_database(db)
|
||||
|
||||
def backup_redis_database(self):
|
||||
"""备份Redis数据库"""
|
||||
try:
|
||||
@ -351,54 +453,101 @@ class DatabaseManager:
|
||||
self.redis_conn.close()
|
||||
logger.info("Redis连接已关闭")
|
||||
|
||||
def select_operation_mode():
|
||||
"""选择操作模式"""
|
||||
print("\n请选择操作模式:")
|
||||
print("1. 仅备份数据库")
|
||||
print("2. 仅清空数据库")
|
||||
print("3. 备份后清空数据库")
|
||||
print("4. 备份和清空Redis")
|
||||
print("0. 退出")
|
||||
|
||||
while True:
|
||||
try:
|
||||
choice = input("\n请输入选择 (0-4): ").strip()
|
||||
if choice in ['0', '1', '2', '3', '4']:
|
||||
return choice
|
||||
else:
|
||||
print("无效选择,请输入 0-4")
|
||||
except KeyboardInterrupt:
|
||||
return '0'
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
logger.info("开始执行数据库备份和清空脚本")
|
||||
|
||||
db_manager = DatabaseManager()
|
||||
# 选择操作模式
|
||||
mode = select_operation_mode()
|
||||
if mode == '0':
|
||||
logger.info("用户选择退出")
|
||||
return True
|
||||
|
||||
# 从配置或用户交互获取目标数据库
|
||||
target_dbs = TARGET_DATABASES if TARGET_DATABASES else None
|
||||
db_manager = DatabaseManager(target_databases=target_dbs)
|
||||
|
||||
try:
|
||||
# 连接数据库
|
||||
mysql_connected = db_manager.connect_mysql()
|
||||
redis_connected = db_manager.connect_redis()
|
||||
redis_connected = db_manager.connect_redis() if mode == '4' else True
|
||||
|
||||
if not mysql_connected and not redis_connected:
|
||||
logger.error("无法连接到任何数据库,脚本退出")
|
||||
if mode in ['1', '2', '3'] and not mysql_connected:
|
||||
logger.error("无法连接到MySQL数据库,脚本退出")
|
||||
return False
|
||||
|
||||
# 1. 备份MySQL数据库
|
||||
if mysql_connected:
|
||||
if mode == '4' and not redis_connected:
|
||||
logger.error("无法连接到Redis数据库,脚本退出")
|
||||
return False
|
||||
|
||||
# 执行相应操作
|
||||
if mode == '1': # 仅备份
|
||||
logger.info("开始备份MySQL数据库...")
|
||||
backup_files = db_manager.backup_all_mysql_databases()
|
||||
backup_files = db_manager.backup_selected_mysql_databases()
|
||||
if backup_files:
|
||||
logger.info(f"MySQL备份完成,共备份 {len(backup_files)} 个数据库")
|
||||
else:
|
||||
logger.warning("MySQL备份失败或没有数据库需要备份")
|
||||
|
||||
# 2. 备份Redis数据库
|
||||
if redis_connected:
|
||||
elif mode == '2': # 仅清空
|
||||
logger.info("开始清空MySQL数据库...")
|
||||
db_manager.clear_selected_mysql_databases()
|
||||
logger.info("MySQL数据库清空完成")
|
||||
|
||||
elif mode == '3': # 备份后清空
|
||||
# 1. 备份MySQL数据库
|
||||
logger.info("开始备份MySQL数据库...")
|
||||
backup_files = db_manager.backup_selected_mysql_databases()
|
||||
if backup_files:
|
||||
logger.info(f"MySQL备份完成,共备份 {len(backup_files)} 个数据库")
|
||||
|
||||
# 确认是否继续清空数据库
|
||||
confirm = input("备份完成,是否继续清空数据库?(y/N): ")
|
||||
if confirm.lower() == 'y':
|
||||
logger.info("开始清空MySQL数据库...")
|
||||
# 重新使用相同的数据库选择
|
||||
db_manager.target_databases = [os.path.basename(f).split('_')[0] for f in backup_files]
|
||||
db_manager.clear_selected_mysql_databases()
|
||||
logger.info("MySQL数据库清空完成")
|
||||
else:
|
||||
logger.info("用户取消清空操作")
|
||||
else:
|
||||
logger.warning("MySQL备份失败,跳过清空操作")
|
||||
|
||||
elif mode == '4': # Redis操作
|
||||
# 备份Redis
|
||||
logger.info("开始备份Redis数据库...")
|
||||
redis_backup = db_manager.backup_redis_database()
|
||||
if redis_backup:
|
||||
logger.info("Redis备份完成")
|
||||
|
||||
# 确认是否继续清空数据库
|
||||
confirm = input("备份完成,是否继续清空数据库?(y/N): ")
|
||||
if confirm.lower() != 'y':
|
||||
logger.info("用户取消清空操作")
|
||||
return True
|
||||
|
||||
# 3. 清空MySQL数据库
|
||||
if mysql_connected:
|
||||
logger.info("开始清空MySQL数据库...")
|
||||
db_manager.clear_all_mysql_databases()
|
||||
logger.info("MySQL数据库清空完成")
|
||||
|
||||
# 4. 清空Redis数据库
|
||||
if redis_connected:
|
||||
logger.info("开始清空Redis数据库...")
|
||||
if db_manager.clear_redis_database():
|
||||
logger.info("Redis数据库清空完成")
|
||||
|
||||
# 确认是否清空Redis
|
||||
confirm = input("Redis备份完成,是否清空Redis数据库?(y/N): ")
|
||||
if confirm.lower() == 'y':
|
||||
logger.info("开始清空Redis数据库...")
|
||||
if db_manager.clear_redis_database():
|
||||
logger.info("Redis数据库清空完成")
|
||||
else:
|
||||
logger.info("用户取消Redis清空操作")
|
||||
|
||||
logger.info("所有操作完成")
|
||||
return True
|
||||
|
||||
BIN
script/Item.xlsx
Normal file
BIN
script/Item.xlsx
Normal file
Binary file not shown.
Binary file not shown.
BIN
script/OrderData.xlsx
Normal file
BIN
script/OrderData.xlsx
Normal file
Binary file not shown.
531
script/automate.py
Normal file
531
script/automate.py
Normal file
@ -0,0 +1,531 @@
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
import time
|
||||
import json
|
||||
import csv
|
||||
import os
|
||||
from urllib.parse import urljoin, urlparse
|
||||
import logging
|
||||
from playwright.sync_api import sync_playwright, TimeoutError as PlaywrightTimeoutError
|
||||
import asyncio
|
||||
|
||||
class WebScraper:
|
||||
def __init__(self, delay=1, timeout=30000, headless=True):
|
||||
"""
|
||||
初始化爬虫
|
||||
:param delay: 请求间隔时间(秒)
|
||||
:param timeout: 页面加载超时时间(毫秒)
|
||||
:param headless: 是否无头模式运行浏览器
|
||||
"""
|
||||
self.delay = delay
|
||||
self.timeout = timeout
|
||||
self.headless = headless
|
||||
self.playwright = None
|
||||
self.browser = None
|
||||
self.context = None
|
||||
|
||||
# 设置日志
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
||||
self.logger = logging.getLogger(__name__)
|
||||
|
||||
def start_browser(self):
|
||||
"""启动浏览器"""
|
||||
try:
|
||||
self.playwright = sync_playwright().start()
|
||||
self.browser = self.playwright.chromium.launch(
|
||||
headless=self.headless,
|
||||
args=[
|
||||
'--disable-blink-features=AutomationControlled',
|
||||
'--no-sandbox',
|
||||
'--disable-dev-shm-usage'
|
||||
]
|
||||
)
|
||||
self.context = self.browser.new_context(
|
||||
user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
|
||||
viewport={'width': 1920, 'height': 1080}
|
||||
)
|
||||
self.logger.info("浏览器启动成功")
|
||||
except Exception as e:
|
||||
self.logger.error(f"启动浏览器失败: {e}")
|
||||
raise
|
||||
|
||||
def stop_browser(self):
|
||||
"""关闭浏览器"""
|
||||
if self.context:
|
||||
self.context.close()
|
||||
if self.browser:
|
||||
self.browser.close()
|
||||
if self.playwright:
|
||||
self.playwright.stop()
|
||||
self.logger.info("浏览器已关闭")
|
||||
|
||||
def get_page_with_playwright(self, url, max_retries=3, wait_for_load=True):
|
||||
"""
|
||||
使用Playwright获取网页内容
|
||||
:param url: 目标URL
|
||||
:param max_retries: 最大重试次数
|
||||
:param wait_for_load: 是否等待页面完全加载
|
||||
:return: HTML内容或None
|
||||
"""
|
||||
if not self.context:
|
||||
self.start_browser()
|
||||
|
||||
for attempt in range(max_retries):
|
||||
page = None
|
||||
try:
|
||||
page = self.context.new_page()
|
||||
|
||||
# 设置额外的请求头
|
||||
page.set_extra_http_headers({
|
||||
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
|
||||
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
|
||||
'Accept-Encoding': 'gzip, deflate, br',
|
||||
'DNT': '1',
|
||||
'Connection': 'keep-alive',
|
||||
'Upgrade-Insecure-Requests': '1',
|
||||
})
|
||||
|
||||
# 访问页面
|
||||
response = page.goto(url, timeout=self.timeout, wait_until='domcontentloaded')
|
||||
|
||||
if response and response.status == 200:
|
||||
# 等待页面加载完成
|
||||
if wait_for_load:
|
||||
try:
|
||||
# 等待网络空闲
|
||||
|
||||
page.wait_for_load_state('networkidle', timeout=10000)
|
||||
# 额外等待JavaScript执行
|
||||
page.wait_for_timeout(2000)
|
||||
except PlaywrightTimeoutError:
|
||||
self.logger.warning(f"页面加载超时,但继续处理: {url}")
|
||||
|
||||
# 获取页面内容
|
||||
html_content = page.content()
|
||||
page.close()
|
||||
|
||||
self.logger.info(f"成功获取页面: {url}")
|
||||
time.sleep(self.delay)
|
||||
return html_content
|
||||
else:
|
||||
self.logger.warning(f"页面响应状态异常: {response.status if response else 'None'}")
|
||||
|
||||
except PlaywrightTimeoutError:
|
||||
self.logger.warning(f"页面加载超时 (尝试 {attempt + 1}/{max_retries}): {url}")
|
||||
except Exception as e:
|
||||
self.logger.warning(f"获取页面失败 (尝试 {attempt + 1}/{max_retries}): {e}")
|
||||
finally:
|
||||
if page:
|
||||
page.close()
|
||||
|
||||
if attempt < max_retries - 1:
|
||||
time.sleep(2 ** attempt) # 指数退避
|
||||
|
||||
self.logger.error(f"无法获取页面: {url}")
|
||||
return None
|
||||
|
||||
def get_page(self, url, max_retries=3):
|
||||
"""
|
||||
获取网页内容(兼容方法,使用Playwright)
|
||||
:param url: 目标URL
|
||||
:param max_retries: 最大重试次数
|
||||
:return: HTML内容或None
|
||||
"""
|
||||
return self.get_page_with_playwright(url, max_retries)
|
||||
|
||||
def parse_html(self, html_content, parser='html.parser'):
|
||||
"""
|
||||
解析HTML内容
|
||||
:param html_content: HTML字符串
|
||||
:param parser: 解析器类型
|
||||
:return: BeautifulSoup对象
|
||||
"""
|
||||
return BeautifulSoup(html_content, parser)
|
||||
|
||||
def extract_links(self, soup, base_url):
|
||||
"""
|
||||
提取页面中的所有链接
|
||||
:param soup: BeautifulSoup对象
|
||||
:param base_url: 基础URL
|
||||
:return: 链接列表
|
||||
"""
|
||||
links = []
|
||||
for link in soup.find_all('a', href=True):
|
||||
full_url = urljoin(base_url, link['href'])
|
||||
links.append({
|
||||
'url': full_url,
|
||||
'text': link.get_text(strip=True),
|
||||
'title': link.get('title', '')
|
||||
})
|
||||
return links
|
||||
|
||||
def extract_images(self, soup, base_url):
|
||||
"""
|
||||
提取页面中的所有图片
|
||||
:param soup: BeautifulSoup对象
|
||||
:param base_url: 基础URL
|
||||
:return: 图片信息列表
|
||||
"""
|
||||
images = []
|
||||
for img in soup.find_all('img'):
|
||||
src = img.get('src')
|
||||
if src:
|
||||
full_url = urljoin(base_url, src)
|
||||
images.append({
|
||||
'url': full_url,
|
||||
'alt': img.get('alt', ''),
|
||||
'title': img.get('title', '')
|
||||
})
|
||||
return images
|
||||
|
||||
def save_to_json(self, data, filename):
|
||||
"""
|
||||
保存数据为JSON格式
|
||||
:param data: 要保存的数据
|
||||
:param filename: 文件名
|
||||
"""
|
||||
os.makedirs(os.path.dirname(filename), exist_ok=True)
|
||||
with open(filename, 'w', encoding='utf-8') as f:
|
||||
json.dump(data, f, ensure_ascii=False, indent=2)
|
||||
self.logger.info(f"数据已保存到: {filename}")
|
||||
|
||||
def save_to_csv(self, data, filename, fieldnames):
|
||||
"""
|
||||
保存数据为CSV格式
|
||||
:param data: 要保存的数据列表
|
||||
:param filename: 文件名
|
||||
:param fieldnames: CSV字段名
|
||||
"""
|
||||
os.makedirs(os.path.dirname(filename), exist_ok=True)
|
||||
with open(filename, 'w', newline='', encoding='utf-8') as f:
|
||||
writer = csv.DictWriter(f, fieldnames=fieldnames)
|
||||
writer.writeheader()
|
||||
writer.writerows(data)
|
||||
self.logger.info(f"数据已保存到: {filename}")
|
||||
|
||||
def save_to_html(self, html_content, filename):
|
||||
"""
|
||||
保存HTML内容到文件
|
||||
:param html_content: HTML内容
|
||||
:param filename: 文件名
|
||||
"""
|
||||
os.makedirs(os.path.dirname(filename), exist_ok=True)
|
||||
with open(filename, 'w', encoding='utf-8') as f:
|
||||
f.write(html_content)
|
||||
self.logger.info(f"HTML已保存到: {filename}")
|
||||
|
||||
def scrape_page(self, url):
|
||||
"""
|
||||
爬取单个页面的完整信息
|
||||
:param url: 目标URL
|
||||
:return: 页面数据字典
|
||||
"""
|
||||
html_content = self.get_page_with_playwright(url)
|
||||
if not html_content:
|
||||
return None
|
||||
|
||||
# 保存原始HTML内容
|
||||
soup = self.parse_html(html_content)
|
||||
|
||||
# 提取基本信息
|
||||
title = soup.find('title')
|
||||
title_text = title.get_text(strip=True) if title else ''
|
||||
|
||||
# 提取meta信息
|
||||
meta_description = soup.find('meta', attrs={'name': 'description'})
|
||||
description = meta_description.get('content', '') if meta_description else ''
|
||||
|
||||
# 提取链接和图片
|
||||
links = self.extract_links(soup, url)
|
||||
images = self.extract_images(soup, url)
|
||||
|
||||
# 提取文本内容
|
||||
text_content = soup.get_text(strip=True)
|
||||
|
||||
# 提取JavaScript变量(特别针对飞书等SPA应用)
|
||||
script_data = self.extract_script_data(soup)
|
||||
|
||||
return {
|
||||
'url': url,
|
||||
'title': title_text,
|
||||
'description': description,
|
||||
'links': links,
|
||||
'images': images,
|
||||
'text_length': len(text_content),
|
||||
'html_content': html_content,
|
||||
'html_length': len(html_content),
|
||||
'script_data': script_data,
|
||||
'timestamp': time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
}
|
||||
|
||||
def extract_script_data(self, soup):
|
||||
"""
|
||||
提取页面中的JavaScript数据
|
||||
:param soup: BeautifulSoup对象
|
||||
:return: 提取的数据字典
|
||||
"""
|
||||
script_data = {}
|
||||
|
||||
# 查找包含JSON数据的script标签
|
||||
for script in soup.find_all('script'):
|
||||
script_text = script.get_text()
|
||||
|
||||
# 查找常见的数据模式
|
||||
patterns = [
|
||||
'window.__pageStartTime',
|
||||
'window.serverInjectRes',
|
||||
'window.ENV',
|
||||
'window.locales',
|
||||
'window.deviceInfoBySSO'
|
||||
]
|
||||
|
||||
for pattern in patterns:
|
||||
if pattern in script_text:
|
||||
try:
|
||||
# 提取变量赋值
|
||||
lines = script_text.split('\n')
|
||||
for line in lines:
|
||||
if pattern in line and '=' in line:
|
||||
script_data[pattern] = line.strip()
|
||||
except Exception as e:
|
||||
self.logger.warning(f"提取脚本数据失败: {e}")
|
||||
|
||||
return script_data
|
||||
|
||||
def create_safe_filename(self, url, max_length=100):
|
||||
"""
|
||||
创建安全的文件名
|
||||
:param url: 原始URL
|
||||
:param max_length: 最大文件名长度
|
||||
:return: 安全的文件名
|
||||
"""
|
||||
# 移除协议
|
||||
safe_name = url.replace('https://', '').replace('http://', '')
|
||||
|
||||
# 替换或移除无效字符
|
||||
invalid_chars = ['<', '>', ':', '"', '|', '?', '*', '/', '\\', '&', '=', '#']
|
||||
for char in invalid_chars:
|
||||
safe_name = safe_name.replace(char, '_')
|
||||
|
||||
# 移除连续的下划线
|
||||
while '__' in safe_name:
|
||||
safe_name = safe_name.replace('__', '_')
|
||||
|
||||
# 移除开头和结尾的下划线
|
||||
safe_name = safe_name.strip('_')
|
||||
|
||||
# 限制长度
|
||||
if len(safe_name) > max_length:
|
||||
safe_name = safe_name[:max_length]
|
||||
|
||||
# 确保文件名不为空
|
||||
if not safe_name:
|
||||
safe_name = 'scraped_page'
|
||||
|
||||
return safe_name
|
||||
|
||||
def manual_login_and_scrape(self, login_url, target_urls):
|
||||
"""
|
||||
手动登录并爬取页面
|
||||
:param login_url: 登录页面URL
|
||||
:param target_urls: 需要爬取的目标URL列表
|
||||
:return: 爬取结果列表
|
||||
"""
|
||||
if not self.context:
|
||||
self.start_browser()
|
||||
|
||||
page = self.context.new_page()
|
||||
|
||||
try:
|
||||
# 打开登录页面
|
||||
self.logger.info(f"正在打开登录页面: {login_url}")
|
||||
page.goto(login_url, timeout=self.timeout)
|
||||
|
||||
# 等待用户手动登录
|
||||
print("=" * 60)
|
||||
print("浏览器已打开,请在浏览器中完成登录操作")
|
||||
print("登录完成后,请在此控制台按回车键继续...")
|
||||
print("=" * 60)
|
||||
input()
|
||||
|
||||
# 确认登录状态
|
||||
current_url = page.url
|
||||
self.logger.info(f"当前页面URL: {current_url}")
|
||||
|
||||
# 获取cookies用于后续请求
|
||||
cookies = self.context.cookies()
|
||||
self.logger.info(f"获取到 {len(cookies)} 个cookies")
|
||||
|
||||
# 开始爬取目标页面
|
||||
results = []
|
||||
for url in target_urls:
|
||||
print(f"正在爬取: {url}")
|
||||
data = self.scrape_page_with_session(page, url)
|
||||
if data:
|
||||
results.append(data)
|
||||
|
||||
return results
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"手动登录过程中发生错误: {e}")
|
||||
return []
|
||||
finally:
|
||||
if page:
|
||||
page.close()
|
||||
|
||||
def scrape_page_with_session(self, page, url):
|
||||
"""
|
||||
使用已有session爬取页面
|
||||
:param page: Playwright页面对象
|
||||
:param url: 目标URL
|
||||
:return: 页面数据字典
|
||||
"""
|
||||
try:
|
||||
# 导航到目标页面
|
||||
response = page.goto(url, timeout=self.timeout, wait_until='domcontentloaded')
|
||||
|
||||
if response and response.status == 200:
|
||||
# 等待页面加载完成
|
||||
try:
|
||||
page.wait_for_load_state('networkidle', timeout=15000)
|
||||
page.wait_for_timeout(3000) # 额外等待时间确保内容加载
|
||||
except PlaywrightTimeoutError:
|
||||
self.logger.warning(f"页面加载超时,但继续处理: {url}")
|
||||
|
||||
# 获取页面内容
|
||||
html_content = page.content()
|
||||
|
||||
# 解析页面内容
|
||||
soup = self.parse_html(html_content)
|
||||
|
||||
# 提取基本信息
|
||||
title = soup.find('title')
|
||||
title_text = title.get_text(strip=True) if title else ''
|
||||
|
||||
# 提取meta信息
|
||||
meta_description = soup.find('meta', attrs={'name': 'description'})
|
||||
description = meta_description.get('content', '') if meta_description else ''
|
||||
|
||||
# 提取链接和图片
|
||||
links = self.extract_links(soup, url)
|
||||
images = self.extract_images(soup, url)
|
||||
|
||||
# 提取文本内容
|
||||
text_content = soup.get_text(strip=True)
|
||||
|
||||
# 提取JavaScript变量
|
||||
script_data = self.extract_script_data(soup)
|
||||
|
||||
self.logger.info(f"成功获取页面: {url}")
|
||||
time.sleep(self.delay)
|
||||
|
||||
return {
|
||||
'url': url,
|
||||
'title': title_text,
|
||||
'description': description,
|
||||
'links': links,
|
||||
'images': images,
|
||||
'text_length': len(text_content),
|
||||
'html_content': html_content,
|
||||
'html_length': len(html_content),
|
||||
'script_data': script_data,
|
||||
'timestamp': time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
}
|
||||
else:
|
||||
self.logger.warning(f"页面响应状态异常: {response.status if response else 'None'}")
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"爬取页面失败: {e}")
|
||||
return None
|
||||
|
||||
def wait_for_manual_action(self, page, message="请完成操作后按回车继续..."):
|
||||
"""
|
||||
等待用户手动操作
|
||||
:param page: Playwright页面对象
|
||||
:param message: 提示信息
|
||||
"""
|
||||
print("=" * 60)
|
||||
print(f"当前页面: {page.url}")
|
||||
print(message)
|
||||
print("=" * 60)
|
||||
input()
|
||||
|
||||
def main():
|
||||
"""
|
||||
示例使用方法 - 手动登录模式
|
||||
"""
|
||||
# 创建爬虫实例(非无头模式,便于手动登录)
|
||||
scraper = WebScraper(delay=2, timeout=30000, headless=False)
|
||||
|
||||
try:
|
||||
# 启动浏览器
|
||||
scraper.start_browser()
|
||||
|
||||
# 定义输出目录
|
||||
output_dir = 'd:/Github/devops/output'
|
||||
|
||||
# 登录页面和目标页面
|
||||
login_url = 'https://yixj5m42od.feishu.cn/sheets/VlAIsKxYchNABztr3RGcBnrEnYM?table=tblNs3625a9MAc89&view=vewkRuPWCL&sheet=y1FRE9'
|
||||
target_urls = [
|
||||
'https://yixj5m42od.feishu.cn/sheets/VlAIsKxYchNABztr3RGcBnrEnYM?table=tblNs3625a9MAc89&view=vewkRuPWCL&sheet=y1FRE9',
|
||||
# 可以添加更多需要爬取的页面
|
||||
]
|
||||
|
||||
# 手动登录并爬取
|
||||
print("开始手动登录流程...")
|
||||
results = scraper.manual_login_and_scrape(login_url, target_urls)
|
||||
|
||||
# 保存结果
|
||||
if results:
|
||||
# 保存HTML文件
|
||||
for result in results:
|
||||
safe_filename = scraper.create_safe_filename(result['url'])
|
||||
html_filename = f'{output_dir}/html/{safe_filename}_logged_in.html'
|
||||
scraper.save_to_html(result['html_content'], html_filename)
|
||||
|
||||
# 保存完整数据(包含HTML)到JSON
|
||||
scraper.save_to_json(results, f'{output_dir}/scrape_results_full_logged_in.json')
|
||||
|
||||
# 保存不含HTML的精简版本到JSON
|
||||
simplified_results = []
|
||||
for result in results:
|
||||
simplified_result = result.copy()
|
||||
simplified_result.pop('html_content', None)
|
||||
simplified_results.append(simplified_result)
|
||||
|
||||
scraper.save_to_json(simplified_results, f'{output_dir}/scrape_results_logged_in.json')
|
||||
|
||||
# 保存CSV
|
||||
csv_data = []
|
||||
for result in results:
|
||||
csv_data.append({
|
||||
'url': result['url'],
|
||||
'title': result['title'],
|
||||
'description': result['description'],
|
||||
'links_count': len(result['links']),
|
||||
'images_count': len(result['images']),
|
||||
'html_length': result['html_length'],
|
||||
'timestamp': result['timestamp']
|
||||
})
|
||||
|
||||
fieldnames = ['url', 'title', 'description', 'links_count', 'images_count', 'html_length', 'timestamp']
|
||||
scraper.save_to_csv(csv_data, f'{output_dir}/scrape_results_logged_in.csv', fieldnames)
|
||||
|
||||
print(f"爬取完成,共处理 {len(results)} 个页面")
|
||||
print(f"HTML文件保存在: {output_dir}/html/")
|
||||
print(f"完整数据保存在: {output_dir}/scrape_results_full_logged_in.json")
|
||||
else:
|
||||
print("未获取到任何数据")
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\n用户中断操作")
|
||||
except Exception as e:
|
||||
print(f"发生错误: {e}")
|
||||
finally:
|
||||
# 确保浏览器被关闭
|
||||
print("正在关闭浏览器...")
|
||||
scraper.stop_browser()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
582
script/backup.py
Normal file
582
script/backup.py
Normal file
@ -0,0 +1,582 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
数据库备份和清空脚本
|
||||
功能:
|
||||
1. 备份MySQL数据库(支持指定特定数据库)
|
||||
2. 清空MySQL数据库(支持指定特定数据库)
|
||||
3. 清空Redis数据库
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import datetime
|
||||
import logging
|
||||
import redis
|
||||
import pymysql
|
||||
from pathlib import Path
|
||||
|
||||
# 配置日志
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(levelname)s - %(message)s',
|
||||
handlers=[
|
||||
logging.FileHandler('script.log'),
|
||||
logging.StreamHandler()
|
||||
]
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# 数据库配置
|
||||
MYSQL_CONFIG = {
|
||||
'host': '127.0.0.1',
|
||||
'port': 3306,
|
||||
'user': 'root',
|
||||
'password': 'Xijing1!',
|
||||
'charset': 'utf8mb4'
|
||||
}
|
||||
|
||||
REDIS_CONFIG = {
|
||||
'host': '127.0.0.1',
|
||||
'port': 6379,
|
||||
'password': None, # 如果有密码请设置
|
||||
'db': 0
|
||||
}
|
||||
|
||||
# 备份目录
|
||||
BACKUP_DIR = './backups'
|
||||
|
||||
# 指定要操作的数据库列表(为空表示操作所有用户数据库)
|
||||
TARGET_DATABASES = ["merge_pet_1"] # 例如: ['database1', 'database2']
|
||||
|
||||
class DatabaseManager:
|
||||
def __init__(self, target_databases=None):
|
||||
self.mysql_conn = None
|
||||
self.redis_conn = None
|
||||
self.backup_dir = Path(BACKUP_DIR)
|
||||
self.backup_dir.mkdir(exist_ok=True)
|
||||
self.target_databases = target_databases or []
|
||||
|
||||
def connect_mysql(self):
|
||||
"""连接MySQL数据库"""
|
||||
try:
|
||||
self.mysql_conn = pymysql.connect(**MYSQL_CONFIG)
|
||||
logger.info("MySQL连接成功")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"MySQL连接失败: {e}")
|
||||
return False
|
||||
|
||||
def connect_redis(self):
|
||||
"""连接Redis数据库"""
|
||||
try:
|
||||
self.redis_conn = redis.Redis(**REDIS_CONFIG)
|
||||
self.redis_conn.ping()
|
||||
logger.info("Redis连接成功")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Redis连接失败: {e}")
|
||||
return False
|
||||
|
||||
def get_mysql_databases(self):
|
||||
"""获取所有MySQL数据库列表(排除系统数据库)"""
|
||||
try:
|
||||
cursor = self.mysql_conn.cursor()
|
||||
cursor.execute("SHOW DATABASES")
|
||||
databases = [db[0] for db in cursor.fetchall()]
|
||||
# 排除系统数据库
|
||||
system_dbs = ['information_schema', 'performance_schema', 'mysql', 'sys']
|
||||
user_dbs = [db for db in databases if db not in system_dbs]
|
||||
cursor.close()
|
||||
return user_dbs
|
||||
except Exception as e:
|
||||
logger.error(f"获取数据库列表失败: {e}")
|
||||
return []
|
||||
|
||||
def backup_mysql_database(self, database_name):
|
||||
"""备份指定的MySQL数据库"""
|
||||
try:
|
||||
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
backup_file = self.backup_dir / f"{database_name}_{timestamp}.sql"
|
||||
|
||||
# 确保备份目录存在
|
||||
backup_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# 使用mysqldump命令备份
|
||||
cmd = [
|
||||
'mysqldump',
|
||||
f'--host={MYSQL_CONFIG["host"]}',
|
||||
f'--port={MYSQL_CONFIG["port"]}',
|
||||
f'--user={MYSQL_CONFIG["user"]}',
|
||||
f'--password={MYSQL_CONFIG["password"]}',
|
||||
'--single-transaction',
|
||||
'--routines',
|
||||
'--triggers',
|
||||
database_name
|
||||
]
|
||||
|
||||
# 创建备份文件(如果不存在会自动创建)
|
||||
logger.info(f"准备备份数据库 {database_name} 到文件: {backup_file}")
|
||||
with open(backup_file, 'w', encoding='utf-8') as f:
|
||||
result = subprocess.run(cmd, stdout=f, stderr=subprocess.PIPE)
|
||||
|
||||
if result.returncode == 0:
|
||||
# 检查备份文件是否创建成功并且有内容
|
||||
if backup_file.exists() and backup_file.stat().st_size > 0:
|
||||
logger.info(f"数据库 {database_name} 备份成功: {backup_file} (大小: {backup_file.stat().st_size} 字节)")
|
||||
return str(backup_file)
|
||||
else:
|
||||
logger.error(f"数据库 {database_name} 备份文件创建失败或为空")
|
||||
return None
|
||||
else:
|
||||
logger.error(f"数据库 {database_name} 备份失败: {result.stderr}")
|
||||
# 如果备份失败,删除可能创建的空文件
|
||||
if backup_file.exists():
|
||||
backup_file.unlink()
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"备份数据库 {database_name} 时发生错误: {e}")
|
||||
return None
|
||||
|
||||
def backup_all_mysql_databases(self):
|
||||
"""备份所有用户数据库"""
|
||||
databases = self.get_mysql_databases()
|
||||
if not databases:
|
||||
logger.warning("没有找到用户数据库")
|
||||
return []
|
||||
|
||||
backup_files = []
|
||||
for db in databases:
|
||||
backup_file = self.backup_mysql_database(db)
|
||||
if backup_file:
|
||||
backup_files.append(backup_file)
|
||||
|
||||
return backup_files
|
||||
|
||||
def get_target_databases(self):
|
||||
"""获取要操作的数据库列表"""
|
||||
all_databases = self.get_mysql_databases()
|
||||
if not all_databases:
|
||||
logger.warning("没有找到用户数据库")
|
||||
return []
|
||||
|
||||
if self.target_databases:
|
||||
# 验证指定的数据库是否存在
|
||||
valid_databases = []
|
||||
for db in self.target_databases:
|
||||
if db in all_databases:
|
||||
valid_databases.append(db)
|
||||
else:
|
||||
logger.warning(f"指定的数据库 '{db}' 不存在")
|
||||
return valid_databases
|
||||
else:
|
||||
# 如果没有指定,让用户选择
|
||||
return self.select_databases_interactively(all_databases)
|
||||
|
||||
def select_databases_interactively(self, all_databases):
|
||||
"""交互式选择数据库"""
|
||||
print("\n可用的数据库列表:")
|
||||
for i, db in enumerate(all_databases, 1):
|
||||
print(f"{i}. {db}")
|
||||
|
||||
print(f"{len(all_databases) + 1}. 所有数据库")
|
||||
print("0. 退出")
|
||||
|
||||
while True:
|
||||
try:
|
||||
choice = input("\n请选择要操作的数据库(输入数字,多个数字用逗号分隔): ").strip()
|
||||
|
||||
if choice == '0':
|
||||
logger.info("用户选择退出")
|
||||
return []
|
||||
|
||||
if choice == str(len(all_databases) + 1):
|
||||
logger.info("用户选择操作所有数据库")
|
||||
return all_databases
|
||||
|
||||
# 解析用户输入的数字
|
||||
selected_indices = [int(x.strip()) for x in choice.split(',') if x.strip()]
|
||||
selected_databases = []
|
||||
|
||||
for index in selected_indices:
|
||||
if 1 <= index <= len(all_databases):
|
||||
selected_databases.append(all_databases[index - 1])
|
||||
else:
|
||||
print(f"无效的选择: {index}")
|
||||
continue
|
||||
|
||||
if selected_databases:
|
||||
logger.info(f"用户选择的数据库: {', '.join(selected_databases)}")
|
||||
return selected_databases
|
||||
else:
|
||||
print("没有有效的选择,请重新输入")
|
||||
|
||||
except ValueError:
|
||||
print("输入格式错误,请输入数字")
|
||||
except KeyboardInterrupt:
|
||||
logger.info("用户中断操作")
|
||||
return []
|
||||
|
||||
def backup_selected_mysql_databases(self):
|
||||
"""备份选定的MySQL数据库"""
|
||||
databases = self.get_target_databases()
|
||||
if not databases:
|
||||
logger.warning("没有选择要备份的数据库")
|
||||
return []
|
||||
|
||||
backup_files = []
|
||||
for db in databases:
|
||||
logger.info(f"正在备份数据库: {db}")
|
||||
backup_file = self.backup_mysql_database(db)
|
||||
if backup_file:
|
||||
backup_files.append(backup_file)
|
||||
|
||||
return backup_files
|
||||
|
||||
def clear_mysql_database(self, database_name):
|
||||
"""清空指定MySQL数据库的所有表"""
|
||||
try:
|
||||
cursor = self.mysql_conn.cursor()
|
||||
|
||||
# 使用数据库
|
||||
cursor.execute(f"USE `{database_name}`")
|
||||
|
||||
# 禁用外键检查
|
||||
cursor.execute("SET FOREIGN_KEY_CHECKS = 0")
|
||||
|
||||
# 获取所有表
|
||||
cursor.execute("SHOW TABLES")
|
||||
tables = [table[0] for table in cursor.fetchall()]
|
||||
|
||||
# 清空所有表
|
||||
for table in tables:
|
||||
cursor.execute(f"TRUNCATE TABLE `{table}`")
|
||||
logger.info(f"已清空表: {database_name}.{table}")
|
||||
|
||||
# 重新启用外键检查
|
||||
cursor.execute("SET FOREIGN_KEY_CHECKS = 1")
|
||||
|
||||
self.mysql_conn.commit()
|
||||
cursor.close()
|
||||
logger.info(f"数据库 {database_name} 所有表已清空")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"清空数据库 {database_name} 失败: {e}")
|
||||
return False
|
||||
|
||||
def clear_all_mysql_databases(self):
|
||||
"""清空所有用户数据库"""
|
||||
databases = self.get_mysql_databases()
|
||||
if not databases:
|
||||
logger.warning("没有找到用户数据库")
|
||||
return
|
||||
|
||||
for db in databases:
|
||||
self.clear_mysql_database(db)
|
||||
|
||||
def clear_selected_mysql_databases(self):
|
||||
"""清空选定的MySQL数据库"""
|
||||
databases = self.get_target_databases()
|
||||
if not databases:
|
||||
logger.warning("没有选择要清空的数据库")
|
||||
return
|
||||
|
||||
# 确认清空操作
|
||||
print(f"\n即将清空以下数据库: {', '.join(databases)}")
|
||||
confirm = input("确认要清空这些数据库吗?(y/N): ")
|
||||
if confirm.lower() != 'y':
|
||||
logger.info("用户取消清空操作")
|
||||
return
|
||||
|
||||
for db in databases:
|
||||
logger.info(f"正在清空数据库: {db}")
|
||||
self.clear_mysql_database(db)
|
||||
|
||||
def backup_redis_database(self):
|
||||
"""备份Redis数据库"""
|
||||
try:
|
||||
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
backup_file = self.backup_dir / f"redis_{timestamp}.rdb"
|
||||
|
||||
# 确保备份目录存在
|
||||
backup_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# 执行BGSAVE命令
|
||||
self.redis_conn.bgsave()
|
||||
logger.info("Redis后台保存已启动")
|
||||
|
||||
# 等待保存完成
|
||||
import time
|
||||
initial_lastsave = self.redis_conn.lastsave()
|
||||
logger.info("等待Redis数据保存完成...")
|
||||
|
||||
# 等待BGSAVE完成,最多等待30秒
|
||||
timeout = 30
|
||||
start_time = time.time()
|
||||
while time.time() - start_time < timeout:
|
||||
current_lastsave = self.redis_conn.lastsave()
|
||||
if current_lastsave > initial_lastsave:
|
||||
logger.info("Redis数据保存完成")
|
||||
break
|
||||
time.sleep(1)
|
||||
else:
|
||||
logger.warning("Redis保存超时,但继续尝试备份")
|
||||
|
||||
# 尝试获取Redis RDB文件路径
|
||||
try:
|
||||
config_info = self.redis_conn.config_get('dir')
|
||||
redis_dir = config_info.get('dir', './') if config_info else './'
|
||||
dbfilename_info = self.redis_conn.config_get('dbfilename')
|
||||
dbfilename = dbfilename_info.get('dbfilename', 'dump.rdb') if dbfilename_info else 'dump.rdb'
|
||||
redis_rdb_path = os.path.join(redis_dir, dbfilename)
|
||||
logger.info(f"Redis RDB文件路径: {redis_rdb_path}")
|
||||
except:
|
||||
# 如果无法获取配置,使用默认路径
|
||||
redis_rdb_path = "./dump.rdb"
|
||||
logger.warning(f"无法获取Redis配置,使用默认路径: {redis_rdb_path}")
|
||||
|
||||
# 复制RDB文件
|
||||
if os.path.exists(redis_rdb_path):
|
||||
import shutil
|
||||
# 确保目标文件目录存在
|
||||
backup_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
shutil.copy2(redis_rdb_path, backup_file)
|
||||
if backup_file.exists() and backup_file.stat().st_size > 0:
|
||||
logger.info(f"Redis数据备份成功: {backup_file} (大小: {backup_file.stat().st_size} 字节)")
|
||||
return str(backup_file)
|
||||
else:
|
||||
logger.error("Redis备份文件创建失败或为空")
|
||||
return None
|
||||
else:
|
||||
logger.warning(f"找不到Redis RDB文件: {redis_rdb_path}")
|
||||
# 尝试创建一个简单的Redis数据导出
|
||||
return self._create_redis_text_backup(backup_file)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"备份Redis数据失败: {e}")
|
||||
return None
|
||||
|
||||
def _create_redis_text_backup(self, backup_file):
|
||||
"""创建Redis文本格式备份"""
|
||||
try:
|
||||
text_backup_file = backup_file.with_suffix('.txt')
|
||||
# 确保目录存在
|
||||
text_backup_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
logger.info(f"创建Redis文本格式备份: {text_backup_file}")
|
||||
with open(text_backup_file, 'w', encoding='utf-8') as f:
|
||||
f.write("# Redis数据导出\n")
|
||||
f.write(f"# 导出时间: {datetime.datetime.now()}\n\n")
|
||||
|
||||
# 获取所有key
|
||||
keys = self.redis_conn.keys('*')
|
||||
total_keys = len(keys)
|
||||
|
||||
if total_keys == 0:
|
||||
f.write("# Redis数据库为空\n")
|
||||
logger.info("Redis数据库为空,创建空备份文件")
|
||||
else:
|
||||
f.write(f"# 总共 {total_keys} 个键\n\n")
|
||||
logger.info(f"正在导出 {total_keys} 个Redis键...")
|
||||
|
||||
for i, key in enumerate(keys, 1):
|
||||
try:
|
||||
key_str = key.decode('utf-8') if isinstance(key, bytes) else str(key)
|
||||
key_type = self.redis_conn.type(key).decode('utf-8')
|
||||
|
||||
f.write(f"# Key {i}/{total_keys}: {key_str} (类型: {key_type})\n")
|
||||
|
||||
if key_type == 'string':
|
||||
value = self.redis_conn.get(key)
|
||||
if isinstance(value, bytes):
|
||||
try:
|
||||
value = value.decode('utf-8')
|
||||
except:
|
||||
value = str(value)
|
||||
f.write(f"SET \"{key_str}\" \"{value}\"\n")
|
||||
elif key_type == 'hash':
|
||||
hash_data = self.redis_conn.hgetall(key)
|
||||
for field, value in hash_data.items():
|
||||
if isinstance(field, bytes):
|
||||
field = field.decode('utf-8')
|
||||
if isinstance(value, bytes):
|
||||
value = value.decode('utf-8')
|
||||
f.write(f"HSET \"{key_str}\" \"{field}\" \"{value}\"\n")
|
||||
|
||||
f.write("\n")
|
||||
|
||||
except Exception as key_error:
|
||||
f.write(f"# 错误处理键 {key}: {key_error}\n\n")
|
||||
continue
|
||||
|
||||
if text_backup_file.exists():
|
||||
logger.info(f"Redis文本备份创建成功: {text_backup_file}")
|
||||
return str(text_backup_file)
|
||||
else:
|
||||
logger.error("Redis文本备份文件创建失败")
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"创建Redis文本备份失败: {e}")
|
||||
return None
|
||||
|
||||
def clear_redis_database(self):
|
||||
"""清空Redis数据库"""
|
||||
try:
|
||||
# 获取当前数据库的key数量
|
||||
key_count = self.redis_conn.dbsize()
|
||||
logger.info(f"Redis数据库当前有 {key_count} 个key")
|
||||
|
||||
if key_count > 0:
|
||||
# 清空当前数据库
|
||||
self.redis_conn.flushdb()
|
||||
logger.info("Redis数据库已清空")
|
||||
else:
|
||||
logger.info("Redis数据库已经是空的")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"清空Redis数据库失败: {e}")
|
||||
return False
|
||||
|
||||
def close_connections(self):
|
||||
"""关闭数据库连接"""
|
||||
if self.mysql_conn:
|
||||
self.mysql_conn.close()
|
||||
logger.info("MySQL连接已关闭")
|
||||
|
||||
if self.redis_conn:
|
||||
self.redis_conn.close()
|
||||
logger.info("Redis连接已关闭")
|
||||
|
||||
def select_operation_mode():
|
||||
"""选择操作模式"""
|
||||
print("\n请选择操作模式:")
|
||||
print("1. 仅备份数据库")
|
||||
print("2. 仅清空数据库")
|
||||
print("3. 备份后清空数据库")
|
||||
print("4. 备份和清空Redis")
|
||||
print("0. 退出")
|
||||
|
||||
while True:
|
||||
try:
|
||||
choice = input("\n请输入选择 (0-4): ").strip()
|
||||
if choice in ['0', '1', '2', '3', '4']:
|
||||
return choice
|
||||
else:
|
||||
print("无效选择,请输入 0-4")
|
||||
except KeyboardInterrupt:
|
||||
return '0'
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
logger.info("开始执行数据库备份和清空脚本")
|
||||
|
||||
# 选择操作模式
|
||||
mode = select_operation_mode()
|
||||
if mode == '0':
|
||||
logger.info("用户选择退出")
|
||||
return True
|
||||
|
||||
# 从配置或用户交互获取目标数据库
|
||||
target_dbs = TARGET_DATABASES if TARGET_DATABASES else None
|
||||
db_manager = DatabaseManager(target_databases=target_dbs)
|
||||
|
||||
try:
|
||||
# 连接数据库
|
||||
mysql_connected = db_manager.connect_mysql()
|
||||
redis_connected = db_manager.connect_redis() if mode == '4' else True
|
||||
|
||||
if mode in ['1', '2', '3'] and not mysql_connected:
|
||||
logger.error("无法连接到MySQL数据库,脚本退出")
|
||||
return False
|
||||
|
||||
if mode == '4' and not redis_connected:
|
||||
logger.error("无法连接到Redis数据库,脚本退出")
|
||||
return False
|
||||
|
||||
# 执行相应操作
|
||||
if mode == '1': # 仅备份
|
||||
logger.info("开始备份MySQL数据库...")
|
||||
backup_files = db_manager.backup_selected_mysql_databases()
|
||||
if backup_files:
|
||||
logger.info(f"MySQL备份完成,共备份 {len(backup_files)} 个数据库")
|
||||
else:
|
||||
logger.warning("MySQL备份失败或没有数据库需要备份")
|
||||
|
||||
elif mode == '2': # 仅清空
|
||||
logger.info("开始清空MySQL数据库...")
|
||||
db_manager.clear_selected_mysql_databases()
|
||||
logger.info("MySQL数据库清空完成")
|
||||
|
||||
elif mode == '3': # 备份后清空
|
||||
# 1. 备份MySQL数据库
|
||||
logger.info("开始备份MySQL数据库...")
|
||||
backup_files = db_manager.backup_selected_mysql_databases()
|
||||
if backup_files:
|
||||
logger.info(f"MySQL备份完成,共备份 {len(backup_files)} 个数据库")
|
||||
|
||||
# 确认是否继续清空数据库
|
||||
confirm = input("备份完成,是否继续清空数据库?(y/N): ")
|
||||
if confirm.lower() == 'y':
|
||||
logger.info("开始清空MySQL数据库...")
|
||||
# 重新使用相同的数据库选择
|
||||
db_manager.target_databases = [os.path.basename(f).split('_')[0] for f in backup_files]
|
||||
db_manager.clear_selected_mysql_databases()
|
||||
logger.info("MySQL数据库清空完成")
|
||||
else:
|
||||
logger.info("用户取消清空操作")
|
||||
else:
|
||||
logger.warning("MySQL备份失败,跳过清空操作")
|
||||
|
||||
elif mode == '4': # Redis操作
|
||||
# 备份Redis
|
||||
logger.info("开始备份Redis数据库...")
|
||||
redis_backup = db_manager.backup_redis_database()
|
||||
if redis_backup:
|
||||
logger.info("Redis备份完成")
|
||||
|
||||
# 确认是否清空Redis
|
||||
confirm = input("Redis备份完成,是否清空Redis数据库?(y/N): ")
|
||||
if confirm.lower() == 'y':
|
||||
logger.info("开始清空Redis数据库...")
|
||||
if db_manager.clear_redis_database():
|
||||
logger.info("Redis数据库清空完成")
|
||||
else:
|
||||
logger.info("用户取消Redis清空操作")
|
||||
|
||||
logger.info("所有操作完成")
|
||||
return True
|
||||
|
||||
except KeyboardInterrupt:
|
||||
logger.info("用户中断了脚本执行")
|
||||
return False
|
||||
except Exception as e:
|
||||
logger.error(f"脚本执行过程中发生错误: {e}")
|
||||
return False
|
||||
finally:
|
||||
db_manager.close_connections()
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 检查依赖包
|
||||
required_packages = ['pymysql', 'redis']
|
||||
missing_packages = []
|
||||
|
||||
for package in required_packages:
|
||||
try:
|
||||
__import__(package)
|
||||
except ImportError:
|
||||
missing_packages.append(package)
|
||||
|
||||
if missing_packages:
|
||||
print(f"缺少依赖包: {', '.join(missing_packages)}")
|
||||
print(f"请运行: pip install {' '.join(missing_packages)}")
|
||||
sys.exit(1)
|
||||
|
||||
success = main()
|
||||
sys.exit(0 if success else 1)
|
||||
|
||||
@ -2,47 +2,26 @@ import pandas as pd
|
||||
import math
|
||||
|
||||
|
||||
subEmitColor = ["Wood", "Clothes storage bag"]
|
||||
file_path = './script/MergeData.xlsx'
|
||||
|
||||
file_path = 'D:/Github/docs/config/MergeData.xlsx'
|
||||
df = pd.read_excel(file_path, engine='openpyxl')
|
||||
df = df.drop(index=0)
|
||||
df_emitter = df[(df['Type'] == 'Emitter') & (df['Emit_Product'].notnull())]
|
||||
df_emitter = df_emitter.assign(Dynamic=df_emitter['Emit_Product'])
|
||||
|
||||
def limitLv(x):
|
||||
if x == 0:
|
||||
return 5
|
||||
if x == 1:
|
||||
return 3
|
||||
if x == 2:
|
||||
return 2
|
||||
if x == 3:
|
||||
return 1
|
||||
|
||||
|
||||
# for index, row in df_emitter.iterrows():
|
||||
# print(f"Index: {index}")
|
||||
# print(row['Emit_List'])
|
||||
# a1 = row['Emit_List'].split(',')
|
||||
# Product = row['Emit_Product'].split(',')
|
||||
# main = row['Emit_Product'].split(',')[0]
|
||||
# if len(a1) == 1:
|
||||
# a2 = a1[0].split('=')
|
||||
# color_values = df[df["Id"] == int(a2[0])]["Color"].values[0]
|
||||
# if color_values in subEmitColor:
|
||||
# print(f"Main: {main} - Sub: {color_values}")
|
||||
# else:
|
||||
# df_emitter.loc[index, 'Dynamic'] = f"{color_values}=0"
|
||||
# continue
|
||||
# d = {}
|
||||
# for i in Product:
|
||||
# d[i] = 0.0
|
||||
# for i in a1 :
|
||||
# a2 = i.split('=')
|
||||
# color = df[df["Id"] == int(a2[0])]["Color"].values[0]
|
||||
# d[color] += float(a2[1])*(int(a2[0])%10)
|
||||
# c = {}
|
||||
# mainNum = d[main]
|
||||
# for k, i in d.items():
|
||||
# if k == main:
|
||||
# c[k] = 0
|
||||
# else:
|
||||
# x = round(mainNum/i)
|
||||
# c[k] = round(math.log(x, 2))
|
||||
|
||||
# print(df_emitter.head())
|
||||
|
||||
def minLv(x):
|
||||
return min(x, lv)
|
||||
def getDynamicValue1(df, index):
|
||||
row = df.loc[index]
|
||||
d = {}
|
||||
@ -55,79 +34,199 @@ def getDynamicValue1(df, index):
|
||||
d[color_values] = 0
|
||||
return d
|
||||
else:
|
||||
sumN = 0
|
||||
for i in Product:
|
||||
d[i] = 0.0
|
||||
for i in Emit_List :
|
||||
a2 = i.split('=')
|
||||
color = df[df["Id"] == int(a2[0])]["Color"].values[0]
|
||||
d[color] += float(a2[1])*(int(a2[0])%10)
|
||||
d[color] += float(a2[1])*(minLv(int(a2[0])%10))
|
||||
sumN += float(a2[1])*(minLv(int(a2[0])%10))
|
||||
c = {}
|
||||
mainNum = d[main]
|
||||
# mainNum = d[main]
|
||||
for k, i in d.items():
|
||||
if k == main:
|
||||
c[k] = 0
|
||||
else:
|
||||
x = mainNum/i
|
||||
c[k] = math.floor(math.log(x, 2))
|
||||
x = sumN/i
|
||||
c[k] = math.floor(math.log(x, 2))
|
||||
return c
|
||||
|
||||
def getDynamicValueG(df, index):
|
||||
def getDynamicValueJ(df, index):
|
||||
row = df.loc[index]
|
||||
d = {}
|
||||
Emit_List = row['Emit_List'].split(',')
|
||||
Product = row['Emit_Product'].split(',')
|
||||
main = row['Emit_Product'].split(',')[0]
|
||||
x1 = 30
|
||||
y = 16
|
||||
c = {}
|
||||
if len(Emit_List) == 1:
|
||||
a2 = Emit_List[0].split('=')
|
||||
color_values = df[df["Id"] == int(a2[0])]["Color"].values[0]
|
||||
d[color_values] = 0
|
||||
return d
|
||||
c["Detective Tools"] = round(math.floor(math.log((x1+y)/y, 2)))
|
||||
return c
|
||||
else:
|
||||
for i in Product:
|
||||
d[i] = 0.0
|
||||
for i in Emit_List :
|
||||
a2 = i.split('=')
|
||||
color = df[df["Id"] == int(a2[0])]["Color"].values[0]
|
||||
if color == "Clothes storage bag":
|
||||
d["Dress"] += float(a2[1])*(int(a2[0])%10)
|
||||
if color == "Detective Bag":
|
||||
d["Detective Tools"] += float(a2[1])*(minLv(int(a2[0])%10))
|
||||
else:
|
||||
d[color] += float(a2[1])*(int(a2[0])%10)
|
||||
c = {}
|
||||
mainNum = d[main]
|
||||
for k, i in d.items():
|
||||
if k == main:
|
||||
c[k] = 0
|
||||
else:
|
||||
x = mainNum/i
|
||||
c[k] = math.floor(math.log(x, 2))
|
||||
d[color] += float(a2[1])*(minLv(int(a2[0])%10))
|
||||
x2 = x1*(d["Detective Tools"]/d["Detective Outfit"])
|
||||
c["Detective Tools"] = round(math.ceil(math.log((x1+x2+y)/y, 2)))
|
||||
c["Detective Outfit"] = round(math.floor(math.log((x1+x2)/x2, 2)))
|
||||
return c
|
||||
def getDynamicValueM(df, index):
|
||||
row = df.loc[index]
|
||||
d = {}
|
||||
Emit_List = row['Emit_List'].split(',')
|
||||
Product = row['Emit_Product'].split(',')
|
||||
x1 = 112
|
||||
y = 16
|
||||
c = {}
|
||||
if len(Emit_List) == 1:
|
||||
c["Dye"] = round(math.floor(math.log((x1+y)/y, 2)))
|
||||
return c
|
||||
else:
|
||||
for i in Product:
|
||||
d[i] = 0.0
|
||||
for i in Emit_List :
|
||||
a2 = i.split('=')
|
||||
color = df[df["Id"] == int(a2[0])]["Color"].values[0]
|
||||
if color == "Flower":
|
||||
d["Dye"] += float(a2[1])*(minLv(int(a2[0])%10))
|
||||
else:
|
||||
d[color] += float(a2[1])*(minLv(int(a2[0])%10))
|
||||
|
||||
x2 = x1*(d["Dye"]/d["Aromatherapy"])
|
||||
c["Dye"] = round(math.ceil(math.log((x1+x2+y)/y, 2)))
|
||||
c["Aromatherapy"] = round(math.floor(math.log((x1+x2)/x2, 2)))
|
||||
return c
|
||||
def getDynamicValueR(df, index):
|
||||
row = df.loc[index]
|
||||
d = {}
|
||||
Emit_List = row['Emit_List'].split(',')
|
||||
Product = row['Emit_Product'].split(',')
|
||||
x1 = 112
|
||||
y = 15
|
||||
c = {}
|
||||
if len(Emit_List) == 1:
|
||||
c["Outdoor Toys"] = round(math.floor(math.log((x1+y)/y, 2)))
|
||||
return c
|
||||
else:
|
||||
for i in Product:
|
||||
d[i] = 0.0
|
||||
for i in Emit_List :
|
||||
a2 = i.split('=')
|
||||
color = df[df["Id"] == int(a2[0])]["Color"].values[0]
|
||||
if color == "Tent":
|
||||
d["Outdoor Toys"] += float(a2[1])*(minLv(int(a2[0])%10))
|
||||
else:
|
||||
d[color] += float(a2[1])*(minLv(int(a2[0])%10))
|
||||
|
||||
x2 = x1*(d["Bird Watching"]/d["Outdoor Toys"])
|
||||
c["Outdoor Toys"] = round(math.ceil(math.log((x1+x2+y)/y, 2)))
|
||||
c["Bird Watching"] = round(math.floor(math.log((x1+x2)/x2, 2)))
|
||||
return c
|
||||
def getDynamicValueW(df, index):
|
||||
row = df.loc[index]
|
||||
d = {}
|
||||
Emit_List = row['Emit_List'].split(',')
|
||||
Product = row['Emit_Product'].split(',')
|
||||
x1 = 31
|
||||
y = 16
|
||||
c = {}
|
||||
if len(Emit_List) == 1:
|
||||
c["Curtains"] = 1
|
||||
return c
|
||||
else:
|
||||
for i in Product:
|
||||
d[i] = 0.0
|
||||
for i in Emit_List :
|
||||
a2 = i.split('=')
|
||||
color = df[df["Id"] == int(a2[0])]["Color"].values[0]
|
||||
if color == "Handmade Fabric Art":
|
||||
d["Cushion"] += float(a2[1])*(minLv(int(a2[0])%10))
|
||||
else:
|
||||
d[color] += float(a2[1])*(minLv(int(a2[0])%10))
|
||||
|
||||
x2 = x1*(d["Cushion"]/d["Curtains"])
|
||||
c["Cushion"] = round(math.ceil(math.log((x1+x2+y)/y, 2)))
|
||||
c["Curtains"] = round(math.floor(math.log((x1+x2)/x2, 2)))
|
||||
return c
|
||||
def getDynamicValueC(df, index):
|
||||
x1 = 16
|
||||
y = 16
|
||||
c = {}
|
||||
c["Pet House"] = round(math.ceil(math.log((x1+y)/y, 2)))
|
||||
return c
|
||||
def getDynamicValueH(df, index):
|
||||
x1 = 112
|
||||
y = 16
|
||||
c = {}
|
||||
c["Jewelry Accessories"] = round(math.ceil(math.log((x1+y)/y, 2)))
|
||||
return c
|
||||
def getDynamicValue3(df, id):
|
||||
return df[df['Id'] == id]['Dynamic'].values[0]
|
||||
for i in range(0,4):
|
||||
lv = limitLv(i)
|
||||
for index, row in df_emitter.iterrows():
|
||||
if row['Emit_ID'] == 'A':
|
||||
d = getDynamicValue1(df, index)
|
||||
if row['Emit_ID'] == 'B':
|
||||
d = getDynamicValue1(df, index)
|
||||
if row['Emit_ID'] == 'C':
|
||||
d = getDynamicValueC(df, index)
|
||||
if row['Emit_ID'] == 'D':
|
||||
d = getDynamicValue1(df, index)
|
||||
if row['Emit_ID'] == 'E':
|
||||
d = getDynamicValue1(df, index)
|
||||
if row['Emit_ID'] == 'F':
|
||||
d = getDynamicValue1(df, index)
|
||||
if row['Emit_ID'] == 'G':
|
||||
d = getDynamicValue1(df, index)
|
||||
if row['Emit_ID'] == 'H':
|
||||
d = getDynamicValueH(df, index)
|
||||
if row['Emit_ID'] == 'I':
|
||||
d = getDynamicValue1(df, index)
|
||||
if row['Emit_ID'] == 'J':
|
||||
d = getDynamicValueJ(df, index)
|
||||
if row['Emit_ID'] == 'K':
|
||||
d = getDynamicValue1(df, index)
|
||||
if row['Emit_ID'] == 'L':
|
||||
d = getDynamicValue1(df, index)
|
||||
if row['Emit_ID'] == 'M':
|
||||
d = getDynamicValueM(df, index)
|
||||
if row['Emit_ID'] == 'N':
|
||||
d = getDynamicValue1(df, index)
|
||||
if row['Emit_ID'] == 'O':
|
||||
d = getDynamicValue1(df, index)
|
||||
if row['Emit_ID'] == 'P':
|
||||
d = getDynamicValue1(df, index)
|
||||
if row['Emit_ID'] == 'Q':
|
||||
d = getDynamicValue1(df, index)
|
||||
if row['Emit_ID'] == 'R':
|
||||
d = getDynamicValueR(df, index)
|
||||
if row['Emit_ID'] == 'S':
|
||||
d = getDynamicValue1(df, index)
|
||||
if row['Emit_ID'] == 'T':
|
||||
d = getDynamicValue1(df, index)
|
||||
if row['Emit_ID'] == 'U':
|
||||
d = getDynamicValue1(df, index)
|
||||
if row['Emit_ID'] == 'V':
|
||||
d = getDynamicValue1(df, index)
|
||||
if row['Emit_ID'] == 'W':
|
||||
d = getDynamicValueW(df, index)
|
||||
if row['Emit_ID'] == 'X':
|
||||
d = getDynamicValue1(df, index)
|
||||
|
||||
# 将字典格式化为 "key=value,..." 并写入原 DataFrame 的 'X' 列,然后打印验证
|
||||
dynamic_str = ",".join(f"{k}={v}" for k, v in d.items())
|
||||
# 构造列名,避免将 int 直接与 str 拼接导致 TypeError
|
||||
col_name = 'Dynamic' if i == 0 else f'Dynamic{i}'
|
||||
df.at[index, col_name] = dynamic_str
|
||||
print(dynamic_str)
|
||||
|
||||
|
||||
|
||||
for index, row in df_emitter.iterrows():
|
||||
if row['Emit_ID'] == 'I':
|
||||
d = getDynamicValueG(df, index)
|
||||
else:
|
||||
continue
|
||||
# if row['Emit_ID'] == 'B':
|
||||
# d = getDynamicValue1(df, index)
|
||||
# if row['Emit_ID'] == 'C':
|
||||
# d = getDynamicValue1(df, index)
|
||||
# if row['Emit_ID'] == 'D':
|
||||
# d = getDynamicValue1(df, index)
|
||||
# if row['Emit_ID'] == 'E':
|
||||
# d = getDynamicValue1(df, index)
|
||||
# if row['Emit_ID'] == 'F':
|
||||
# d = getDynamicValue1(df, index)
|
||||
# if row['Emit_ID'] == 'G':
|
||||
# d = getDynamicValue1(df, index)
|
||||
# if row['Emit_ID'] == 'H':
|
||||
# d = getDynamicValue1(df, index)
|
||||
# if row['Emit_ID'] == 'I':
|
||||
# d = getDynamicValue1(df, index)
|
||||
str = ""
|
||||
for i,j in d.items():
|
||||
str += f"{i}={j},"
|
||||
str = str[:-1]
|
||||
print(str)
|
||||
# 保存回 Excel(会覆盖原文件,已在脚本开始处有备份逻辑可扩展)
|
||||
save_file_path = './dynamicLv_output.xlsx'
|
||||
df.to_excel(save_file_path, index=False, engine='openpyxl')
|
||||
print(f"Saved updated file to {save_file_path}")
|
||||
61
script/insertRegister.py
Normal file
61
script/insertRegister.py
Normal file
@ -0,0 +1,61 @@
|
||||
import pymysql
|
||||
from sshtunnel import SSHTunnelForwarder
|
||||
|
||||
|
||||
server = SSHTunnelForwarder(
|
||||
ssh_address_or_host=("1.15.182.107", 22),
|
||||
ssh_username="root",
|
||||
ssh_password="`NS?VGg@7]~F3}p",
|
||||
remote_bind_address=("127.0.0.1",3306),
|
||||
local_bind_address=('127.0.0.1',5143)
|
||||
)
|
||||
|
||||
server.start()
|
||||
db_host = server.local_bind_host
|
||||
db_port = server.local_bind_port
|
||||
|
||||
conn = pymysql.connect(
|
||||
host=db_host,
|
||||
port=db_port,
|
||||
user="root",
|
||||
password="Z4rf7eZZe500dxa",
|
||||
database="pet_home_5"
|
||||
)
|
||||
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("select `dwUin`, `rolecreatetime` from t_player_baseinfo")
|
||||
result = cursor.fetchall()
|
||||
|
||||
server2 = SSHTunnelForwarder(
|
||||
ssh_address_or_host=("8.155.14.94", 22),
|
||||
ssh_username="root",
|
||||
ssh_password="-xLX]p!PQ1@SHm`A",
|
||||
remote_bind_address=("rm-f8zd2030feam53n43.mysql.rds.aliyuncs.com",3306),
|
||||
local_bind_address=('127.0.0.1',5144)
|
||||
)
|
||||
|
||||
server2.start()
|
||||
db_host2 = server2.local_bind_host
|
||||
db_port2 = server2.local_bind_port
|
||||
|
||||
conn2 = pymysql.connect(
|
||||
host=db_host2,
|
||||
port=db_port2,
|
||||
user="root",
|
||||
password="Z4rf7eZZe500dxa",
|
||||
database="pet_home"
|
||||
)
|
||||
|
||||
cursor2 = conn2.cursor()
|
||||
for i in result:
|
||||
cursor2.execute("INSERT INTO log_login (`Uid`, `Event`, Timestamp) VALUES (%s, 'register', %s)", (i[0], i[1]))
|
||||
print(i)
|
||||
conn2.commit()
|
||||
|
||||
cursor2.close()
|
||||
conn2.close()
|
||||
server2.stop()
|
||||
|
||||
cursor.close()
|
||||
conn.close()
|
||||
server.stop()
|
||||
1923
script/merged.csv
Normal file
1923
script/merged.csv
Normal file
File diff suppressed because it is too large
Load Diff
BIN
script/merged.xlsx
Normal file
BIN
script/merged.xlsx
Normal file
Binary file not shown.
@ -23,8 +23,8 @@ server.start()
|
||||
db_host = server.local_bind_host
|
||||
db_port = server.local_bind_port
|
||||
print(db_host, db_port)
|
||||
RID = 100184
|
||||
MYRID = 100004
|
||||
RID = 105372
|
||||
MYRID = 100100042
|
||||
|
||||
conn = pymysql.connect(
|
||||
host=db_host,
|
||||
@ -37,20 +37,32 @@ cursor = conn.cursor()
|
||||
cursor.execute(("select * from t_player_mod where dwUin = {rid}").format(rid = RID))
|
||||
result1 = cursor.fetchone()
|
||||
|
||||
conn1 = pymysql.connect(
|
||||
host="127.0.0.1",
|
||||
port=3306,
|
||||
user="root",
|
||||
password="root",
|
||||
database='Merge_Pet'
|
||||
|
||||
server2 = SSHTunnelForwarder(
|
||||
ssh_address_or_host=("1.15.182.107", 22),
|
||||
ssh_username="root",
|
||||
ssh_password="`NS?VGg@7]~F3}p",
|
||||
remote_bind_address=("127.0.0.1",3306),
|
||||
local_bind_address=('127.0.0.1',5144)
|
||||
)
|
||||
cursor1 = conn1.cursor()
|
||||
server2.start()
|
||||
db_host2 = server2.local_bind_host
|
||||
db_port2 = server2.local_bind_port
|
||||
conn2 = pymysql.connect(
|
||||
host=db_host2,
|
||||
port=db_port2,
|
||||
user="root",
|
||||
password="Z4rf7eZZe500dxa",
|
||||
database=f"pet_home_1"
|
||||
)
|
||||
cursor2 = conn2.cursor()
|
||||
|
||||
sql = "UPDATE t_player_mod SET mData = %s WHERE dwUin = %s"
|
||||
cursor1.execute(sql, (result1[1], MYRID))
|
||||
conn1.commit()
|
||||
cursor2.execute(sql, (result1[1], MYRID))
|
||||
conn2.commit()
|
||||
|
||||
cursor.close()
|
||||
conn.close()
|
||||
cursor1.close()
|
||||
conn1.close()
|
||||
cursor2.close()
|
||||
conn2.close()
|
||||
exit()
|
||||
56
script/mysql copy_to_local.py
Normal file
56
script/mysql copy_to_local.py
Normal file
@ -0,0 +1,56 @@
|
||||
import pymysql
|
||||
from sshtunnel import SSHTunnelForwarder
|
||||
from pymysql.converters import escape_string
|
||||
from ruamel.yaml import YAML
|
||||
import math
|
||||
|
||||
|
||||
UUID = 600000500823
|
||||
|
||||
|
||||
|
||||
# ===================config===================
|
||||
|
||||
|
||||
server = SSHTunnelForwarder(
|
||||
ssh_address_or_host=("47.254.83.25", 22),
|
||||
ssh_username="root",
|
||||
ssh_password="ByWayStudios01!",
|
||||
remote_bind_address=("127.0.0.1",3306),
|
||||
local_bind_address=('127.0.0.1',5143)
|
||||
)
|
||||
server.start()
|
||||
db_host = server.local_bind_host
|
||||
db_port = server.local_bind_port
|
||||
print(db_host, db_port)
|
||||
RID = 104214
|
||||
MYRID = 100100017
|
||||
|
||||
conn = pymysql.connect(
|
||||
host=db_host,
|
||||
port=db_port,
|
||||
user="root",
|
||||
password="Xijing1!",
|
||||
database="Merge_Pet_1"
|
||||
)
|
||||
cursor = conn.cursor()
|
||||
cursor.execute(("select * from t_player_mod where dwUin = {rid}").format(rid = RID))
|
||||
result1 = cursor.fetchone()
|
||||
|
||||
conn1 = pymysql.connect(
|
||||
host="127.0.0.1",
|
||||
port=3306,
|
||||
user="root",
|
||||
password="root",
|
||||
database='Merge_Pet_1'
|
||||
)
|
||||
cursor1 = conn1.cursor()
|
||||
sql = "UPDATE t_player_mod SET mData = %s WHERE dwUin = %s"
|
||||
cursor1.execute(sql, (result1[1], MYRID))
|
||||
conn1.commit()
|
||||
|
||||
cursor.close()
|
||||
conn.close()
|
||||
cursor1.close()
|
||||
conn1.close()
|
||||
exit()
|
||||
68
script/mysql copy_to_sdk.py
Normal file
68
script/mysql copy_to_sdk.py
Normal file
@ -0,0 +1,68 @@
|
||||
import pymysql
|
||||
from sshtunnel import SSHTunnelForwarder
|
||||
from pymysql.converters import escape_string
|
||||
from ruamel.yaml import YAML
|
||||
import math
|
||||
|
||||
|
||||
UUID = 600000500823
|
||||
|
||||
|
||||
|
||||
# ===================config===================
|
||||
|
||||
|
||||
server = SSHTunnelForwarder(
|
||||
ssh_address_or_host=("47.254.83.25", 22),
|
||||
ssh_username="root",
|
||||
ssh_password="ByWayStudios01!",
|
||||
remote_bind_address=("127.0.0.1",3306),
|
||||
local_bind_address=('127.0.0.1',5143)
|
||||
)
|
||||
server.start()
|
||||
db_host = server.local_bind_host
|
||||
db_port = server.local_bind_port
|
||||
print(db_host, db_port)
|
||||
RID = 102931
|
||||
MYRID = 200100030
|
||||
|
||||
conn = pymysql.connect(
|
||||
host=db_host,
|
||||
port=db_port,
|
||||
user="root",
|
||||
password="Xijing1!",
|
||||
database="Merge_Pet_1"
|
||||
)
|
||||
cursor = conn.cursor()
|
||||
cursor.execute(("select * from t_player_mod where dwUin = {rid}").format(rid = RID))
|
||||
result1 = cursor.fetchone()
|
||||
|
||||
|
||||
server2 = SSHTunnelForwarder(
|
||||
ssh_address_or_host=("1.15.182.107", 22),
|
||||
ssh_username="root",
|
||||
ssh_password="`NS?VGg@7]~F3}p",
|
||||
remote_bind_address=("127.0.0.1",3306),
|
||||
local_bind_address=('127.0.0.1',5144)
|
||||
)
|
||||
server2.start()
|
||||
db_host2 = server2.local_bind_host
|
||||
db_port2 = server2.local_bind_port
|
||||
conn2 = pymysql.connect(
|
||||
host=db_host2,
|
||||
port=db_port2,
|
||||
user="root",
|
||||
password="Z4rf7eZZe500dxa",
|
||||
database=f"Merge_Pet_sdk"
|
||||
)
|
||||
cursor2 = conn2.cursor()
|
||||
|
||||
sql = "UPDATE t_player_mod SET mData = %s WHERE dwUin = %s"
|
||||
cursor2.execute(sql, (result1[1], MYRID))
|
||||
conn2.commit()
|
||||
|
||||
cursor.close()
|
||||
conn.close()
|
||||
cursor2.close()
|
||||
conn2.close()
|
||||
exit()
|
||||
@ -1,8 +1,5 @@
|
||||
import pymysql
|
||||
from sshtunnel import SSHTunnelForwarder
|
||||
from pymysql.converters import escape_string
|
||||
from ruamel.yaml import YAML
|
||||
import math
|
||||
|
||||
|
||||
UUID = 600000500823
|
||||
@ -23,8 +20,8 @@ server.start()
|
||||
db_host = server.local_bind_host
|
||||
db_port = server.local_bind_port
|
||||
print(db_host, db_port)
|
||||
RID = 200200121
|
||||
MYRID = 100004
|
||||
RID = 200100004
|
||||
MYRID = 100100001
|
||||
|
||||
conn = pymysql.connect(
|
||||
host=db_host,
|
||||
|
||||
50
script/mysql_sdk.py
Normal file
50
script/mysql_sdk.py
Normal file
@ -0,0 +1,50 @@
|
||||
import pymysql
|
||||
from sshtunnel import SSHTunnelForwarder
|
||||
from pymysql.converters import escape_string
|
||||
from ruamel.yaml import YAML
|
||||
import math
|
||||
|
||||
# ===================config===================
|
||||
|
||||
|
||||
server = SSHTunnelForwarder(
|
||||
ssh_address_or_host=("1.15.182.107", 22),
|
||||
ssh_username="root",
|
||||
ssh_password="`NS?VGg@7]~F3}p",
|
||||
remote_bind_address=("127.0.0.1",3306),
|
||||
local_bind_address=('127.0.0.1',5143)
|
||||
)
|
||||
server.start()
|
||||
db_host = server.local_bind_host
|
||||
db_port = server.local_bind_port
|
||||
RID = 200100030
|
||||
MYRID = 100100017
|
||||
ServerId = int((RID % 100000000) / 100000)
|
||||
conn = pymysql.connect(
|
||||
host=db_host,
|
||||
port=db_port,
|
||||
user="root",
|
||||
password="Z4rf7eZZe500dxa",
|
||||
database=f"Merge_Pet_sdk"
|
||||
)
|
||||
cursor = conn.cursor()
|
||||
cursor.execute(("select * from t_player_mod where dwUin = {rid}").format(rid = RID))
|
||||
result1 = cursor.fetchone()
|
||||
|
||||
conn1 = pymysql.connect(
|
||||
host="127.0.0.1",
|
||||
port=3306,
|
||||
user="root",
|
||||
password="root",
|
||||
database='Merge_Pet_1'
|
||||
)
|
||||
cursor1 = conn1.cursor()
|
||||
sql = "UPDATE t_player_mod SET mData = %s WHERE dwUin = %s"
|
||||
cursor1.execute(sql, (result1[1], MYRID))
|
||||
conn1.commit()
|
||||
|
||||
cursor.close()
|
||||
conn.close()
|
||||
cursor1.close()
|
||||
conn1.close()
|
||||
exit()
|
||||
51
script/mysql_test.py
Normal file
51
script/mysql_test.py
Normal file
@ -0,0 +1,51 @@
|
||||
import pymysql
|
||||
from sshtunnel import SSHTunnelForwarder
|
||||
from pymysql.converters import escape_string
|
||||
from ruamel.yaml import YAML
|
||||
import math
|
||||
|
||||
# ===================config===================
|
||||
|
||||
|
||||
server = SSHTunnelForwarder(
|
||||
ssh_address_or_host=("1.15.182.107", 22),
|
||||
ssh_username="root",
|
||||
ssh_password="`NS?VGg@7]~F3}p",
|
||||
remote_bind_address=("127.0.0.1",3306),
|
||||
local_bind_address=('127.0.0.1',5143)
|
||||
)
|
||||
server.start()
|
||||
db_host = server.local_bind_host
|
||||
db_port = server.local_bind_port
|
||||
print(db_host, db_port)
|
||||
RID = 100100006
|
||||
MYRID = 100100017
|
||||
ServerId = int((RID % 100000000) / 100000)
|
||||
conn = pymysql.connect(
|
||||
host=db_host,
|
||||
port=db_port,
|
||||
user="root",
|
||||
password="Z4rf7eZZe500dxa",
|
||||
database=f"pet_home_{ServerId}"
|
||||
)
|
||||
cursor = conn.cursor()
|
||||
cursor.execute(("select * from t_player_mod where dwUin = {rid}").format(rid = RID))
|
||||
result1 = cursor.fetchone()
|
||||
|
||||
conn1 = pymysql.connect(
|
||||
host="127.0.0.1",
|
||||
port=3306,
|
||||
user="root",
|
||||
password="root",
|
||||
database='Merge_Pet_1'
|
||||
)
|
||||
cursor1 = conn1.cursor()
|
||||
sql = "UPDATE t_player_mod SET mData = %s WHERE dwUin = %s"
|
||||
cursor1.execute(sql, (result1[1], MYRID))
|
||||
conn1.commit()
|
||||
|
||||
cursor.close()
|
||||
conn.close()
|
||||
cursor1.close()
|
||||
conn1.close()
|
||||
exit()
|
||||
1
script/output.ts
Normal file
1
script/output.ts
Normal file
File diff suppressed because one or more lines are too long
22
script/test.py
Normal file
22
script/test.py
Normal file
@ -0,0 +1,22 @@
|
||||
import requests
|
||||
|
||||
def get_location_by_ip(ip):
|
||||
url = f"http://ip-api.com/json/{ip}?lang=zh-CN"
|
||||
response = requests.get(url)
|
||||
data = response.json()
|
||||
if data['status'] == 'success':
|
||||
return {
|
||||
'国家': data['country'],
|
||||
'省份': data['regionName'],
|
||||
'城市': data['city'],
|
||||
'运营商': data['isp'],
|
||||
'经度': data['lon'],
|
||||
'纬度': data['lat']
|
||||
}
|
||||
else:
|
||||
return None
|
||||
|
||||
# 示例
|
||||
ip = '8.8.8.8'
|
||||
location = get_location_by_ip(ip)
|
||||
print(location)
|
||||
40
script/test.spec
Normal file
40
script/test.spec
Normal file
@ -0,0 +1,40 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
|
||||
block_cipher = None
|
||||
|
||||
|
||||
a = Analysis(['test.py'],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=[],
|
||||
hiddenimports=[],
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=block_cipher,
|
||||
noarchive=False)
|
||||
pyz = PYZ(a.pure, a.zipped_data,
|
||||
cipher=block_cipher)
|
||||
|
||||
exe = EXE(pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
[],
|
||||
name='test',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=True,
|
||||
disable_windowed_traceback=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None )
|
||||
@ -9,17 +9,32 @@
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"42\n",
|
||||
"46\n",
|
||||
"[2, 4, 6, 23, 23, 26, 26, 42, 43, 45, 47, 48, 61, 65, 85, 105, 127, 143, 145, 145, 165, 183, 222, 225, 242, 248, 262, 264, 265, 265, 266, 267, 284, 288, 289, 303, 304, 306, 523, 563, 564, 702]\n",
|
||||
"[2, 4, 6, 22, 22, 23, 26, 26, 42, 43, 45, 47, 48, 61, 64, 64, 85, 105, 127, 143, 145, 145, 165, 183, 222, 225, 242, 248, 262, 264, 265, 265, 266, 267, 284, 288, 289, 303, 304, 306, 521, 521, 522, 563, 564, 702]\n"
|
||||
"60\n",
|
||||
"59\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ename": "ValueError",
|
||||
"evalue": "invalid literal for int() with base 10: '22\\n04'",
|
||||
"output_type": "error",
|
||||
"traceback": [
|
||||
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
|
||||
"\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)",
|
||||
"Cell \u001b[1;32mIn[1], line 18\u001b[0m\n\u001b[0;32m 16\u001b[0m l2 \u001b[38;5;241m=\u001b[39m []\n\u001b[0;32m 17\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;129;01min\u001b[39;00m a1:\n\u001b[1;32m---> 18\u001b[0m l1\u001b[38;5;241m.\u001b[39mappend(\u001b[38;5;28;43mint\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mi\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msplit\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m:\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m)\n\u001b[0;32m 19\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;129;01min\u001b[39;00m a2:\n\u001b[0;32m 20\u001b[0m l2\u001b[38;5;241m.\u001b[39mappend(\u001b[38;5;28mint\u001b[39m(i))\n",
|
||||
"\u001b[1;31mValueError\u001b[0m: invalid literal for int() with base 10: '22\\n04'"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"str = \"\"\"0@0@0@26:702 0@1@0@-1:26 0@2@0@-1:23 0@3@0@-1:303 0@4@0@-1:284 0@5@0@-1:43 0@6@0@-1:2 0@7@0@-1:65 0@8@0@2:85 1@0@0@-1:288 1@1@0@-1:61 1@2@0@-1:242 1@5@0@-1:6 1@6@0@-1:45 1@7@0@-1:47 1@8@0@21:183 2@0@0@-1:26 2@1@0@24:564 2@7@0@-1:42 2@8@0@4:105 3@0@0@16:563 3@1@0@-1:4 3@2@0@-1:265 3@6@0@-1:304 3@7@0@-1:222 3@8@0@-1:23 4@0@1@-1:289 4@1@0@-1:266 4@2@0@-1:265 4@7@0@-1:143 4@8@1@-1:306 5@0@0@-1:48 5@1@0@-1:248 5@2@0@-1:262 5@7@0@27:145 5@8@0@28:145 6@0@0@15:165 6@1@0@-1:264 6@2@0@-1:523 6@6@0@-1:225 6@7@0@22:127 6@8@1@-1:267\"\"\"\n",
|
||||
"str = \"\"\"0@0@0@165@0:1807 0@1@0@167@0:1803 0@2@0@-1@0:1531 0\n",
|
||||
"@3@0@155@0:1806 0@4@0@-1@0:1224 0@5@0@77@0:1207 0@6@0@-1@0:1222 0@7@0@-1@0:1523 0@8@0@-1@0:1521 1@0@0@147@0:1802 1@1@0@146@0:1801 1@2@0@205@0:2328 1@3@0@-1@0:2026 1@4@0@-1@0:1221 1@5@0@189@0:2302 1@6@0@187@0:22\n",
|
||||
"04 1@7@0@-1@0:1511 1@8@0@137@0:1408 2@0@0@152@0:1805 2@1@0@206@0:1602 2@3@0@204@0:2506 2@5@0@-1@0:2422 2@6@0@201@0:2403 2@7@0@-1@0:1866 2@8@0@198@0:2305 3@0@0@86@0:1107 3@1@0@-1@0:1512 3@2@0@186@0:2301 3@3@0@-1\n",
|
||||
"@0:1531 3@4@0@-1@0:1531 3@5@0@-1@0:2424 3@6@0@-1@0:1532 3@7@0@148@0:1804 3@8@0@168@0:2003 4@0@0@191@0:2007 4@1@0@-1@0:1535 4@3@0@185@0:2107 4@4@0@-1@0:2426 4@5@0@200@0:2401 4@6@0@199@0:2402 4@7@0@166@0:2002 4@8\n",
|
||||
"@0@160@0:2001 5@0@0@139@0:1705 5@1@0@-1@0:2524 5@2@0@181@0:2202 5@3@0@177@0:2105 5@4@0@203@0:563 5@5@0@183@0:2203 5@6@0@182@0:2201 5@7@0@176@0:2101 5@8@0@112@0:1704 6@0@0@104@0:1701 6@1@0@130@0:1703 6@2@0@151@0\n",
|
||||
":1901 6@3@0@159@0:1905 6@4@0@142@0:1706 6@5@0@154@0:1903 6@6@0@157@0:1904 6@7@0@158@0:1902 6@8@0@188@0:1906\"\"\"\n",
|
||||
"\n",
|
||||
"str2 = \"\"\"289 61 105 165 48 85 26 183 306 127 288 266 64 563 26 145 145 143 303 304 284 702 23 6 42 43 45 47 222 225 265 267 22 22 2 4 522 264 265 521 262 242 248 64 521 564\"\"\"\n",
|
||||
"str2 = \"\"\"1107 1701 1207 1704 1703 1705 1706 1801 1802 1804 1901 1805 1806 1904 1902 1903 2001 2002 1803 2003 2101 1807 2105 2202 2201 2203 2107 2204 2301 1866 1905 1906 2302 2007 1408 2305 563 2506 25\n",
|
||||
"24 2026 2328 1523 1511 1224 2401 1222 2402 2403 2424 2426 2422 1512 1221 1531 1535 1531 1521 1533 1522\"\"\"\n",
|
||||
"\n",
|
||||
"a1 = str.split(\" \")\n",
|
||||
"a2 = str2.split(\" \")\n",
|
||||
@ -39,14 +54,161 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"3/Qr-g]ljJ&9@bM&\n"
|
||||
"user_name=13100024182, auto_id=89 已更新\n",
|
||||
"user_name=13100024183, auto_id=90 已更新\n",
|
||||
"user_name=13100024011, auto_id=106 已更新\n",
|
||||
"user_name=13100024012, auto_id=107 已更新\n",
|
||||
"user_name=13100024081, auto_id=108 已更新\n",
|
||||
"user_name=13100024082, auto_id=109 已更新\n",
|
||||
"user_name=13100024161, auto_id=110 已更新\n",
|
||||
"user_name=13100024162, auto_id=111 已更新\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ename": "",
|
||||
"evalue": "",
|
||||
"output_type": "error",
|
||||
"traceback": [
|
||||
"\u001b[1;31m在当前单元格或上一个单元格中执行代码时 Kernel 崩溃。\n",
|
||||
"\u001b[1;31m请查看单元格中的代码,以确定故障的可能原因。\n",
|
||||
"\u001b[1;31m单击<a href='https://aka.ms/vscodeJupyterKernelCrash'>此处</a>了解详细信息。\n",
|
||||
"\u001b[1;31m有关更多详细信息,请查看 Jupyter <a href='command:jupyter.viewOutput'>log</a>。"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import pymysql\n",
|
||||
"from sshtunnel import SSHTunnelForwarder\n",
|
||||
"server = SSHTunnelForwarder(\n",
|
||||
" ssh_address_or_host=(\"1.15.182.107\", 22),\n",
|
||||
" ssh_username=\"root\",\n",
|
||||
" ssh_password=\"`NS?VGg@7]~F3}p\",\n",
|
||||
" remote_bind_address=(\"127.0.0.1\",3306),\n",
|
||||
" local_bind_address=('127.0.0.1',5143)\n",
|
||||
")\n",
|
||||
"server.start()\n",
|
||||
"db_host = server.local_bind_host\n",
|
||||
"db_port = server.local_bind_port\n",
|
||||
"conn = pymysql.connect(\n",
|
||||
" host=db_host,\n",
|
||||
" port=db_port,\n",
|
||||
" user=\"root\",\n",
|
||||
" password=\"Z4rf7eZZe500dxa\",\n",
|
||||
" database=f\"merge_pet_audit_1\"\n",
|
||||
")\n",
|
||||
"cursor = conn.cursor()\n",
|
||||
"# 获取dwUid=400100082的数据\n",
|
||||
"user_names = [\n",
|
||||
" \"13100024182\",\n",
|
||||
" \"13100024183\",\n",
|
||||
" \"13100024011\",\n",
|
||||
" \"13100024012\",\n",
|
||||
" \"13100024081\",\n",
|
||||
" \"13100024082\",\n",
|
||||
" \"13100024161\",\n",
|
||||
" \"13100024162\"\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"# 先获取dwUin=400100088的原始mData和updateTime\n",
|
||||
"cursor.execute(\"SELECT mData, updateTime FROM t_player_mod WHERE dwUin=400100088\")\n",
|
||||
"row = cursor.fetchone()\n",
|
||||
"if not row:\n",
|
||||
" print(\"未找到dwUin=400100088的数据\")\n",
|
||||
"else:\n",
|
||||
" mData, updateTime = row\n",
|
||||
" for user_name in user_names:\n",
|
||||
" # 查找auto_id\n",
|
||||
" cursor.execute(\"SELECT auto_id FROM t_account WHERE user_name=%s\", (user_name,))\n",
|
||||
" result = cursor.fetchone()\n",
|
||||
" if result:\n",
|
||||
" auto_id = result[0]\n",
|
||||
" # 更新t_player_mod表\n",
|
||||
" cursor.execute(\n",
|
||||
" \"UPDATE t_player_mod SET mData=%s, updateTime=%s WHERE dwUin=%s\",\n",
|
||||
" (mData, updateTime, auto_id + 400100000)\n",
|
||||
" )\n",
|
||||
" print(f\"user_name={user_name}, auto_id={auto_id} 已更新\")\n",
|
||||
" else:\n",
|
||||
" print(f\"user_name={user_name} 未找到auto_id\")\n",
|
||||
" conn.commit()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import pandas as pd\n",
|
||||
"\n",
|
||||
"# 读取CSV文件\n",
|
||||
"df = pd.read_excel('item.xlsx')\n",
|
||||
"\n",
|
||||
"# 将数据转换为TS的字典格式\n",
|
||||
"df = df.fillna('')\n",
|
||||
"ts_dict = df.to_dict(orient='records')\n",
|
||||
"\n",
|
||||
"# 写入新的TS文件\n",
|
||||
"with open('output.ts', 'w', encoding='utf-8') as f:\n",
|
||||
" f.write('export const data = ')\n",
|
||||
" f.write(str(ts_dict))\n",
|
||||
" f.write(';')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import requests\n",
|
||||
"\n",
|
||||
"def get_location_by_ip(ip):\n",
|
||||
" url = f\"http://ip-api.com/json/{ip}?lang=zh-CN\"\n",
|
||||
" response = requests.get(url)\n",
|
||||
" data = response.json()\n",
|
||||
" if data['status'] == 'success':\n",
|
||||
" return {\n",
|
||||
" '国家': data['country'],\n",
|
||||
" '省份': data['regionName'],\n",
|
||||
" '城市': data['city'],\n",
|
||||
" '运营商': data['isp'],\n",
|
||||
" '经度': data['lon'],\n",
|
||||
" '纬度': data['lat']\n",
|
||||
" }\n",
|
||||
" else:\n",
|
||||
" return None\n",
|
||||
"\n",
|
||||
"# 示例\n",
|
||||
"ip = '8.8.8.8'\n",
|
||||
"location = get_location_by_ip(ip)\n",
|
||||
"print(location)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"`g.v=aE|-S}[Uk\"^\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
@ -68,14 +230,14 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"日期时间: 2025-01-11 17:38:45\n"
|
||||
"日期时间: 2025-02-23 08:00:00\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
@ -83,7 +245,7 @@
|
||||
"from datetime import datetime\n",
|
||||
"\n",
|
||||
"# 示例时间戳\n",
|
||||
"timestamp = 1736588325\n",
|
||||
"timestamp = 1740268800\n",
|
||||
"\n",
|
||||
"# 将时间戳转换为日期时间\n",
|
||||
"dt_object = datetime.fromtimestamp(timestamp)\n",
|
||||
@ -92,12 +254,432 @@
|
||||
"print(\"日期时间:\", dt_object)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"1739428748\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import time\n",
|
||||
"\n",
|
||||
"timestamp = int(time.time())\n",
|
||||
"print(timestamp)\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"2025-04-28 10:59:46 BST\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from datetime import datetime\n",
|
||||
"import pytz\n",
|
||||
"\n",
|
||||
"date = datetime.now()\n",
|
||||
"timezone = pytz.timezone('Europe/London')\n",
|
||||
"aware_date = timezone.localize(date)\n",
|
||||
"formatted_date = aware_date.strftime(\"%Y-%m-%d %H:%M:%S %Z\")\n",
|
||||
"print(formatted_date)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import chardet\n",
|
||||
"\n",
|
||||
"# 获取当前目录下的所有文件\n",
|
||||
"files = [f for f in os.listdir('F:\\Github\\aplus-b_-pet_-c_nation') if os.path.isfile(f)]\n",
|
||||
"\n",
|
||||
"# 检测每个文件的编码\n",
|
||||
"for file in files:\n",
|
||||
" with open(file, 'rb') as f:\n",
|
||||
" raw_data = f.read()\n",
|
||||
" result = chardet.detect(raw_data)\n",
|
||||
" print(f\"文件: {file}, 编码: {result['encoding']}, 置信度: {result['confidence']}\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"状态码: 404\n",
|
||||
"返回文本: 404 page not found\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import requests\n",
|
||||
"# 使用已在其它单元导入的 requests 发起 POST 请求\n",
|
||||
"url = \"http://ship.bywaystudios.com/api/tuyou/charge\"\n",
|
||||
"\n",
|
||||
"payload = {\n",
|
||||
" \"amount\": 100, # 示例字段,根据接口规范调整\n",
|
||||
" \"currency\": \"USD\",\n",
|
||||
" \"description\": \"test charge\",\n",
|
||||
" \"metadata\": {\"order_id\": \"test123\"}\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"headers = {\n",
|
||||
" \"Content-Type\": \"application/json\",\n",
|
||||
" # 如果接口需要认证,加入相应头,例如:\n",
|
||||
" # \"Authorization\": \"Bearer YOUR_TOKEN\"\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"try:\n",
|
||||
" resp = requests.post(url, json=payload, headers=headers, timeout=10)\n",
|
||||
" print(\"状态码:\", resp.status_code)\n",
|
||||
" # 尝试解析为 JSON,否则打印文本\n",
|
||||
" try:\n",
|
||||
" print(\"返回 JSON:\", resp.json())\n",
|
||||
" except ValueError:\n",
|
||||
" print(\"返回文本:\", resp.text)\n",
|
||||
"except requests.RequestException as e:\n",
|
||||
" print(\"请求失败:\", e)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"C:\\Users\\U\\AppData\\Roaming\\Python\\Python313\\site-packages\\openpyxl\\styles\\stylesheet.py:237: UserWarning: Workbook contains no default style, apply openpyxl's default\n",
|
||||
" warn(\"Workbook contains no default style, apply openpyxl's default\")\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"已输出 Excel: merged.xlsx\n",
|
||||
"已输出 CSV: merged.csv\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import glob\n",
|
||||
"import pandas as pd\n",
|
||||
"import string\n",
|
||||
"\n",
|
||||
"# 合并当前目录下所有 .xlsx 文件中名为 sheet0..sheet38 的子表到一个表\n",
|
||||
"\n",
|
||||
"sheet_names = [f\"Sheet{i}\" for i in range(39)] # sheet0..sheet38\n",
|
||||
"\n",
|
||||
"def merge_sheets_in_dir(path=\".\", pattern=\"*.xlsx\", out_excel=\"merged.xlsx\", out_csv=\"merged.csv\", custom_columns=None):\n",
|
||||
" \"\"\"\n",
|
||||
" 合并多个Excel文件的指定sheet\n",
|
||||
" \n",
|
||||
" Args:\n",
|
||||
" custom_columns: dict, 列名映射,例如 {\"A\": \"姓名\", \"B\": \"年龄\"}\n",
|
||||
" \"\"\"\n",
|
||||
" files = [f for f in glob.glob(os.path.join(path, pattern)) if not os.path.basename(f).startswith(\"~$\")]\n",
|
||||
" dfs = []\n",
|
||||
" for file in files:\n",
|
||||
" try:\n",
|
||||
" # 读取时不使用第一行作为列名,自动生成A,B,C...列名\n",
|
||||
" xls = pd.read_excel(file, sheet_name=None, header=None)\n",
|
||||
" except Exception as e:\n",
|
||||
" print(f\"跳过文件 {file},读取失败: {e}\")\n",
|
||||
" continue\n",
|
||||
"\n",
|
||||
" for s in sheet_names:\n",
|
||||
" if s in xls and isinstance(xls[s], pd.DataFrame):\n",
|
||||
" df = xls[s].copy()\n",
|
||||
" \n",
|
||||
" # 生成A,B,C...列名\n",
|
||||
" num_cols = len(df.columns)\n",
|
||||
" col_letters = [string.ascii_uppercase[i] if i < 26 else f\"{string.ascii_uppercase[i//26-1]}{string.ascii_uppercase[i%26]}\" for i in range(num_cols)]\n",
|
||||
" df.columns = col_letters\n",
|
||||
" \n",
|
||||
" # 应用自定义列名\n",
|
||||
" if custom_columns:\n",
|
||||
" df = df.rename(columns=custom_columns)\n",
|
||||
" \n",
|
||||
" # 添加来源信息,便于追溯\n",
|
||||
" df[\"_source_file\"] = os.path.basename(file)\n",
|
||||
" df[\"_sheet_name\"] = s\n",
|
||||
" dfs.append(df)\n",
|
||||
" # 如果不存在则跳过\n",
|
||||
"\n",
|
||||
" if not dfs:\n",
|
||||
" print(\"未找到任何匹配的 sheet,未生成合并文件。\")\n",
|
||||
" return None\n",
|
||||
"\n",
|
||||
" # 合并,保留所有列(列并集)\n",
|
||||
" merged = pd.concat(dfs, ignore_index=True, sort=False)\n",
|
||||
"\n",
|
||||
" # 写出文件\n",
|
||||
" try:\n",
|
||||
" merged.to_excel(out_excel, index=False)\n",
|
||||
" print(f\"已输出 Excel: {out_excel}\")\n",
|
||||
" except Exception as e:\n",
|
||||
" print(f\"写 Excel 失败: {e}\")\n",
|
||||
"\n",
|
||||
" try:\n",
|
||||
" merged.to_csv(out_csv, index=False)\n",
|
||||
" print(f\"已输出 CSV: {out_csv}\")\n",
|
||||
" except Exception as e:\n",
|
||||
" print(f\"写 CSV 失败: {e}\")\n",
|
||||
"\n",
|
||||
" return merged\n",
|
||||
"\n",
|
||||
"# 执行合并(可修改 path 或 输出文件名)\n",
|
||||
"# 示例:自定义列名,现在A,B,C对应实际的列位置\n",
|
||||
"column_mapping = {\n",
|
||||
" \"A\": \"用户ID\",\n",
|
||||
" \"B\": \"用户名\", \n",
|
||||
" \"C\": \"积分\"\n",
|
||||
"}\n",
|
||||
"merged_df = merge_sheets_in_dir(\n",
|
||||
" path=r\"D:\\Github\\devops\\source\",\n",
|
||||
" custom_columns=column_mapping # 传入None则不重命名\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 28,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"连接哨兵或 Redis 时出错: No master found for 'mymaster' : <redis.client.Redis(<redis.connection.ConnectionPool(<redis.connection.Connection(host=127.0.0.1,port=26379,db=0)>)>)> - TimeoutError('Timeout connecting to server')\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from redis.sentinel import Sentinel\n",
|
||||
"\n",
|
||||
"# 连接 Redis 哨兵并获取主节点的示例\n",
|
||||
"# 若未安装 redis 库,请先在终端运行: pip install redis\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"# 修改为你的哨兵地址列表和 master 名称(若只有一个哨兵地址,仍以列表形式传入)\n",
|
||||
"SENTINELS = [('127.0.0.1', 26379)]\n",
|
||||
"MASTER_NAME = 'mymaster' # 根据你的配置修改(常见默认为 'mymaster')\n",
|
||||
"\n",
|
||||
"# 如果哨兵或 Redis 需要密码,按需设置以下两个变量\n",
|
||||
"SENTINEL_PASSWORD = None # 如果 sentinel 自身需要认证,设置该值或保持 None\n",
|
||||
"REDIS_PASSWORD = None # 如果 redis 主从需要认证,设置该值或保持 None\n",
|
||||
"\n",
|
||||
"try:\n",
|
||||
" sentinel = Sentinel(\n",
|
||||
" SENTINELS,\n",
|
||||
" socket_timeout=1,\n",
|
||||
" sentinel_kwargs={'password': SENTINEL_PASSWORD} if SENTINEL_PASSWORD else None\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" # 获取主节点客户端(写操作走主节点)\n",
|
||||
" master = sentinel.master_for(MASTER_NAME, socket_timeout=1, password=REDIS_PASSWORD)\n",
|
||||
" # 获取主节点的 IP 地址和端口\n",
|
||||
" master_info = sentinel.discover_master(MASTER_NAME)\n",
|
||||
" print(f\"主节点地址: {master_info[0]}:{master_info[1]}\")\n",
|
||||
" # 获取从节点客户端(读操作走从节点)\n",
|
||||
" slave = sentinel.slave_for(MASTER_NAME, socket_timeout=1, password=REDIS_PASSWORD)\n",
|
||||
"\n",
|
||||
" # 简单读写测试\n",
|
||||
" master.set('sentinel_test_key', 'hello')\n",
|
||||
" val = slave.get('sentinel_test_key') # 视复制延迟,可能需要短暂等待\n",
|
||||
" if val is not None:\n",
|
||||
" print(\"从节点读取值:\", val.decode() if isinstance(val, bytes) else val)\n",
|
||||
" else:\n",
|
||||
" print(\"从节点未读到值(可能有复制延迟),主节点值:\", master.get('sentinel_test_key'))\n",
|
||||
"\n",
|
||||
"except Exception as e:\n",
|
||||
" print(\"连接哨兵或 Redis 时出错:\", e)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 25,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"原始主节点: 172.22.0.2:6379\n",
|
||||
"映射后地址: 172.22.0.2:6379\n",
|
||||
"连接失败: Timeout connecting to server\n",
|
||||
"直接端口映射连接成功\n",
|
||||
"使用直接端口映射连接\n",
|
||||
"连接失败: Timeout connecting to server\n",
|
||||
"直接端口映射连接成功\n",
|
||||
"使用直接端口映射连接\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from redis.sentinel import Sentinel\n",
|
||||
"import redis\n",
|
||||
"\n",
|
||||
"# 解决容器内IP映射问题的几种方案\n",
|
||||
"\n",
|
||||
"# 方案1: 地址映射 - 将容器内部IP映射到外部可访问地址\n",
|
||||
"IP_MAPPING = {\n",
|
||||
" '172.17.0.2': '127.0.0.1', # 容器内IP -> 外部IP\n",
|
||||
" '172.17.0.3': '127.0.0.1', # 根据实际情况修改\n",
|
||||
" # 添加更多映射...\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"# 方案2: 自定义连接类处理IP映射\n",
|
||||
"class MappedSentinel(Sentinel):\n",
|
||||
" def __init__(self, sentinels, ip_mapping=None, **kwargs):\n",
|
||||
" super().__init__(sentinels, **kwargs)\n",
|
||||
" self.ip_mapping = ip_mapping or {}\n",
|
||||
" \n",
|
||||
" def master_for(self, service_name, **kwargs):\n",
|
||||
" # 获取原始主节点信息\n",
|
||||
" master_info = self.discover_master(service_name)\n",
|
||||
" original_host = master_info[0]\n",
|
||||
" port = master_info[1]\n",
|
||||
" \n",
|
||||
" # 应用IP映射\n",
|
||||
" mapped_host = self.ip_mapping.get(original_host, original_host)\n",
|
||||
" print(f\"原始主节点: {original_host}:{port}\")\n",
|
||||
" print(f\"映射后地址: {mapped_host}:{port}\")\n",
|
||||
" \n",
|
||||
" # 直接创建Redis连接到映射后的地址\n",
|
||||
" return redis.Redis(host=mapped_host, port=port, **kwargs)\n",
|
||||
"\n",
|
||||
"# 使用示例\n",
|
||||
"SENTINELS = [('127.0.0.1', 6381)]\n",
|
||||
"MASTER_NAME = 'mymaster'\n",
|
||||
"\n",
|
||||
"try:\n",
|
||||
" # 方案1: 使用自定义Sentinel类\n",
|
||||
" sentinel = MappedSentinel(\n",
|
||||
" SENTINELS,\n",
|
||||
" ip_mapping=IP_MAPPING,\n",
|
||||
" socket_timeout=1\n",
|
||||
" )\n",
|
||||
" \n",
|
||||
" master = sentinel.master_for(MASTER_NAME, socket_timeout=1, password=None)\n",
|
||||
" \n",
|
||||
" # 测试连接\n",
|
||||
" master.set('test_key', 'test_value')\n",
|
||||
" result = master.get('test_key')\n",
|
||||
" print(f\"连接测试成功: {result}\")\n",
|
||||
" \n",
|
||||
"except Exception as e:\n",
|
||||
" print(\"连接失败:\", e)\n",
|
||||
"\n",
|
||||
"# 方案3: 直接指定端口映射(如果使用Docker端口映射)\n",
|
||||
"def connect_with_port_mapping():\n",
|
||||
" \"\"\"\n",
|
||||
" 如果Redis容器使用了端口映射,如 -p 6379:6379\n",
|
||||
" 可以直接连接到映射的端口\n",
|
||||
" \"\"\"\n",
|
||||
" try:\n",
|
||||
" # 假设容器映射到本地端口6379\n",
|
||||
" direct_redis = redis.Redis(host='127.0.0.1', port=6379, socket_timeout=1, password='change_me_redis_pass')\n",
|
||||
" direct_redis.ping()\n",
|
||||
" print(\"直接端口映射连接成功\")\n",
|
||||
" return direct_redis\n",
|
||||
" except Exception as e:\n",
|
||||
" print(f\"直接连接失败: {e}\")\n",
|
||||
" return None\n",
|
||||
"\n",
|
||||
"# 方案4: 环境变量配置\n",
|
||||
"import os\n",
|
||||
"def get_redis_config():\n",
|
||||
" \"\"\"\n",
|
||||
" 从环境变量获取Redis配置\n",
|
||||
" \"\"\"\n",
|
||||
" return {\n",
|
||||
" 'host': os.getenv('REDIS_HOST', '127.0.0.1'),\n",
|
||||
" 'port': int(os.getenv('REDIS_PORT', '6379')),\n",
|
||||
" 'password': os.getenv('REDIS_PASSWORD', None)\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
"# 测试直接连接\n",
|
||||
"direct_connection = connect_with_port_mapping()\n",
|
||||
"if direct_connection:\n",
|
||||
" print(\"使用直接端口映射连接\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 补充:Docker网络配置建议\n",
|
||||
"\n",
|
||||
"docker_tips = \"\"\"\n",
|
||||
"解决容器IP问题的Docker配置建议:\n",
|
||||
"\n",
|
||||
"1. 端口映射方式:\n",
|
||||
" docker run -p 6379:6379 redis:latest\n",
|
||||
"\n",
|
||||
"2. 自定义网络:\n",
|
||||
" docker network create redis-net\n",
|
||||
" docker run --network redis-net --name redis-master redis:latest\n",
|
||||
"\n",
|
||||
"3. Host网络模式:\n",
|
||||
" docker run --network host redis:latest\n",
|
||||
"\n",
|
||||
"4. 环境变量配置:\n",
|
||||
" docker run -e REDIS_HOST=127.0.0.1 -e REDIS_PORT=6379 your-app\n",
|
||||
"\n",
|
||||
"5. Docker Compose示例:\n",
|
||||
" version: '3'\n",
|
||||
" services:\n",
|
||||
" redis:\n",
|
||||
" image: redis:latest\n",
|
||||
" ports:\n",
|
||||
" - \"6379:6379\"\n",
|
||||
" app:\n",
|
||||
" build: .\n",
|
||||
" environment:\n",
|
||||
" - REDIS_HOST=redis\n",
|
||||
" - REDIS_PORT=6379\n",
|
||||
" depends_on:\n",
|
||||
" - redis\n",
|
||||
"\"\"\"\n",
|
||||
"\n",
|
||||
"print(docker_tips)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"/usr/local/game/logs/ga_log/.log"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
|
||||
@ -47,10 +47,10 @@ def verify_order(product_id, token, access_token):
|
||||
parser = argparse.ArgumentParser(description="Verify Google Play order")
|
||||
parser.add_argument("product_id", help="Product ID")
|
||||
parser.add_argument("token", help="Purchase token")
|
||||
# args = parser.parse_args()
|
||||
args = parser.parse_args()
|
||||
accessToken = getAccessToken()
|
||||
order = verify_order("diamond_001_1.99", "ipdmanofmimckinooopehnnm.AO-J1OyP6x7gWu-hzaGlGJAeWEQMoqPC0TgQDCXeqz6QGMy4J8ZlDgZllTqSuAIX6uWJJ9QHS5KYnY-4Y6dr6B3T_td7n9ohLqm26WxNw4oBS0dL3GSYKYM", accessToken)
|
||||
order = verify_order(args.product_id, args.token, accessToken)
|
||||
print(order)
|
||||
|
||||
# python script/verifyOrder.py diamond_001_1.99 ipdmanofmimckinooopehnnm.AO-J1OyP6x7gWu-hzaGlGJAeWEQMoqPC0TgQDCXeqz6QGMy4J8ZlDgZllTqSuAIX6uWJJ9QHS5KYnY-4Y6dr6B3T_td7n9ohLqm26WxNw4oBS0dL3GSYKYM
|
||||
# ./verifyOrder shopspecialtwonew_001_0.99 dipjdchagdecheahmfmmhoep.AO-J1Ozl2Fmx55383f8zimKDr2vsBpu-86KjOYzCa2KjBt10u-G2-S-L9SOG0aokMMfwpiVsFDkxx87nLIhVl4jQPKO7cISj5ZLjLlI11MFQP_w6QQ4tEqo
|
||||
# newplayer_001_0.49 ojiimdalhjimomakjmmikjeo.AO-J1OyrzyVwOmTB1g27m5IDCegRilBl67Z36fOgtnqxJCXg0lXahFIAAzCc-BE_1jx01f2FWI9RgukVu6MDY6SbCs23S6TNHXq219h2hczovSm7Ae9nuMc
|
||||
# python script/verifyOrder.py shopspecialtwonew_001_0.99 lkdkopelbankljnfjfcgaflp.AO-J1OxLyAueQLDYIU3OysbqL-OOlPJvQktggsmurub3-oMDSX0qKcyBcBZA4yQWKnGa-r_cllfTrisHSNt4xFalk0YZg6FhNPeWTdJDjBaHi96isH7ML-c
|
||||
# ./verifyOrder newplayer_001_0.49 ojiimdalhjimomakjmmikjeo.AO-J1OyrzyVwOmTB1g27m5IDCegRilBl67Z36fOgtnqxJCXg0lXahFIAAzCc-BE_1jx01f2FWI9RgukVu6MDY6SbCs23S6TNHXq219h2hczovSm7Ae9nuMc
|
||||
40
script/verifyOrder.spec
Normal file
40
script/verifyOrder.spec
Normal file
@ -0,0 +1,40 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
|
||||
block_cipher = None
|
||||
|
||||
|
||||
a = Analysis(['verifyOrder.py'],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=[],
|
||||
hiddenimports=[],
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=block_cipher,
|
||||
noarchive=False)
|
||||
pyz = PYZ(a.pure, a.zipped_data,
|
||||
cipher=block_cipher)
|
||||
|
||||
exe = EXE(pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
[],
|
||||
name='verifyOrder',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=True,
|
||||
disable_windowed_traceback=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None )
|
||||
BIN
source/20251112.xlsx
Normal file
BIN
source/20251112.xlsx
Normal file
Binary file not shown.
@ -1,62 +1,62 @@
|
||||
[docker-ce-stable]
|
||||
name=Docker CE Stable - $basearch
|
||||
baseurl=https://download.docker.com/linux/centos/$releasever/$basearch/stable
|
||||
baseurl=https://download.docker.com/linux/centos/7/$basearch/stable
|
||||
enabled=1
|
||||
gpgcheck=1
|
||||
gpgkey=https://download.docker.com/linux/centos/gpg
|
||||
|
||||
[docker-ce-stable-debuginfo]
|
||||
name=Docker CE Stable - Debuginfo $basearch
|
||||
baseurl=https://download.docker.com/linux/centos/$releasever/debug-$basearch/stable
|
||||
baseurl=https://download.docker.com/linux/centos/7/debug-$basearch/stable
|
||||
enabled=0
|
||||
gpgcheck=1
|
||||
gpgkey=https://download.docker.com/linux/centos/gpg
|
||||
|
||||
[docker-ce-stable-source]
|
||||
name=Docker CE Stable - Sources
|
||||
baseurl=https://download.docker.com/linux/centos/$releasever/source/stable
|
||||
baseurl=https://download.docker.com/linux/centos/7/source/stable
|
||||
enabled=0
|
||||
gpgcheck=1
|
||||
gpgkey=https://download.docker.com/linux/centos/gpg
|
||||
|
||||
[docker-ce-test]
|
||||
name=Docker CE Test - $basearch
|
||||
baseurl=https://download.docker.com/linux/centos/$releasever/$basearch/test
|
||||
baseurl=https://download.docker.com/linux/centos/7/$basearch/test
|
||||
enabled=0
|
||||
gpgcheck=1
|
||||
gpgkey=https://download.docker.com/linux/centos/gpg
|
||||
|
||||
[docker-ce-test-debuginfo]
|
||||
name=Docker CE Test - Debuginfo $basearch
|
||||
baseurl=https://download.docker.com/linux/centos/$releasever/debug-$basearch/test
|
||||
baseurl=https://download.docker.com/linux/centos/7/debug-$basearch/test
|
||||
enabled=0
|
||||
gpgcheck=1
|
||||
gpgkey=https://download.docker.com/linux/centos/gpg
|
||||
|
||||
[docker-ce-test-source]
|
||||
name=Docker CE Test - Sources
|
||||
baseurl=https://download.docker.com/linux/centos/$releasever/source/test
|
||||
baseurl=https://download.docker.com/linux/centos/7/source/test
|
||||
enabled=0
|
||||
gpgcheck=1
|
||||
gpgkey=https://download.docker.com/linux/centos/gpg
|
||||
|
||||
[docker-ce-nightly]
|
||||
name=Docker CE Nightly - $basearch
|
||||
baseurl=https://download.docker.com/linux/centos/$releasever/$basearch/nightly
|
||||
baseurl=https://download.docker.com/linux/centos/7/$basearch/nightly
|
||||
enabled=0
|
||||
gpgcheck=1
|
||||
gpgkey=https://download.docker.com/linux/centos/gpg
|
||||
|
||||
[docker-ce-nightly-debuginfo]
|
||||
name=Docker CE Nightly - Debuginfo $basearch
|
||||
baseurl=https://download.docker.com/linux/centos/$releasever/debug-$basearch/nightly
|
||||
baseurl=https://download.docker.com/linux/centos/7/debug-$basearch/nightly
|
||||
enabled=0
|
||||
gpgcheck=1
|
||||
gpgkey=https://download.docker.com/linux/centos/gpg
|
||||
|
||||
[docker-ce-nightly-source]
|
||||
name=Docker CE Nightly - Sources
|
||||
baseurl=https://download.docker.com/linux/centos/$releasever/source/nightly
|
||||
baseurl=https://download.docker.com/linux/centos/7/source/nightly
|
||||
enabled=0
|
||||
gpgcheck=1
|
||||
gpgkey=https://download.docker.com/linux/centos/gpg
|
||||
|
||||
BIN
source/go1.24.4.linux-amd64.tar.gz
Normal file
BIN
source/go1.24.4.linux-amd64.tar.gz
Normal file
Binary file not shown.
5
sql/add_title_en_content_en.sql
Normal file
5
sql/add_title_en_content_en.sql
Normal file
@ -0,0 +1,5 @@
|
||||
-- filepath: sql/add_title_en_content_en.sql
|
||||
-- 在 system_mail_info 表中增加 title_en 和 content_en 列
|
||||
ALTER TABLE system_mail_info
|
||||
ADD COLUMN title_en VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'English title',
|
||||
ADD COLUMN content_en TEXT NOT NULL COMMENT 'English content';
|
||||
27
ssl/bywaystudios.com.key
Normal file
27
ssl/bywaystudios.com.key
Normal file
@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAth2OvQ4vKkQnKzfMEW+dBUGjPXpwuzizCa5wAGOyLFTIwv2a
|
||||
WsRDSnCeAA8NsoYVzuG2+tzHi7hOulAJTWHzr/XgdpNqO7KzFoIkYXGtTjFg3gML
|
||||
R8ikRZZWMMnSHy0jDvBoeydaf/ff+a2WZjKb2FknRBIUfdmbQdFLauo9Q1/V2mSc
|
||||
/9MQT4rLk50wpbWf4zzsYClHt09BD4lDoWS1iLKLDi5Do2DELkUUbV2flaElBcqX
|
||||
D6yw1v/fqmXUM1UpV5gKBrDZp3x9k0cbudUGfYlLulC0+k+UuVhXsVWQPMNUlp0+
|
||||
s9bfUUm1BQRmSaPUvkgwtzH83EAZmiKuUMTJ0QIDAQABAoIBAAJW+uB+8Cgw2/f4
|
||||
LY0DzBanMzu0+QHOxq4XKaU3orBjHnky3OrRnrO0IrOJffmPM3SG/dzXPVEUOx61
|
||||
rIjr+z+Ffy7G0hSWRSrC3UjLNxjMFZyEmX6Am2uxdMYHscVoxQyKFi2O4eDHBH+m
|
||||
tUn22H29F34OZWkAhLghwkBLZiIZcYBJhptG0uk5mpdN7thAG+3DQXv6VYIYyLT6
|
||||
3MVFPmaxBmxhQGUzRyyd+YF3Z6DiKPpWVYL7Wk3MT+62aui7X1J9Rwh54yAaFVox
|
||||
9U6cbwJb23cccSRvYJV19Uq1WzVTc19mex5+a9IY72kV9X50s6K/xpbzHyHhW+1B
|
||||
Bf4vcIECgYEA+gSjDkK+jKN2Scr61g5eTDd398aQcChvYSjVRTb2hY5pPTTVSy5/
|
||||
PoeW7XQlWbYZRpB3gVWLh61pSY4M063E/d8IZXHvvOl8UwwktoqCkrS7y5PO7aNM
|
||||
jF0vfbK9btMm/hjK/1bNPDQjknwVXMOug153wxLuCoRkm5yf7XxZTlkCgYEAunkE
|
||||
LJgpIcHQdViWwUzdqDuF8croDFRpDi/Nm93142E5w2N6yX9RS07EnRw2HacLQWxp
|
||||
oS85s3QxukihemU/4yblhtw6PZTkXE4vUPH8OI9hUQi9SwaWfD9qS4CGhYmjbB+d
|
||||
L917QHKoaaxk0+LvNZHa93RQsPl0yTSOiSCaGDkCgYEApKnHJk5JJ2FFN8aqu65M
|
||||
5s+lgJfTazsGWCxHgkV3yXCI2VnhnJlsDqfIfG2BZ/tp3DKrso+/zMUmUd5vjj6l
|
||||
PjrVUdLffUEds6iMyXiiFLNZ9/NKVvK1KMD61UOSRdpllPaJQ/BMTXldcE2u2CC8
|
||||
4CKop97gziZyCJb4MbYzL0kCgYEAm4klOi0Q4d9PiRGDbWg32oMLjkq4ktA1cGff
|
||||
EAtrdWU7UQZA/KD9pdrllEZbvRAAC2nqEU/ayRw5/i9mwTiCuW1QNdSrn4H5mCR+
|
||||
wv2Ua3jsqzKm8VVlX+1lM+TYT7omXaFg8vPCQldgsgPhdfrrm7s08QJL69Gm38y+
|
||||
txJCdcECgYBd6HDypjiuswd6fTmdNYMZBQJ+M1ouuyoylv4m6hEp3iHhmWyGvE30
|
||||
+VLfzPDMXwjAvbk6PLIKJw6R2fA/Lh3GOjb0heAcwuGpgqe0OM0+PRo4mxlbovcx
|
||||
K0RpSiac5cgpEdO4Og+cgKzCg3g35wVLfvUYDAaZrsP26I/Xru5lUw==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
127
ssl/bywaystudios.com.pem
Normal file
127
ssl/bywaystudios.com.pem
Normal file
@ -0,0 +1,127 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIGNzCCBR+gAwIBAgIQVqPp7OLoPM3oQ1nibTAApzANBgkqhkiG9w0BAQsFADBc
|
||||
MQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29UcnVzIENBIExpbWl0ZWQxMTAvBgNV
|
||||
BAMMKFdvVHJ1cyBEViBTZXJ2ZXIgQ0EgIFtSdW4gYnkgdGhlIElzc3Vlcl0wHhcN
|
||||
MjUxMjA5MDAwMDAwWhcNMjcwMTA5MjM1OTU5WjAdMRswGQYDVQQDDBIqLmJ5d2F5
|
||||
c3R1ZGlvcy5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2HY69
|
||||
Di8qRCcrN8wRb50FQaM9enC7OLMJrnAAY7IsVMjC/ZpaxENKcJ4ADw2yhhXO4bb6
|
||||
3MeLuE66UAlNYfOv9eB2k2o7srMWgiRhca1OMWDeAwtHyKRFllYwydIfLSMO8Gh7
|
||||
J1p/99/5rZZmMpvYWSdEEhR92ZtB0Utq6j1DX9XaZJz/0xBPisuTnTCltZ/jPOxg
|
||||
KUe3T0EPiUOhZLWIsosOLkOjYMQuRRRtXZ+VoSUFypcPrLDW/9+qZdQzVSlXmAoG
|
||||
sNmnfH2TRxu51QZ9iUu6ULT6T5S5WFexVZA8w1SWnT6z1t9RSbUFBGZJo9S+SDC3
|
||||
MfzcQBmaIq5QxMnRAgMBAAGjggMyMIIDLjAfBgNVHSMEGDAWgBSZmy32i/Cj24nU
|
||||
nvvldC9o0pBP5DAdBgNVHQ4EFgQUCFKCjmFS7bzr/gxZGuYPNTLwwwYwDgYDVR0P
|
||||
AQH/BAQDAgWgMAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwSQYD
|
||||
VR0gBEIwQDA0BgsrBgEEAbIxAQICFjAlMCMGCCsGAQUFBwIBFhdodHRwczovL3Nl
|
||||
Y3RpZ28uY29tL0NQUzAIBgZngQwBAgEwPQYDVR0fBDYwNDAyoDCgLoYsaHR0cDov
|
||||
L2NybC5jcmxvY3NwLmNuL1dvVHJ1c0RWU2VydmVyQ0FfMi5jcmwwbAYIKwYBBQUH
|
||||
AQEEYDBeMDgGCCsGAQUFBzAChixodHRwOi8vYWlhLmNybG9jc3AuY24vV29UcnVz
|
||||
RFZTZXJ2ZXJDQV8yLmNydDAiBggrBgEFBQcwAYYWaHR0cDovL29jc3AuY3Jsb2Nz
|
||||
cC5jbjAvBgNVHREEKDAmghIqLmJ5d2F5c3R1ZGlvcy5jb22CEGJ5d2F5c3R1ZGlv
|
||||
cy5jb20wggGOBgorBgEEAdZ5AgQCBIIBfgSCAXoBeAB3AGBMmq96f3dfAdQG/JIN
|
||||
yJnrCxx9+MlSG/r6F3c7l4vJAAABmwG3KuMAAAQDAEgwRgIhAOApwbyVueun3xhC
|
||||
mTSOgscM+EfoyMnm4lrNEcEly4ANAiEAqkqI93x0tYyXyanzewv1mVqWt5n9jKzs
|
||||
rOVBbn89QRwAfQCOykcLrN5q86IGsKR6hLdG/h/Gv5U+JeabTuQCSPPG6AAAAZsB
|
||||
tyvaAAgAAAUAAGfcEAQDAEYwRAIgIITO+svcTRkjPRrFpuvPT0yBDrxI0to55ivE
|
||||
amsxY+ACIGyR3rLWtmunFaVO4SIFzwg8cIl9Dv3C8+gEIE+YmhNwAH4AWW5sM4aU
|
||||
sllyolbIoOjdkEp26Ag92oc7AQg4KBQ87lkAAAGbAbcsGQAIAAAFAAAA590EAwBH
|
||||
MEUCIQDa9BiAFvEFRyS2VXo1RD6NL+1LycCQfe8lwaRgANltYAIgQwclGCysMlcz
|
||||
dB0OfBnmP5yskdWL4raEoxLX5+y9OPQwDQYJKoZIhvcNAQELBQADggEBAFULS/wz
|
||||
GEE6rqG1Pdd8in6JthtVgVwwTbLsOt09RAWRs0VS/qeVEYxrqYCcuO5FIjoX6ENk
|
||||
Hf6FAnqZp65/iTv9YtSoZFbghvD8ys8kjCB8bZOcs0FROehtCzLZb02ceozYjPoz
|
||||
1S1SEsvy4TM3pkW2OCPdNqTm1+dSPHZKlfZeeMuZxYv7a3rONry/JE3kN6tQ0Wfe
|
||||
HTRjO+H7trxie+e92SQ4vCcbooHvS6A5TAgtBC4cGNWWaMga+3GJyp2kcdjPzzpI
|
||||
yuOJLZKbRba+sWY1EDZVZ8pMwYMOYbf+4/ThLHVpzignsjSMgvcnq9CnMA4MPeIW
|
||||
bUtCaexj/Mif4ww=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIF4jCCA8qgAwIBAgIRANVuJGyU7WOrsUbvwZa2T7AwDQYJKoZIhvcNAQEMBQAw
|
||||
gYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtK
|
||||
ZXJzZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMS4wLAYD
|
||||
VQQDEyVVU0VSVHJ1c3QgUlNBIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTIw
|
||||
MDEwODAwMDAwMFoXDTMwMDEwNzIzNTk1OVowXDELMAkGA1UEBhMCQ04xGjAYBgNV
|
||||
BAoTEVdvVHJ1cyBDQSBMaW1pdGVkMTEwLwYDVQQDDChXb1RydXMgRFYgU2VydmVy
|
||||
IENBICBbUnVuIGJ5IHRoZSBJc3N1ZXJdMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
|
||||
MIIBCgKCAQEA7IE0rmVTVdRdNOzK1jsR/VppyukZ/XbQgakJHOhg6XGDsiHe/l5B
|
||||
3PxyXw18jEdN+7YxP0qsGz+HlQbsQh6XlwIyjpz/2gFMiqa7y1v+dHOgj6xNOF5a
|
||||
oaPm/Qhb0N+JYQidgaC+1Zp6W+YeC736rzCMr9vL1Usa3QLzRoQEo0DzbG4sPeP1
|
||||
US0Ia/i8o6szArH+DAcvrzCZ2kkpTScQ9QfOsvkMBP1W2otICdKUyZHaBc+ztTAd
|
||||
ovSlOR+GPf29dYfGQkZAp0tffIRw/na3WB86WGZPpNFfo2QxxsHYoL3oSWKfSWTY
|
||||
FgW22J8eA03TFHYowm/NqYuJ7GW553HppQIDAQABo4IBcDCCAWwwHwYDVR0jBBgw
|
||||
FoAUU3m/WqorSs9UgOHYm8Cd8rIDZsswHQYDVR0OBBYEFJmbLfaL8KPbidSe++V0
|
||||
L2jSkE/kMA4GA1UdDwEB/wQEAwIBhjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1Ud
|
||||
JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAiBgNVHSAEGzAZMA0GCysGAQQBsjEB
|
||||
AgIWMAgGBmeBDAECATBQBgNVHR8ESTBHMEWgQ6BBhj9odHRwOi8vY3JsLnVzZXJ0
|
||||
cnVzdC5jb20vVVNFUlRydXN0UlNBQ2VydGlmaWNhdGlvbkF1dGhvcml0eS5jcmww
|
||||
cQYIKwYBBQUHAQEEZTBjMDoGCCsGAQUFBzAChi5odHRwOi8vY3J0LnVzZXJ0cnVz
|
||||
dC5jb20vVVNFUlRydXN0UlNBQUFBQ0EuY3J0MCUGCCsGAQUFBzABhhlodHRwOi8v
|
||||
b2NzcC51c2VydHJ1c3QuY29tMA0GCSqGSIb3DQEBDAUAA4ICAQB5t8v3uYzHa4EL
|
||||
0rOb9g/YAmptUbILcBMKk1x188ucsGVPaG1DG9bpVamxbmCtFA1MlrA7iUC8SGop
|
||||
KBnuWFsNKiC7jCbRoahT1/FSwFsSuDlDmOjr1MqDXE+or08UkXsJB57XxXxdVOPl
|
||||
DcZHII4qHi1XKK4iurMqb+kbdpAWadyfidRRCGPopYCVYLLYhRJgpFGtfr6Gk8N0
|
||||
j81jq/7QbN0dRSDzMNdadKTc7c3+i9fIrXj79lV5Wvva+OL7nh8MxQhG1Ekek7Rv
|
||||
en++jSZvaEhCrMsSedFTA/aIy7oJg85tfglF2ybK61HsobjYzdDNICKJlIm4chlA
|
||||
XIDDqw2mw0Kz2snrkp9dpvMBqahF/Uy1kHzPcrq1/w5OqZWAuDKxZ68PuZ/ME2hI
|
||||
YbIDG9dWT6Y7eqtjQ2TmAQbOqdAG2LeikPMl2DMrPEa4lcKJzsFbHfHAW3hVgPSQ
|
||||
hRfS4TtbNnxijbsp8GguMHxP2R7dpAAYybwfZdXP7WYAnwEr1mzIf0Y3J0m7GDyX
|
||||
JhaflN3G2wIm2HzRd39NvnDRmFEraqui/YYO9ym0pwq1d0S+bGG6876QCto0u3Cg
|
||||
ItFh3Za2ZeIY+g5mWrejSaDs9LT7eu44iCyebfgekdMRqFeCuGAsJdsun3LOHHJo
|
||||
tCVPRjyFg9NDeJeMa4Z8QuXAXLd9cw==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFgTCCBGmgAwIBAgIQOXJEOvkit1HX02wQ3TE1lTANBgkqhkiG9w0BAQwFADB7
|
||||
MQswCQYDVQQGEwJHQjEbMBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYD
|
||||
VQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UE
|
||||
AwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTE5MDMxMjAwMDAwMFoXDTI4
|
||||
MTIzMTIzNTk1OVowgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5
|
||||
MRQwEgYDVQQHEwtKZXJzZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBO
|
||||
ZXR3b3JrMS4wLAYDVQQDEyVVU0VSVHJ1c3QgUlNBIENlcnRpZmljYXRpb24gQXV0
|
||||
aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAgBJlFzYOw9sI
|
||||
s9CsVw127c0n00ytUINh4qogTQktZAnczomfzD2p7PbPwdzx07HWezcoEStH2jnG
|
||||
vDoZtF+mvX2do2NCtnbyqTsrkfjib9DsFiCQCT7i6HTJGLSR1GJk23+jBvGIGGqQ
|
||||
Ijy8/hPwhxR79uQfjtTkUcYRZ0YIUcuGFFQ/vDP+fmyc/xadGL1RjjWmp2bIcmfb
|
||||
IWax1Jt4A8BQOujM8Ny8nkz+rwWWNR9XWrf/zvk9tyy29lTdyOcSOk2uTIq3XJq0
|
||||
tyA9yn8iNK5+O2hmAUTnAU5GU5szYPeUvlM3kHND8zLDU+/bqv50TmnHa4xgk97E
|
||||
xwzf4TKuzJM7UXiVZ4vuPVb+DNBpDxsP8yUmazNt925H+nND5X4OpWaxKXwyhGNV
|
||||
icQNwZNUMBkTrNN9N6frXTpsNVzbQdcS2qlJC9/YgIoJk2KOtWbPJYjNhLixP6Q5
|
||||
D9kCnusSTJV882sFqV4Wg8y4Z+LoE53MW4LTTLPtW//e5XOsIzstAL81VXQJSdhJ
|
||||
WBp/kjbmUZIO8yZ9HE0XvMnsQybQv0FfQKlERPSZ51eHnlAfV1SoPv10Yy+xUGUJ
|
||||
5lhCLkMaTLTwJUdZ+gQek9QmRkpQgbLevni3/GcV4clXhB4PY9bpYrrWX1Uu6lzG
|
||||
KAgEJTm4Diup8kyXHAc/DVL17e8vgg8CAwEAAaOB8jCB7zAfBgNVHSMEGDAWgBSg
|
||||
EQojPpbxB+zirynvgqV/0DCktDAdBgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rID
|
||||
ZsswDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0gBAowCDAG
|
||||
BgRVHSAAMEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly9jcmwuY29tb2RvY2EuY29t
|
||||
L0FBQUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDQGCCsGAQUFBwEBBCgwJjAkBggr
|
||||
BgEFBQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2EuY29tMA0GCSqGSIb3DQEBDAUA
|
||||
A4IBAQAYh1HcdCE9nIrgJ7cz0C7M7PDmy14R3iJvm3WOnnL+5Nb+qh+cli3vA0p+
|
||||
rvSNb3I8QzvAP+u431yqqcau8vzY7qN7Q/aGNnwU4M309z/+3ri0ivCRlv79Q2R+
|
||||
/czSAaF9ffgZGclCKxO/WIu6pKJmBHaIkU4MiRTOok3JMrO66BQavHHxW/BBC5gA
|
||||
CiIDEOUMsfnNkjcZ7Tvx5Dq2+UUTJnWvu6rvP3t3O9LEApE9GQDTF1w52z97GA1F
|
||||
zZOFli9d31kWTz9RvdVFGD/tSo7oBmF0Ixa1DVBzJ0RHfxBdiSprhTEUxOipakyA
|
||||
vGp4z7h/jnZymQyd/teRCBaho1+V
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb
|
||||
MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
|
||||
GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj
|
||||
YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL
|
||||
MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
|
||||
BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM
|
||||
GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
||||
ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua
|
||||
BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe
|
||||
3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4
|
||||
YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR
|
||||
rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm
|
||||
ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU
|
||||
oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
|
||||
MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v
|
||||
QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t
|
||||
b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF
|
||||
AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q
|
||||
GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
|
||||
Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2
|
||||
G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi
|
||||
l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3
|
||||
smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
|
||||
-----END CERTIFICATE-----
|
||||
@ -1,27 +0,0 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAo6z7cPVcCIu+rT6ywB5dhhpZfCiKQu155+XPR1kmMFwiFVQe
|
||||
XnzcT5kmdHLJVEZOgV+LM76SeiGi7haF3wH9N9uYUMmp91b4H2IAiybaKGl/Xc7M
|
||||
WWpn5YJcttCdd3ZfzYqRQoysucmi4qTzSwf3vJqijo+JFmDvolVWO0KtDsRmU6DL
|
||||
nocygaKROyyCh5HbWZnikb0bUTLYu58zhYvc1eFwrfwjRSPsGDcTbFHWCl1UNnfZ
|
||||
mWO0ydMnbfzUSQTGJmOVwqFkhMVRGFFjrTRUAeDNQpkr9YN8tGc+111Igq+uAfMc
|
||||
yrIIlfEy2ltSnu8hxjNb4sk5v9Fv7APkrjGVsQIDAQABAoIBAALK+8Fm/NDyg+iH
|
||||
fNv1YknDBYrhhpzZjSGtYYOWQr+pgTViKZOzYSKeLbKBl1J8uDzR6T/fsFBgMykJ
|
||||
flnnU6+Fa9k/dhe2RrNplzIvEaLsTFP79UjptwGK320ixl6yL04d337f6qSci07l
|
||||
wXcJMquBUf78j22WOt1gxAEGRFcccNj4yTxLOAFUqwegBy9MuH02VCW4z9QEwiWU
|
||||
MmQHbFIpHreJaIh+CaBWx9CUEzL4iCYqRnmSNgfw5AE0snvXid1tlQT4IBRvcPE4
|
||||
I2bRKUcxvckXHpVKbNPv2A43DoWjF+vlGjU6utMfZ5DRJWyn03s4HOAtrUGY48Sj
|
||||
0kNDbOECgYEAzSZYgqJuNXEzuZ9dYeXwvCdmU+krOUGaRu1gAymkRdSu+KFDxaTs
|
||||
xnbhbC0uUzSL0idqeUt3DpeV5rGJf8InbCVwTjmV8hKGS9zTMvBWAH4TavZswAJz
|
||||
/MNKXZ96UR9xRZFU4988pMF/yqliCLUgN8FI0KvAdIiMgJt4XWa0UUkCgYEAzD7s
|
||||
n9F7vo7ZHYt/L81lviw4+BBk1934LIvZsXadxmUE8S46ZgbqRZHbrErQ4GJGpCsc
|
||||
tGAsJpubDapGHv8iL5e6eUphHsM1wR18ciCSNjkxcvSiQJcCpzXLgDY8Tg7KxIOF
|
||||
c+HKH5O+awCIJcRBBZIXgTC6Gxy6IFee/GXNCSkCgYA0h4YQZSENJCBXflv97k/X
|
||||
Dcug3sqHjanAUZXNGYOLserflQNyf0l1hAkyltsOyRyoQhl8V3tzzBLBEGKhyQgp
|
||||
I+j+zrX7Vwz2LeQSXgHXfHDiaZjtDXO/nA3VrTk3vnJVmuH+uzGfCkD7lqWYjzBh
|
||||
tmc7r07HSBOZ9rU6TUsMqQKBgQCEoPPNEB4X7vDj85rCstE3vcW8qACkALrQSnwx
|
||||
dgIcO6sK5mb7q8/jH0UTy315x7dxkaFRLAZfh7oXFJP2Oty7JP7tFjSc4kx8u6X9
|
||||
AlOPrHIE4QCfirApXpBoEE/2rDpVg8ZcKqmy+aC0ISNHyvoiIOzscnTXeD8RE3Tl
|
||||
F0IeiQKBgAMSt0sbXy7jgBSUgK8GU5Ox2YcstNMJfeXu5F7WjbtuAlwMNJgBLVYd
|
||||
gM2lEE8xBUx/5wPkbvzJq4tRPzNO5T7AjOnYH1Ul2iz+kEDOZfPVL0OL/VUYFBYg
|
||||
4SZnnt1jC9aHLHVqVIIJK//9cEfOJZ6mz3DtyX2wDm/tdoFOr4cG
|
||||
-----END RSA PRIVATE KEY-----
|
||||
@ -1,62 +0,0 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIGCDCCBPCgAwIBAgIQA0IfJS+AMdxZgd8L1fUl/TANBgkqhkiG9w0BAQsFADBu
|
||||
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
|
||||
d3cuZGlnaWNlcnQuY29tMS0wKwYDVQQDEyRFbmNyeXB0aW9uIEV2ZXJ5d2hlcmUg
|
||||
RFYgVExTIENBIC0gRzIwHhcNMjQxMjA5MDAwMDAwWhcNMjUwMzA5MjM1OTU5WjAj
|
||||
MSEwHwYDVQQDExhwZXRob21lLmJ5d2F5c3R1ZGlvcy5jb20wggEiMA0GCSqGSIb3
|
||||
DQEBAQUAA4IBDwAwggEKAoIBAQCjrPtw9VwIi76tPrLAHl2GGll8KIpC7Xnn5c9H
|
||||
WSYwXCIVVB5efNxPmSZ0cslURk6BX4szvpJ6IaLuFoXfAf0325hQyan3VvgfYgCL
|
||||
JtooaX9dzsxZamflgly20J13dl/NipFCjKy5yaLipPNLB/e8mqKOj4kWYO+iVVY7
|
||||
Qq0OxGZToMuehzKBopE7LIKHkdtZmeKRvRtRMti7nzOFi9zV4XCt/CNFI+wYNxNs
|
||||
UdYKXVQ2d9mZY7TJ0ydt/NRJBMYmY5XCoWSExVEYUWOtNFQB4M1CmSv1g3y0Zz7X
|
||||
XUiCr64B8xzKsgiV8TLaW1Ke7yHGM1viyTm/0W/sA+SuMZWxAgMBAAGjggLrMIIC
|
||||
5zAfBgNVHSMEGDAWgBR435GQX+7erPbFdevVTFVT7yRKtjAdBgNVHQ4EFgQUKDRG
|
||||
tBU/MaYUiXNhjO+s2+fcgs0wIwYDVR0RBBwwGoIYcGV0aG9tZS5ieXdheXN0dWRp
|
||||
b3MuY29tMD4GA1UdIAQ3MDUwMwYGZ4EMAQIBMCkwJwYIKwYBBQUHAgEWG2h0dHA6
|
||||
Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYw
|
||||
FAYIKwYBBQUHAwEGCCsGAQUFBwMCMIGABggrBgEFBQcBAQR0MHIwJAYIKwYBBQUH
|
||||
MAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBKBggrBgEFBQcwAoY+aHR0cDov
|
||||
L2NhY2VydHMuZGlnaWNlcnQuY29tL0VuY3J5cHRpb25FdmVyeXdoZXJlRFZUTFND
|
||||
QS1HMi5jcnQwDAYDVR0TAQH/BAIwADCCAX4GCisGAQQB1nkCBAIEggFuBIIBagFo
|
||||
AHYATnWjJ1yaEMM4W2zU3z9S6x3w4I4bjWnAsfpksWKaOd8AAAGTqSjTewAABAMA
|
||||
RzBFAiBZVs4LrOREOEnv8tQKb5UNFkPVfV2nNqCy24bKLAVr/gIhAMg2KsKQ9a6q
|
||||
8Wc64AKJx3DjFqLFpCytkTVKtrBp0tUzAHUAcyAiDwgWivnzxKaLCrJqmkoA7vV3
|
||||
hYoITQUA1KVCRFkAAAGTqSjTHwAABAMARjBEAiAiy4Xqcy0oqGMDDBRManyt6VmT
|
||||
jCZRVA+mHBzoQT0NAgIgOCW5513LuInmKGlKi5jxRkIM0xh6te0uIQvt4ze9EekA
|
||||
dwDm0jFjQHeMwRBBBtdxuc7B0kD2loSG+7qHMh39HjeOUAAAAZOpKNMvAAAEAwBI
|
||||
MEYCIQDFKi06ApokpmIizAxE+175uD3bIYO9P3+otQg1ZjSiUQIhAJ0SThOlYjU6
|
||||
1nvXCCVCrj96Jsb1KuKUdtPAelusunAHMA0GCSqGSIb3DQEBCwUAA4IBAQCoWphr
|
||||
4DagcE2yZJkgbhtJ05HLnFBqaQQ5+7X6SR/MRAPY65nCKzgntzXvBcpexiF04I2u
|
||||
ivtR0sH28Riuu+VDL4ltjZQsW20hd0QNeKia4caUaOaX0hEG1EO0sGLfHQI0G+oq
|
||||
jtEuSQnnzy2El3gs0kORAFqhGkL2q56rscPpandzdF1H5v2CeM54Q9EmCFzwGW7e
|
||||
NbLm7MSbn0enWs9q/Zjs6+t9n4VYFZw2c8BXDXtrim35ZcJpJZ7D91ve5SaMH5yg
|
||||
5at5un2nAdDe3D3V1aATz5ebq3M0JHoqkmPE1a3CkzMdfA8CQArmClBn8gquxm/+
|
||||
dq4rSsSh89wAz+lO
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEqjCCA5KgAwIBAgIQDeD/te5iy2EQn2CMnO1e0zANBgkqhkiG9w0BAQsFADBh
|
||||
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
|
||||
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH
|
||||
MjAeFw0xNzExMjcxMjQ2NDBaFw0yNzExMjcxMjQ2NDBaMG4xCzAJBgNVBAYTAlVT
|
||||
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
|
||||
b20xLTArBgNVBAMTJEVuY3J5cHRpb24gRXZlcnl3aGVyZSBEViBUTFMgQ0EgLSBH
|
||||
MjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAO8Uf46i/nr7pkgTDqnE
|
||||
eSIfCFqvPnUq3aF1tMJ5hh9MnO6Lmt5UdHfBGwC9Si+XjK12cjZgxObsL6Rg1njv
|
||||
NhAMJ4JunN0JGGRJGSevbJsA3sc68nbPQzuKp5Jc8vpryp2mts38pSCXorPR+sch
|
||||
QisKA7OSQ1MjcFN0d7tbrceWFNbzgL2csJVQeogOBGSe/KZEIZw6gXLKeFe7mupn
|
||||
NYJROi2iC11+HuF79iAttMc32Cv6UOxixY/3ZV+LzpLnklFq98XORgwkIJL1HuvP
|
||||
ha8yvb+W6JislZJL+HLFtidoxmI7Qm3ZyIV66W533DsGFimFJkz3y0GeHWuSVMbI
|
||||
lfsCAwEAAaOCAU8wggFLMB0GA1UdDgQWBBR435GQX+7erPbFdevVTFVT7yRKtjAf
|
||||
BgNVHSMEGDAWgBROIlQgGJXm427mD/r6uRLtBhePOTAOBgNVHQ8BAf8EBAMCAYYw
|
||||
HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQIMAYBAf8C
|
||||
AQAwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp
|
||||
Y2VydC5jb20wQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybDMuZGlnaWNlcnQu
|
||||
Y29tL0RpZ2lDZXJ0R2xvYmFsUm9vdEcyLmNybDBMBgNVHSAERTBDMDcGCWCGSAGG
|
||||
/WwBAjAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BT
|
||||
MAgGBmeBDAECATANBgkqhkiG9w0BAQsFAAOCAQEAoBs1eCLKakLtVRPFRjBIJ9LJ
|
||||
L0s8ZWum8U8/1TMVkQMBn+CPb5xnCD0GSA6L/V0ZFrMNqBirrr5B241OesECvxIi
|
||||
98bZ90h9+q/X5eMyOD35f8YTaEMpdnQCnawIwiHx06/0BfiTj+b/XQih+mqt3ZXe
|
||||
xNCJqKexdiB2IWGSKcgahPacWkk/BAQFisKIFYEqHzV974S3FAz/8LIfD58xnsEN
|
||||
GfzyIDkH3JrwYZ8caPTf6ZX9M1GrISN8HnWTtdNCH2xEajRa/h9ZBXjUyFKQrGk2
|
||||
n2hcLrfZSbynEC/pSw/ET7H5nWwckjmAJ1l9fcnbqkU/pf6uMQmnfl0JQjJNSg==
|
||||
-----END CERTIFICATE-----
|
||||
31
tool/app.ini
31
tool/app.ini
@ -1,31 +0,0 @@
|
||||
[app]
|
||||
app_name = pet_home
|
||||
app_id = 1001
|
||||
app_path = /data/devops/Goleaf
|
||||
conf_path = /etc/pet_home
|
||||
[server]
|
||||
tcp_addr = 3600
|
||||
ws_addr = 3700
|
||||
listen_addr = 3800
|
||||
max_conn = 1000
|
||||
remote = pethome.bywaystudios.com
|
||||
|
||||
[mysql]
|
||||
mysql_user = root
|
||||
mysql_password = root
|
||||
mysql_host = 172.20.0.5
|
||||
mysql_port = 3306
|
||||
|
||||
[redis]
|
||||
redis_host = 172.20.0.6
|
||||
redis_port = 6379
|
||||
|
||||
[cluster]
|
||||
center_id = 0
|
||||
center_host = pethome.bywaystudios.com
|
||||
center_port = 3800
|
||||
|
||||
[log]
|
||||
log_level = debug
|
||||
te_log_path = /var/log/pet_home/te
|
||||
|
||||
15
tool/go.mod
15
tool/go.mod
@ -1,15 +0,0 @@
|
||||
module tool
|
||||
|
||||
go 1.23.1
|
||||
|
||||
require gopkg.in/ini.v1 v1.67.0
|
||||
|
||||
require (
|
||||
github.com/fatih/color v1.18.0 // indirect
|
||||
github.com/gookit/color v1.5.4 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/stretchr/testify v1.10.0 // indirect
|
||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
|
||||
golang.org/x/sys v0.25.0 // indirect
|
||||
)
|
||||
549
tool/main.go
549
tool/main.go
@ -1,549 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/gookit/color"
|
||||
"gopkg.in/ini.v1"
|
||||
)
|
||||
|
||||
const (
|
||||
SECRET_KEY = ")VQbB(vpy=U(wcp)"
|
||||
)
|
||||
|
||||
// GOOS=linux GOARCH=amd64 go build -o /data/devops/MergePet/tool/tool main.go
|
||||
var help = `
|
||||
Usage: app.ini [options]
|
||||
|
||||
start start the server
|
||||
stop stop the server
|
||||
restart restart the server
|
||||
status get the server status
|
||||
install install the server
|
||||
uninstall uninstall the server
|
||||
kill kill the server
|
||||
`
|
||||
var cfg *ini.File
|
||||
var FuncMap map[string]func() error
|
||||
var dirPath string
|
||||
var app_path string
|
||||
var (
|
||||
infoColor = color.New(color.FgGreen)
|
||||
warn = color.New(color.FgYellow)
|
||||
err = color.New(color.FgRed)
|
||||
)
|
||||
|
||||
func info(format string, a ...interface{}) {
|
||||
time := time.Now().Format("2006-01-02 15:04:05")
|
||||
format = fmt.Sprintf("[%s] %s\n", time, format)
|
||||
infoColor.Printf(format, a...)
|
||||
}
|
||||
|
||||
func main() {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
info("%s", help)
|
||||
}
|
||||
}()
|
||||
FuncMap = make(map[string]func() error)
|
||||
// 检查是否提供了命令行参数
|
||||
if len(os.Args) < 2 {
|
||||
log.Fatal(help)
|
||||
}
|
||||
var err error
|
||||
|
||||
// 获取当前文件的绝对路径
|
||||
execPath, err := os.Executable()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
absPath, err := filepath.Abs(execPath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
// 获取当前文件的绝对路径的文件夹路径
|
||||
dirPath = filepath.Dir(absPath)
|
||||
|
||||
// 加载 app.ini 文件
|
||||
cfg, err = ini.Load(dirPath + "/app.ini")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
app_path = cfg.Section("app").Key("app_path").String()
|
||||
register("start", start)
|
||||
register("stop", stop)
|
||||
register("install", install)
|
||||
register("status", status)
|
||||
register("restart", restart)
|
||||
register("uninstall", uninstall)
|
||||
register("reload", reload)
|
||||
register("kill", kill)
|
||||
funcName := os.Args[1]
|
||||
if f, ok := FuncMap[funcName]; ok {
|
||||
e := f()
|
||||
if e != nil {
|
||||
log.Fatal(e)
|
||||
}
|
||||
} else {
|
||||
log.Fatal(help)
|
||||
}
|
||||
}
|
||||
|
||||
func register(name string, f func() error) {
|
||||
FuncMap[name] = f
|
||||
}
|
||||
|
||||
func kill() error {
|
||||
if len(os.Args) < 4 {
|
||||
log.Fatal("请输入要停止的服务类型和区号 kill [center|node] 区号")
|
||||
}
|
||||
NodeType := os.Args[2]
|
||||
Zone := os.Args[3]
|
||||
// 示例命令
|
||||
app_name := cfg.Section("app").Key("app_name").String()
|
||||
processName := fmt.Sprintf("%s/zone/%s_%s_%s/server.json", app_path, app_name, NodeType, Zone)
|
||||
// 示例进程名称
|
||||
|
||||
// 获取进程号
|
||||
pid, err := getPidByArgs(processName)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// 使用命令行命令 kill -9 杀死进程
|
||||
cmd := exec.Command("kill", "-9", strconv.Itoa(pid))
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
info("server %s_%s 已被 kill -9 杀死, 进程号:%d", NodeType, Zone, pid)
|
||||
return nil
|
||||
}
|
||||
|
||||
func install() error {
|
||||
// log.Println("install")
|
||||
if len(os.Args) < 4 {
|
||||
err.Println("请输入要安装的服务类型和区号 install [center|node] 区号")
|
||||
}
|
||||
serverType := os.Args[2]
|
||||
zone := os.Args[3]
|
||||
if serverType != "center" && serverType != "node" {
|
||||
err.Println("请输入正确的服务类型 center|node")
|
||||
}
|
||||
AppName := cfg.Section("app").Key("app_name").String()
|
||||
// 生成服务名
|
||||
serviceName := fmt.Sprintf("%s_%s_%s", AppName, serverType, zone)
|
||||
// 判断文件夹是否存在
|
||||
folderPath := fmt.Sprintf("%s/zone/%s", app_path, serviceName)
|
||||
if _, err := os.Stat(folderPath); os.IsNotExist(err) {
|
||||
err := os.MkdirAll(folderPath, os.ModePerm)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
info("文件夹 %s 创建成功\n", folderPath)
|
||||
} else {
|
||||
info("文件夹 %s 已存在\n", folderPath)
|
||||
}
|
||||
|
||||
// 生成配置文件
|
||||
configPath := fmt.Sprintf("%s/server.json", folderPath)
|
||||
file, err := os.Create(configPath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer file.Close()
|
||||
zoneId, _ := strconv.Atoi(zone)
|
||||
cf, confs := createConfigFile(zoneId, serverType)
|
||||
file.WriteString(confs)
|
||||
|
||||
// 读取 SQL 文件内容并替换 %database% 字符串
|
||||
sqlFilePath := fmt.Sprintf("%s/tool/Merge_Pet.sql", app_path)
|
||||
sqlContent, err := os.ReadFile(sqlFilePath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
dbName := cf["DbName"].(string)
|
||||
modifiedSQL := strings.ReplaceAll(string(sqlContent), "%database%", dbName)
|
||||
|
||||
// 将修改后的内容写入临时文件
|
||||
tempSQLFile, err := os.CreateTemp("", "modified_*.sql")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
_, err = tempSQLFile.WriteString(modifiedSQL)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
tempSQLFile.Close()
|
||||
|
||||
// 创建数据库
|
||||
dbUser := cfg.Section("mysql").Key("mysql_user").String()
|
||||
dbPassword, _ := Decrypt(cfg.Section("mysql").Key("mysql_password").String())
|
||||
dbHost := cfg.Section("mysql").Key("mysql_host").String()
|
||||
dbPort := cfg.Section("mysql").Key("mysql_port").String()
|
||||
// log.Println("mysql", "-u"+dbUser, "-p"+dbPassword, "-h"+dbHost, "-P"+dbPort, "-e", fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", dbName))
|
||||
createDBCmd := exec.Command("mysql", "-u"+dbUser, "-p"+dbPassword, "-h"+dbHost, "-P"+dbPort, "-e", fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", dbName))
|
||||
createDBCmd.Stdout = os.Stdout
|
||||
createDBCmd.Stderr = os.Stderr
|
||||
|
||||
err = createDBCmd.Run()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
// log.Println("mysql", "-u"+dbUser, "-p"+dbPassword, "-h"+dbHost, "-P"+dbPort, dbName, "-e", fmt.Sprintf("source %s", tempSQLFile.Name()))
|
||||
// 执行修改后的 SQL 文件
|
||||
cmd := exec.Command("mysql", "-u"+dbUser, "-p"+dbPassword, "-h"+dbHost, "-P"+dbPort, dbName, "-e", fmt.Sprintf("source %s", tempSQLFile.Name()))
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
cmd = exec.Command("mkdir", cf["LogPath"].(string))
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
info("SQL 文件 %s 执行成功\n", sqlFilePath)
|
||||
info("配置文件 %s 创建成功\n", configPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
func uninstall() error {
|
||||
stop()
|
||||
if len(os.Args) < 4 {
|
||||
log.Fatal("请输入要卸载的服务类型和区号 uninstall [center|node] 区号")
|
||||
}
|
||||
serverType := os.Args[2]
|
||||
zone := os.Args[3]
|
||||
if serverType != "center" && serverType != "node" {
|
||||
log.Fatal("请输入正确的服务类型 center|node")
|
||||
}
|
||||
AppName := cfg.Section("app").Key("app_name").String()
|
||||
// 生成服务名
|
||||
serviceName := fmt.Sprintf("%s_%s_%s", AppName, serverType, zone)
|
||||
// 判断文件夹是否存在
|
||||
folderPath := fmt.Sprintf("%s/zone/%s", app_path, serviceName)
|
||||
if _, err := os.Stat(folderPath); os.IsNotExist(err) {
|
||||
info("文件夹 %s 不存在\n", folderPath)
|
||||
return nil
|
||||
} else {
|
||||
info("文件夹 %s 存在\n", folderPath)
|
||||
}
|
||||
// 删除文件夹
|
||||
err := os.RemoveAll(folderPath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
info("文件夹 %s 删除成功\n", folderPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
func createConfigFile(Id int, Type string) (map[string]interface{}, string) {
|
||||
conf := make(map[string]interface{})
|
||||
conf["LogLevel"] = cfg.Section("log").Key("log_level").String()
|
||||
|
||||
TcpStartAddr, _ := cfg.Section("server").Key("tcp_addr").Int()
|
||||
conf["TcpAddr"] = fmt.Sprintf(":%d", TcpStartAddr+Id)
|
||||
|
||||
WsStartAddr, _ := cfg.Section("server").Key("ws_addr").Int()
|
||||
conf["WsAddr"] = fmt.Sprintf(":%d", WsStartAddr+Id)
|
||||
|
||||
ListenAddr, _ := cfg.Section("server").Key("listen_addr").Int()
|
||||
|
||||
conf["MySqlAddr"] = cfg.Section("mysql").Key("mysql_host").String()
|
||||
conf["MySqlUsr"] = cfg.Section("mysql").Key("mysql_user").String()
|
||||
conf["MySqlPwd"] = cfg.Section("mysql").Key("mysql_password").String()
|
||||
conf["MySqlPort"] = cfg.Section("mysql").Key("mysql_port").String()
|
||||
MaxConnNum, _ := cfg.Section("server").Key("max_conn").Int()
|
||||
conf["MaxConnNum"] = MaxConnNum
|
||||
app_name := cfg.Section("app").Key("app_name").String()
|
||||
conf["LogPath"] = fmt.Sprintf("%s/zone/%s_%s_%d/log", app_path, app_name, Type, Id)
|
||||
conf["DbName"] = fmt.Sprintf("%s_%d", app_name, Id)
|
||||
|
||||
conf["TELOGDIR"] = cfg.Section("log").Key("te_log_path").String()
|
||||
|
||||
conf["GameName"] = app_name
|
||||
AppId, _ := cfg.Section("app").Key("app_id").Int()
|
||||
conf["AppID"] = AppId
|
||||
conf["AppPath"] = app_path
|
||||
conf["ServerType"] = Type
|
||||
conf["ServerID"] = Id
|
||||
|
||||
conf["ServerOpenTime"] = "2028-01-01 00:00:00"
|
||||
conf["ServerName"] = fmt.Sprintf("%s_%d", app_name, Id)
|
||||
conf["ServerStatus"] = 1
|
||||
CenterId, _ := cfg.Section("app").Key("center_id").Int()
|
||||
conf["ServerCenter"] = CenterId
|
||||
|
||||
conf["RedisAddr"] = cfg.Section("redis").Key("redis_host").String()
|
||||
conf["RedisPort"] = cfg.Section("redis").Key("redis_port").String()
|
||||
conf["GameConfPath"] = app_path + "/config/"
|
||||
conf["RemoteAddr"] = fmt.Sprintf("%s:%d", cfg.Section("server").Key("remote").String(), ListenAddr+Id) // 服务器地址
|
||||
conf["ListenAddr"] = fmt.Sprintf(":%d", ListenAddr+Id)
|
||||
conf["CenterAddr"] = fmt.Sprintf("%s:%s", cfg.Section("cluster").Key("center_host").String(), cfg.Section("cluster").Key("center_port").String()) // 服务器地址
|
||||
b, _ := json.MarshalIndent(conf, "", " ")
|
||||
return conf, string(b)
|
||||
}
|
||||
|
||||
func start() error {
|
||||
// log.Println("start")
|
||||
if len(os.Args) < 4 {
|
||||
log.Fatal("请输入要启动的服务类型和区号 start [center|node] 区号")
|
||||
}
|
||||
err := status()
|
||||
if err == nil {
|
||||
return err
|
||||
}
|
||||
|
||||
info("正在启动服务:server %s_%s ...", os.Args[2], os.Args[3])
|
||||
NodeType := os.Args[2]
|
||||
Zone := os.Args[3]
|
||||
// 示例命令
|
||||
app_name := cfg.Section("app").Key("app_name").String()
|
||||
|
||||
cmdName := app_path + "/main"
|
||||
cmdArgs := []string{fmt.Sprintf("%s/zone/%s_%s_%s/server.json", app_path, app_name, NodeType, Zone)}
|
||||
|
||||
// 创建命令
|
||||
cmd := exec.Command(cmdName, cmdArgs...)
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{}
|
||||
// 创建管道
|
||||
stdin, err := cmd.StdinPipe()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
cmd.Env = os.Environ()
|
||||
// 打开输出文件
|
||||
outfile, err := os.OpenFile(fmt.Sprintf("%s/zone/%s_%s_%s/output.log", app_path, app_name, NodeType, Zone), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer outfile.Close()
|
||||
|
||||
// 重定向标准输出和标准错误到文件
|
||||
cmd.Stdout = outfile
|
||||
cmd.Stderr = outfile
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// 打印进程号
|
||||
info("server %s_%s已启动, 进程号:%d", os.Args[2], os.Args[3], cmd.Process.Pid)
|
||||
|
||||
// 发送命令到子进程
|
||||
go func() {
|
||||
time.Sleep(2 * time.Second) // 等待子进程启动
|
||||
_, err := stdin.Write([]byte("your_command\n"))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
stdin.Close()
|
||||
}()
|
||||
|
||||
// 释放与子进程相关的资源
|
||||
err = cmd.Process.Release()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func reload() error {
|
||||
if len(os.Args) < 4 {
|
||||
log.Fatal("请输入要重启的服务类型和区号 reload [center|node] 区号")
|
||||
}
|
||||
app_name := cfg.Section("app").Key("app_name").String()
|
||||
NodeType := os.Args[2]
|
||||
Zone := os.Args[3]
|
||||
args := fmt.Sprintf("%s_%s_%s", app_name, NodeType, Zone)
|
||||
|
||||
pid, err := getPidByArgs(args)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// 向进程发送SIGTERM信号
|
||||
process, err := os.FindProcess(pid)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
err = process.Signal(syscall.SIGINT)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Printf("server %s_%s 已发送SIGINT信号, 进程号: %d\n", NodeType, Zone, pid)
|
||||
return nil
|
||||
}
|
||||
|
||||
func stop() error {
|
||||
if len(os.Args) < 4 {
|
||||
log.Fatal("请输入要停止的服务类型和区号 stop [center|node] 区号")
|
||||
}
|
||||
err := statusInfo()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
info("正在关闭服务:server %s_%s ...", os.Args[2], os.Args[3])
|
||||
NodeType := os.Args[2]
|
||||
Zone := os.Args[3]
|
||||
// 示例命令
|
||||
app_name := cfg.Section("app").Key("app_name").String()
|
||||
processName := fmt.Sprintf("%s/zone/%s_%s_%s/server.json", app_path, app_name, NodeType, Zone)
|
||||
// 示例进程名称
|
||||
|
||||
// 获取进程号
|
||||
pid, err := getPidByArgs(processName)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// 查找进程
|
||||
process, err := os.FindProcess(pid)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// 关闭进程
|
||||
err = process.Signal(syscall.SIGTERM)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
info("server %s_%s 已关闭,进程号:%d", NodeType, Zone, pid)
|
||||
return nil
|
||||
}
|
||||
|
||||
func getPidByArgs(args string) (int, error) {
|
||||
cmd := exec.Command("pgrep", "-f", args)
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 解析输出,获取第一个匹配的进程号
|
||||
outputStr := strings.TrimSpace(string(output))
|
||||
pidStr := strings.Split(outputStr, "\n")[0]
|
||||
pid, err := strconv.Atoi(pidStr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return pid, nil
|
||||
}
|
||||
|
||||
func status() error {
|
||||
if len(os.Args) < 4 {
|
||||
log.Fatal("请输入要查询的服务类型和区号 status [center|node] 区号")
|
||||
}
|
||||
|
||||
NodeType := os.Args[2]
|
||||
Zone := os.Args[3]
|
||||
// 示例命令
|
||||
app_name := cfg.Section("app").Key("app_name").String()
|
||||
processName := fmt.Sprintf("%s/zone/%s_%s_%s/server.json", app_path, app_name, NodeType, Zone)
|
||||
// 示例进程名称
|
||||
|
||||
// 获取进程号
|
||||
pid, err := getPidByArgs(processName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("进程 %s_%s 未启动", NodeType, Zone)
|
||||
}
|
||||
|
||||
// 查找进程
|
||||
_, err = os.FindProcess(pid)
|
||||
if err != nil {
|
||||
return fmt.Errorf("进程 %s_%s 未启动", NodeType, Zone)
|
||||
}
|
||||
|
||||
info("节点 %s_%s 启动中, 进程号 %d\n", NodeType, Zone, pid)
|
||||
return nil
|
||||
}
|
||||
|
||||
func statusInfo() error {
|
||||
NodeType := os.Args[2]
|
||||
Zone := os.Args[3]
|
||||
// 示例命令
|
||||
app_name := cfg.Section("app").Key("app_name").String()
|
||||
processName := fmt.Sprintf("%s/zone/%s_%s_%s/server.json", app_path, app_name, NodeType, Zone)
|
||||
// 示例进程名称
|
||||
|
||||
// 获取进程号
|
||||
pid, err := getPidByArgs(processName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("进程 %s_%s 未启动", NodeType, Zone)
|
||||
}
|
||||
|
||||
// 查找进程
|
||||
_, err = os.FindProcess(pid)
|
||||
if err != nil {
|
||||
return fmt.Errorf("进程 %s_%s 未启动", NodeType, Zone)
|
||||
}
|
||||
|
||||
// info.Println("节点 %s_%s 启动中, 进程号 %d\n", NodeType, Zone, pid)
|
||||
return nil
|
||||
}
|
||||
|
||||
func restart() error {
|
||||
if len(os.Args) < 4 {
|
||||
log.Fatal("请输入要重启的服务类型和区号 restart [center|node] 区号")
|
||||
}
|
||||
err := stop()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
for statusInfo() == nil {
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
err = start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 解密字符串
|
||||
func Decrypt(cipherText string) (string, error) {
|
||||
cipherTextBytes, err := base64.URLEncoding.DecodeString(cipherText)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
block, err := aes.NewCipher([]byte(SECRET_KEY))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if len(cipherTextBytes) < aes.BlockSize {
|
||||
return "", fmt.Errorf("cipherText too short")
|
||||
}
|
||||
|
||||
iv := cipherTextBytes[:aes.BlockSize]
|
||||
cipherTextBytes = cipherTextBytes[aes.BlockSize:]
|
||||
|
||||
stream := cipher.NewCFBDecrypter(block, iv)
|
||||
stream.XORKeyStream(cipherTextBytes, cipherTextBytes)
|
||||
|
||||
return string(cipherTextBytes), nil
|
||||
}
|
||||
102
tool/tool.py
102
tool/tool.py
@ -1,102 +0,0 @@
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import configparser
|
||||
|
||||
help_message = """
|
||||
Usage: app.ini [options]
|
||||
|
||||
start start the server
|
||||
stop stop the server
|
||||
restart restart the server
|
||||
status get the server status
|
||||
"""
|
||||
|
||||
cfg = None
|
||||
FuncMap = {}
|
||||
dir_path = ""
|
||||
app_path = ""
|
||||
|
||||
def main():
|
||||
global cfg, dir_path, app_path
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print(help_message)
|
||||
sys.exit(1)
|
||||
|
||||
# 获取当前文件的绝对路径
|
||||
exec_path = os.path.abspath(sys.argv[0])
|
||||
dir_path = os.path.dirname(exec_path)
|
||||
# print(f"当前文件的绝对路径的文件夹路径: {dir_path}")
|
||||
|
||||
# 加载 app.ini 文件
|
||||
cfg = configparser.ConfigParser()
|
||||
cfg.read(os.path.join(dir_path, "app.ini"))
|
||||
app_path = cfg.get("app", "app_path")
|
||||
|
||||
register("start", start)
|
||||
register("stop", stop)
|
||||
|
||||
func_name = sys.argv[1]
|
||||
if func_name in FuncMap:
|
||||
FuncMap[func_name]()
|
||||
else:
|
||||
print(help_message)
|
||||
sys.exit(1)
|
||||
|
||||
def register(name, func):
|
||||
FuncMap[name] = func
|
||||
|
||||
def start():
|
||||
print("start")
|
||||
NodeType = sys.argv[2]
|
||||
Zone = sys.argv[3]
|
||||
app_name = cfg.get("app", "app_name")
|
||||
|
||||
cmd_name = app_path + "/main"
|
||||
cmd_args = [f"{app_path}/zone/{app_name}_{NodeType}_{Zone}/server.json"]
|
||||
|
||||
# 创建命令
|
||||
cmd = [cmd_name] + cmd_args
|
||||
print(cmd)
|
||||
|
||||
# 启动命令
|
||||
process = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, start_new_session=True)
|
||||
print(f"p {process.pid} s")
|
||||
|
||||
# 获取命令输出
|
||||
stdout, stderr = process.communicate()
|
||||
print("e:", stdout.decode('utf-8', errors='ignore'))
|
||||
print("e2:", stderr.decode('utf-8', errors='ignore'))
|
||||
|
||||
def stop():
|
||||
print("stop")
|
||||
NodeType = sys.argv[2]
|
||||
Zone = sys.argv[3]
|
||||
app_name = cfg.get("app", "app_name")
|
||||
process_args = f"{app_path}/zone/{app_name}_{NodeType}_{Zone}/server.json"
|
||||
|
||||
# 获取进程号
|
||||
pid = get_pid_by_args(process_args)
|
||||
if pid is None:
|
||||
print("未找到进程")
|
||||
sys.exit(1)
|
||||
|
||||
# 关闭进程
|
||||
try:
|
||||
os.kill(pid, 9)
|
||||
print(f"进程 {pid} 已关闭")
|
||||
except OSError as e:
|
||||
print(f"关闭进程失败: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
def get_pid_by_args(args):
|
||||
try:
|
||||
output = subprocess.check_output(["pgrep", "-f", args])
|
||||
pid_str = output.decode().strip().split("\n")[0]
|
||||
return int(pid_str)
|
||||
except subprocess.CalledProcessError:
|
||||
return None
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
14
tools/go.mod
Normal file
14
tools/go.mod
Normal file
@ -0,0 +1,14 @@
|
||||
module merge
|
||||
|
||||
go 1.23.1
|
||||
|
||||
require (
|
||||
github.com/gookit/color v1.5.4
|
||||
gopkg.in/ini.v1 v1.67.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/stretchr/testify v1.10.0 // indirect
|
||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
|
||||
golang.org/x/sys v0.25.0 // indirect
|
||||
)
|
||||
@ -1,22 +1,13 @@
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||
github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0=
|
||||
github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8=
|
||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
148
tools/main.go
148
tools/main.go
@ -21,6 +21,7 @@ import (
|
||||
|
||||
const (
|
||||
SECRET_KEY = ")VQbB(vpy=U(wcp)"
|
||||
CLEAN_KEY = "MergePet2024!"
|
||||
)
|
||||
|
||||
// GOOS=linux GOARCH=amd64 go build -o /data/devops/MergePet/tool/tool main.go
|
||||
@ -30,10 +31,13 @@ Usage: app.ini [options]
|
||||
start start the server
|
||||
stop stop the server
|
||||
restart restart the server
|
||||
reload reload the config
|
||||
status get the server status
|
||||
install install the server
|
||||
uninstall uninstall the server
|
||||
kill kill the server
|
||||
backup backup the database
|
||||
clean clean the database
|
||||
`
|
||||
var cfg *ini.File
|
||||
var FuncMap map[string]func() error
|
||||
@ -90,6 +94,8 @@ func main() {
|
||||
register("uninstall", uninstall)
|
||||
register("reload", reload)
|
||||
register("kill", kill)
|
||||
register("backup", backup)
|
||||
register("clean", clean)
|
||||
funcName := os.Args[1]
|
||||
if f, ok := FuncMap[funcName]; ok {
|
||||
e := f()
|
||||
@ -305,6 +311,146 @@ func createConfigFile(Id int, Type string) (map[string]interface{}, string) {
|
||||
return conf, string(b)
|
||||
}
|
||||
|
||||
func backup() error {
|
||||
if len(os.Args) < 4 {
|
||||
log.Fatal("请输入要启动的服务类型和区号 start [center|node] 区号")
|
||||
}
|
||||
err := status()
|
||||
if err == nil {
|
||||
log.Fatal("节点启动中,请先关闭节点")
|
||||
}
|
||||
|
||||
info("开始备份:server %s_%s ...", os.Args[2], os.Args[3])
|
||||
NodeType := os.Args[2]
|
||||
Zone := os.Args[3]
|
||||
// 示例命令
|
||||
app_name := cfg.Section("app").Key("app_name").String()
|
||||
configName := fmt.Sprintf("%s/zone/%s_%s_%s/server.json", app_path, app_name, NodeType, Zone)
|
||||
jsonData, err := os.ReadFile(configName)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
var config map[string]interface{}
|
||||
if err := json.Unmarshal(jsonData, &config); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
info("读取配置文件 %s 成功", configName)
|
||||
dbUser := cfg.Section("mysql").Key("mysql_user").String()
|
||||
dbPassword, _ := Decrypt(cfg.Section("mysql").Key("mysql_password").String())
|
||||
dbHost := cfg.Section("mysql").Key("mysql_host").String()
|
||||
dbPort := cfg.Section("mysql").Key("mysql_port").String()
|
||||
dbName := config["DbName"].(string)
|
||||
|
||||
// 生成备份文件名
|
||||
backupFile := fmt.Sprintf("%s/zone/%s_%s_%s/%s_backup_%s.sql",
|
||||
app_path, app_name, NodeType, Zone, dbName, time.Now().Format("20060102_150405"))
|
||||
|
||||
// 执行 mysqldump 命令
|
||||
cmd := exec.Command("mysqldump",
|
||||
"-u"+dbUser,
|
||||
"-p"+dbPassword,
|
||||
"-h"+dbHost,
|
||||
"-P"+dbPort,
|
||||
dbName,
|
||||
)
|
||||
outFile, err := os.Create(backupFile)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer outFile.Close()
|
||||
cmd.Stdout = outFile
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
info("数据库 %s 备份成功,文件:%s", dbName, backupFile)
|
||||
return nil
|
||||
}
|
||||
|
||||
func clean() error {
|
||||
if len(os.Args) < 4 {
|
||||
log.Fatal("请输入要清空的服务类型和区号 clean [center|node] 区号")
|
||||
}
|
||||
err := status()
|
||||
if err == nil {
|
||||
log.Fatal("节点启动中,请先关闭节点")
|
||||
}
|
||||
fmt.Print("请输入操作密钥: ")
|
||||
var inputKey string
|
||||
fmt.Scanln(&inputKey)
|
||||
if inputKey != CLEAN_KEY {
|
||||
log.Fatal("密钥错误,操作终止")
|
||||
}
|
||||
info("开始清空数据库:server %s_%s ...", os.Args[2], os.Args[3])
|
||||
NodeType := os.Args[2]
|
||||
Zone := os.Args[3]
|
||||
app_name := cfg.Section("app").Key("app_name").String()
|
||||
configName := fmt.Sprintf("%s/zone/%s_%s_%s/server.json", app_path, app_name, NodeType, Zone)
|
||||
jsonData, err := os.ReadFile(configName)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
var config map[string]interface{}
|
||||
if err := json.Unmarshal(jsonData, &config); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
dbUser := cfg.Section("mysql").Key("mysql_user").String()
|
||||
dbPassword, _ := Decrypt(cfg.Section("mysql").Key("mysql_password").String())
|
||||
dbHost := cfg.Section("mysql").Key("mysql_host").String()
|
||||
dbPort := cfg.Section("mysql").Key("mysql_port").String()
|
||||
dbName := config["DbName"].(string)
|
||||
|
||||
// 获取所有表名
|
||||
showTablesCmd := exec.Command("mysql",
|
||||
"-u"+dbUser,
|
||||
"-p"+dbPassword,
|
||||
"-h"+dbHost,
|
||||
"-P"+dbPort,
|
||||
"-N", "-e", "SHOW TABLES IN "+dbName)
|
||||
output, err := showTablesCmd.Output()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
tables := strings.Fields(string(output))
|
||||
if len(tables) == 0 {
|
||||
info("数据库 %s 无表,无需清空", dbName)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 拼接 TRUNCATE 语句
|
||||
var stmts []string
|
||||
for _, t := range tables {
|
||||
stmts = append(stmts, fmt.Sprintf("TRUNCATE TABLE `%s`;", t))
|
||||
}
|
||||
truncateSQL := strings.Join(stmts, " ")
|
||||
|
||||
// 执行清空
|
||||
truncateCmd := exec.Command("mysql",
|
||||
"-u"+dbUser,
|
||||
"-p"+dbPassword,
|
||||
"-h"+dbHost,
|
||||
"-P"+dbPort,
|
||||
dbName,
|
||||
"-e", truncateSQL)
|
||||
truncateCmd.Stdout = os.Stdout
|
||||
truncateCmd.Stderr = os.Stderr
|
||||
if err := truncateCmd.Run(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
info("数据库 %s 所有表已清空", dbName)
|
||||
redisHost := cfg.Section("redis").Key("redis_host").String()
|
||||
redisPort := cfg.Section("redis").Key("redis_port").String()
|
||||
cmd := exec.Command("redis-cli", "-h", redisHost, "-p", redisPort, "FLUSHALL")
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Fatal("清空 Redis 失败: ", err)
|
||||
}
|
||||
info("Redis 所有数据已清空")
|
||||
return nil
|
||||
}
|
||||
|
||||
func start() error {
|
||||
// log.Println("start")
|
||||
if len(os.Args) < 4 {
|
||||
@ -312,7 +458,7 @@ func start() error {
|
||||
}
|
||||
err := status()
|
||||
if err == nil {
|
||||
return err
|
||||
log.Fatal("节点启动中")
|
||||
}
|
||||
|
||||
info("正在启动服务:server %s_%s ...", os.Args[2], os.Args[3])
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
# !/bin/bash
|
||||
cd /data/devops/tool
|
||||
cd /data/devops/tools
|
||||
GOOS=linux GOARCH=amd64 go build -o /data/devops/MergePet/tool/tool main.go
|
||||
38
verifyOrder.spec
Normal file
38
verifyOrder.spec
Normal file
@ -0,0 +1,38 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
|
||||
a = Analysis(
|
||||
['script/verifyOrder.py'],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=[],
|
||||
hiddenimports=[],
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
noarchive=False,
|
||||
optimize=0,
|
||||
)
|
||||
pyz = PYZ(a.pure)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
a.datas,
|
||||
[],
|
||||
name='verifyOrder',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=True,
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
)
|
||||
Loading…
Reference in New Issue
Block a user