1. 完成消息的接收循环的编写,现在的逻辑是:
1. 如果当前的前台程序是xxx那么就进入等待移出状态, 2. 如果当前是等待移出状态,然后切换了前台程序到其他程序那就触发一次同步 3. 同步后进入idle状态等待聚焦到xxx 2. 完成消息的发送基础步骤的准备,自动获取剪切板数据并且根据长度进行拆包进行发送。 3. 创建一个python的flask应用方便快速测试 4. 完成命令行参数的CLI化,方便直接使用,l0就是consumer,l3就是producer 5. 完成用户名的加密解密,使用机器的硬盘序列号进行加密解密 6. 保存msg的magic和cookies,方便重启使用, 但是目前来说cookies没有也是ok的。 因为没有做cookies的过期处理还。每次启动都会登录处理,并且登录期间过期的话只会异常,不会恢复, 所以这块还需要完善一下,如果登录期间发现过期了应当重新认证一下。 7. 等待完善发送的逻辑,这块本意是想要在l3的窗口鼠标移动到边缘之后保持不动就进行发送, 但是会存在一些和l0之间时序上匹配的问题。 如果l3另外启动一个用户界面用来交给用户触发交互呢,又做不到程序起初想要的无感的想法,这块还要再确认下
This commit is contained in:
parent
4d04dc2677
commit
089bf1e3ac
|
@ -9,14 +9,20 @@ tokio-macros = "2.4.0"
|
|||
reqwest = "0.12.5"
|
||||
log = "0.4.22"
|
||||
env_logger = "0.8"
|
||||
clap = "3.0"
|
||||
url = "2.2"
|
||||
percent-encoding = "2.1"
|
||||
trust-dns-resolver = "0.20"
|
||||
select = "0.5"
|
||||
scraper = "0.12"
|
||||
arboard = "3.4.0"
|
||||
|
||||
aes = "0.7"
|
||||
block-modes = "0.8"
|
||||
rand = "0.8" # 哈希库
|
||||
winapi = { version = "0.3.9", features = ["winuser", "psapi"] }
|
||||
base64 = "0.21"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
|
||||
[profile.test]
|
||||
env = { "RUST_LOG" = "debug" }
|
||||
|
|
6
info.json
Executable file
6
info.json
Executable file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"cookies": "",
|
||||
"magic": "3",
|
||||
"password": "ZWtrb2Jhb19fX19fX19fXzlytojwgd3qVW7PNYs7Y9s=",
|
||||
"user_name": "ekko.bao"
|
||||
}
|
24
python_flask_http_server/server.py
Executable file
24
python_flask_http_server/server.py
Executable file
|
@ -0,0 +1,24 @@
|
|||
from flask import Flask, send_from_directory, request,jsonify
|
||||
import sys
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route('/SSWeb/rd/copy_paste.jsp')
|
||||
def copy_paste():
|
||||
return send_from_directory('templates', 'copy_paste.html')
|
||||
|
||||
@app.route('/SSWeb/rd/copy_paste.jsp', methods=['POST'])
|
||||
def recive_msg():
|
||||
# 获取查询参数
|
||||
send_param = request.args.get('send')
|
||||
if not send_param:
|
||||
return jsonify({
|
||||
"zz": "must send query param"
|
||||
})
|
||||
# 获取 JSON 数据
|
||||
data = request.get_data().decode()
|
||||
print(f"msg is [{data}]\n")
|
||||
return send_from_directory('templates', 'copy_paste.html')
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.stdout.reconfigure(encoding='utf-8')
|
||||
app.run(host='0.0.0.0', port=5000)
|
513
python_flask_http_server/templates/copy_paste.html
Executable file
513
python_flask_http_server/templates/copy_paste.html
Executable file
|
@ -0,0 +1,513 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<link rel="stylesheet" type="text/css" href="/SSWeb/css/ajaxtags.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/SSWeb/css/screen.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/SSWeb/css/select2.min.css" />
|
||||
<link rel="stylesheet" type="text/css" href="/SSWeb/js/jquery-ui.min.css" media="print" />
|
||||
<link rel="stylesheet" type="text/css" href="/SSWeb/js/themes/base/jquery-ui.css">
|
||||
<link rel="stylesheet" type="text/css" href="/SSWeb/js/Searchable-Multi-select/jquery.dropdown.css" />
|
||||
|
||||
<script type="text/javascript" src="/SSWeb/js/jquery-1.7.2.min.js"></script>
|
||||
<script type="text/javascript" src="/SSWeb/js/prototype-1.7.3.js"></script>
|
||||
<script type="text/javascript" src="/SSWeb/js/scriptaculous/scriptaculous.js"></script>
|
||||
<script type="text/javascript" src="/SSWeb/js/overlibmws/overlibmws.js"></script>
|
||||
<script type="text/javascript" src="/SSWeb/js/ajaxtags.js"></script>
|
||||
<script type="text/javascript" src="/SSWeb/js/common.js"></script>
|
||||
<script type="text/javascript" src="/SSWeb/js/show_line.js"></script>
|
||||
<script type="text/javascript" src="/SSWeb/js/jquery-3.6.0.min.js"></script>
|
||||
<script type="text/javascript" src="/SSWeb/js/select2/dist/js/select2.min.js"></script>
|
||||
<script type="text/javascript" src="/SSWeb/js/jquery-ui.min.js"></script>
|
||||
<script type="text/javascript" src="/SSWeb/js/Searchable-Multi-select/jquery.dropdown.js"></script>
|
||||
|
||||
<style>
|
||||
.input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.fixline {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.btn-lg {
|
||||
padding: 5px 8px;
|
||||
font-size: 12px;
|
||||
line-height: 1.33;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
color: #fff;
|
||||
background-color: #428bca;
|
||||
border-color: #357ebd;
|
||||
}
|
||||
|
||||
.noteMacro {
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-color: #F0C000;
|
||||
background-color: #FFFFCE;
|
||||
text-align: left;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px
|
||||
}
|
||||
|
||||
.infoMacro {
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-color: #3c78b5;
|
||||
background-color: #D8E4F1;
|
||||
text-align: left;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px
|
||||
}
|
||||
</style>
|
||||
<title>Copy & Paste</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<script>
|
||||
var jBPM = jQuery.noConflict();
|
||||
</script>
|
||||
<form id="copy_paste" name="copy_paste" method="post" action="copy_paste.jsp?send=y">
|
||||
<table style="width:100%" class="simple">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Message (maxiumn 300 characters)</th>
|
||||
<th>Execute</th>
|
||||
<th>Tips</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="width:80%;"><textarea id="message" name="message"
|
||||
style="width:100%;height:80px"></textarea></td>
|
||||
<td style="width:10%;vertical-align:middle;"><input type="submit" value="Send Message" /></td>
|
||||
<td style="width:10%;vertical-align:middle;"><input type="button" value="Show Tips"
|
||||
onclick='javascript: jBPM("#page_tips").show();' /></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
<table id="page_tips" style="display:none;" cellpadding="5" width="80%" cellspacing="8px" class="infoMacro"
|
||||
border="0">
|
||||
<colgroup>
|
||||
<col width="24">
|
||||
<col>
|
||||
</colgroup>
|
||||
<tr>
|
||||
<td>
|
||||
</td>
|
||||
<td style="text-align:left;width:80%">
|
||||
1. ..................300......<br />
|
||||
2. .................................<br />
|
||||
3. .......................................
|
||||
</td>
|
||||
<td style="text-align:right;"><input type="button" value="X"
|
||||
onclick='javascript:jBPM("#page_tips").hide(); '></td>
|
||||
</tr>
|
||||
</table>
|
||||
<span class="pagebanner">59 items found, displaying 1 to 50.</span><span class="pagelinks">[First/Prev]
|
||||
<strong>1</strong>, <a href="/SSWeb/rd/copy_paste.jsp?d-16544-p=2" title="Go to page 2">2</a> [<a
|
||||
href="/SSWeb/rd/copy_paste.jsp?d-16544-p=2">Next</a>/<a
|
||||
href="/SSWeb/rd/copy_paste.jsp?d-16544-p=2">Last</a>]</span>
|
||||
<table class="mars" style="width:100%;" id="row">
|
||||
<caption><u>Message List</u></caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="sortable">
|
||||
<a href="/SSWeb/rd/copy_paste.jsp?d-16544-p=1&d-16544-o=2&d-16544-s=0">Message</a>
|
||||
</th>
|
||||
<th class="sortable sorted order2">
|
||||
<a href="/SSWeb/rd/copy_paste.jsp?d-16544-p=1&d-16544-o=2&d-16544-s=1">Create_Date_Time</a>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre style='font-size:12px;'><code style='background-color:#eec;'>剪切板测试函数</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-10-20 11:25:09.92</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#ccb;'>C:\Users\ekko.bao\Desktop\......</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-10-20 11:24:14.543</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#eec;'>http://sswiki:8090/pages/viewpage.action?pageId=41925635</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-10-11 17:15:46.733</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre style='font-size:12px;'><code style='background-color:#ccb;'> ldc stop channel too long,so force stop&destroy channel resource,then when ldc pass task use channel resources, crash happen
|
||||
</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-09-15 10:06:45.327</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#eec;'>the return value is the number of milliseconds remaining in the originally requested sleep period</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-09-14 15:18:48.05</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#ccb;'>find ./cmodel_ut/output -name "Dst*" |xargs ls -t | xargs -i md5sum {} > ./md5.txt</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-09-08 11:53:33.86</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#eec;'>https://blog.csdn.net/weixin_42319283/article/details/85089887</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-09-05 10:04:31.997</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#ccb;'>eval $(find ./ -name "*0.bmp" | xargs -i printf "\"/mnt/d/software/Beyond\ Compare\ 4/BCompare.exe\" %s ../../%s;\n" {} {} | xargs -i printf "date;echo \"start %s\";%s echo end;" {} {})</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-08-09 20:08:09.93</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#eec;'>eval $(cat check_ut_result/test7/result.txt | grep FAIL | awk '{printf "./prog_ldc_ut -c %s -C;\n", $3}')</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-08-09 20:01:22.627</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#ccb;'>f82d0b02-3a00-43ed-b33b-18e5766035e5</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-07-11 11:20:22.407</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#eec;'>92b100a1-8981-4c74-8a0e-ba4ab8975adb</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-06-22 11:05:09.673</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#ccb;'>5fbf21f4-d9ed-4325-97ed-4109220d9021</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-06-20 16:00:29.843</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#eec;'>a173712a-3c38-4e38-9f61-75b03c9d5a68</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-06-14 19:56:49.29</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre style='font-size:12px;'><code style='background-color:#ccb;'>............: [LDC] ......LDC EIS .........bypass......
|
||||
............: 1. ..............................vpe_ldc...ldc............
|
||||
2. ......ldc&vpe_ldc.....................
|
||||
|
||||
..................review..................</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-03-02 21:45:44.06</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre style='font-size:12px;'><code style='background-color:#eec;'>..................review..................
|
||||
............: [LDC] EIS..............................
|
||||
............: 1. ............L3...CV......................................................</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-03-02 21:45:16.637</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#ccb;'>1. ...............LDC mi_eptz_linux.h.................................lib.............................................................................................................................................................................................-----------............
|
||||
2.wiki...... eptz user guide...............................................................-----...........................</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-03-01 21:42:29.107</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre style='font-size:12px;'><code style='background-color:#eec;'>1. ......ldc..................
|
||||
EPTZ ...Cylinder Projection... EquiRectangularProjection...........................WM DM CM..................
|
||||
Donut.................................
|
||||
Bypass...RCS...MAP2BIN......
|
||||
.........STITCH...PERSPECTIVE......
|
||||
........................lib.......................................</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-03-01 21:42:15.73</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#ccb;'>............: [LDC] EIS..............................
|
||||
............: 1. ......LDC.......................................mjson...............
|
||||
.......................................................................................
|
||||
......claude.................................................................................UTjson.....................LDC................................................</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-02-28 21:46:52.983</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#eec;'>machine hcgit04 login ekko.bao password ve5hVjZePgMfo8YOBXeH09BzaLufKw+xBdNOq9h5Yw</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-02-25 16:51:25.16</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre style='font-size:12px;'><code style='background-color:#ccb;'>machine hcgit04 login USER_NAME password HTTP_PASSWORD
|
||||
machine hcgit04-master login USER_NAME password HTTP_PASSWORD
|
||||
machine hcgit04-sz login USER_NAME password HTTP_PASSWORD
|
||||
machine hcgit04-sh login USER_NAME password HTTP_PASSWORD</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-02-25 15:40:49.633</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre style='font-size:12px;'><code style='background-color:#eec;'>............: [LDC] EIS......... (SOC_I7)
|
||||
............: 1. .....................proc fs..............................proc fs...............
|
||||
|
||||
|
||||
http://sswiki.sigmastar.com.tw:8090/display/MI/Ekko-MI-LDC%28EIS%29-flow
|
||||
http://sswiki.sigmastar.com.tw:8090/display/MI/Ekko-mi_ldcx_procfs_parse</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-02-24 21:34:01.697</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#ccb;'>http://sswiki.sigmastar.com.tw:8090/display/MI/Ekko-create-mi-ldc-eis-demo-env</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-02-23 21:41:34.017</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#eec;'>http://sswiki.sigmastar.com.tw:8090/display/MI/Ekko-devlop_flow</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-02-21 21:40:54.953</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#ccb;'>http://sswiki.sigmastar.com.tw:8090/display/MI/Ekko-learn-fourth_week-0207-0213#Ekko-learn-fourth_week-0207-0213-CMDQ%E6%80%BB%E7%BB%93</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-02-08 21:26:28.69</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#eec;'>http://sswiki.sigmastar.com.tw:8090/display/MI/Ekko-learn-fourth_week-0207-0213</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-02-07 18:04:37.017</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#ccb;'>https://blog.csdn.net/abcwoabcwo/article/details/93099982</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-01-27 10:10:16.68</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#eec;'>http://sswiki.sigmastar.com.tw:8090/display/MI/MHAL_DIS-interface_doc</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-01-27 10:10:14.037</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#ccb;'>http://sswiki.sigmastar.com.tw:8090/display/MI/MHAL_DIS-interface_doc</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-01-26 21:51:48.77</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#eec;'>http://sswiki.sigmastar.com.tw:8090/pages/editpage.action?pageId=28944730</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-01-26 21:51:32.287</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#ccb;'>f output image height is 1512, then the height of each slice is 1512/6=252, which is close to 256 if align to 32. If you choose LdcDisSlice=7, then the height of each slice is 1512/7=216, which is not close to 256</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-01-26 11:05:20.77</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#eec;'>Set higher for more stable image but at the expense of CPU usage</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-01-26 11:04:23.627</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#ccb;'>http://sswiki.sigmastar.com.tw:8090/display/MI/MHAL_DIS-interface_doc</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-01-25 21:35:52.353</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#eec;'>http://sswiki.sigmastar.com.tw:8090/display/MI/Ekko-learn-third_week-0124-0130</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-01-25 21:35:44.177</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#ccb;'>http://sswiki.sigmastar.com.tw:8090/display/MI/Ekko-learn-third_week-0124-0130#Ekko-learn-third_week-0124-0130-%E5%A2%9E%E5%8A%A0procfs</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-01-24 21:33:03.9</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#eec;'>http://sswiki.sigmastar.com.tw:8090/display/MI/Ekko-learn-second_week-0117-0123#Ekko-learn-second_week-0117-0123-%E7%BC%96%E8%AF%91%E6%A1%86%E6%9E%B6%E8%A7%A3%E8%AF%BB</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-01-24 21:32:46.773</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#ccb;'>http://sswiki.sigmastar.com.tw:8090/display/MI/Ekko-learn-second_week-0117-0123#Ekko-learn-second_week-0117-0123-%E8%B7%9F%E8%B8%AA%EF%BC%9A</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-01-21 21:39:55.213</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#eec;'>http://sswiki.sigmastar.com.tw:8090/display/MI/Ekko-learn-second_week-0117-0123#Ekko-learn-second_week-0117-0123-2022/01/19</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-01-19 21:34:06.807</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#ccb;'>http://www.cnblogs.com/king-77024128/articles/2666230.html</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-01-19 10:12:20.44</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#eec;'>file://szswfs01/SSARTIFACTS/NONSYNC/</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-01-18 16:48:57.65</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#ccb;'>sigmastar/L3/autorelease/alkaid/sdk/docs</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-01-18 10:37:18.5</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#eec;'>http://sswiki.sigmastar.com.tw:8090/display/MI/Ekko-learn-second_week-0117-0123</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-01-17 21:40:56.903</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#ccb;'>Digital Overlap High Dynamic Range</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-01-17 18:00:31.783</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#eec;'>http://sswiki.sigmastar.com.tw:8090/display/MI/Ekko-learning-2022_01_14</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-01-14 21:01:21.743</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#ccb;'>in/map/fisheye/new_AMTK_FHD/CalibPoly_new.bin</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-01-14 10:06:00.52</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#eec;'>in/map/fisheye/new_AMTK_FHD/CalibPoly_new.bin</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-01-14 09:45:05.487</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#ccb;'>cfg/bin/TableMode/multiband/sh/dualsensor/1920x1080x2_st.bin</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-01-14 09:44:40.43</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#eec;'>http://sswiki.sigmastar.com.tw:8090/display/MI/Ekko-learning-2022_01_13</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-01-13 21:55:37.52</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre
|
||||
style='font-size:12px;'><code style='background-color:#ccb;'>boot.bin = IPL.bin + IPL_CUST.bin + u-boot </code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-01-13 21:49:28.853</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre style='font-size:12px;'><code style='background-color:#eec;'>MI LDC Training</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-01-13 16:39:14.647</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td style="text-align:left;width:80%;">
|
||||
<pre style='font-size:12px;'><code style='background-color:#ccb;'>declare -x</code></pre>
|
||||
</td>
|
||||
<td class="fixline" style="width:10%;vertical-align:middle;">2022-01-13 11:24:59.05</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
<script>
|
||||
jBPM("#copy_paste").submit(function () {
|
||||
var msg = jBPM("#message").val();
|
||||
var len = msg.replace(/[^\x00-\xff]/g, "xx").length;
|
||||
if (len > 300) {
|
||||
alert("Input text length " + len + " is more than limit characters.");
|
||||
return false;
|
||||
}
|
||||
});
|
||||
</script>
|
96
src/encrypt/mod.rs
Executable file
96
src/encrypt/mod.rs
Executable file
|
@ -0,0 +1,96 @@
|
|||
use std::error::Error;
|
||||
use std::process::Command;
|
||||
extern crate log;
|
||||
use aes::Aes128;
|
||||
use block_modes::{BlockMode, Cbc};
|
||||
use block_modes::block_padding::Pkcs7;
|
||||
use base64::{Engine as _, engine::general_purpose};
|
||||
type Aes128Cbc = Cbc<Aes128, Pkcs7>;
|
||||
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum EncryptErr {
|
||||
NotBase64,
|
||||
}
|
||||
|
||||
impl fmt::Display for EncryptErr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
EncryptErr::NotBase64 => write!(f, "String is not base64"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for EncryptErr {}
|
||||
|
||||
pub fn get_key() -> String {
|
||||
let output = Command::new("wmic")
|
||||
.args(&["DISKDRIVE", "get", "serialnumber"])
|
||||
.output()
|
||||
.expect("Failed to execute command");
|
||||
|
||||
let serial = String::from_utf8_lossy(&output.stdout)
|
||||
.lines()
|
||||
.nth(1) // 获取第二行,通常是序列号
|
||||
.unwrap()
|
||||
.trim()
|
||||
.to_string();
|
||||
log::trace!("hdd serial is {}", serial);
|
||||
serial
|
||||
}
|
||||
|
||||
pub fn is_base64(encrypted_data: &str) -> bool {
|
||||
match general_purpose::STANDARD.decode(encrypted_data) {
|
||||
Ok(_) => true,
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn encrypt(raw_data: &str, key: &str, iv:&str) -> String {
|
||||
let key = append_align(key);
|
||||
let iv = append_align(iv);
|
||||
|
||||
let cipher = Aes128Cbc::new_from_slices(&key, &iv).unwrap();
|
||||
|
||||
let pos = cipher.encrypt_vec(&raw_data.as_bytes());
|
||||
// println!("pos buff size is {} {}, {}", general_purpose::STANDARD.encode(&pos), pos.len(), data.len());
|
||||
let ret = [iv.to_vec(), pos.to_vec()].concat();// Prepend IV for decryption
|
||||
general_purpose::STANDARD.encode(ret)
|
||||
}
|
||||
|
||||
pub fn decrypt(encrypted_data: &str, key: &str) -> Result<String, Box<dyn Error>> {
|
||||
let key: Vec<u8> = append_align(key);
|
||||
let encrypted_data = general_purpose::STANDARD.decode(encrypted_data)?;
|
||||
let (iv, data) = encrypted_data.split_at(16); // First 16 bytes are IV
|
||||
|
||||
let cipher = Aes128Cbc::new_from_slices(&key, &iv)?;
|
||||
let decrypted_data = cipher.decrypt_vec(data).unwrap();
|
||||
|
||||
let result = String::from_utf8(decrypted_data)?;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
|
||||
fn append_align(uuid: &str) -> Vec<u8> {
|
||||
let mut key = uuid.as_bytes().to_vec();
|
||||
key.resize(16, b'_');
|
||||
key
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_key(){
|
||||
get_key();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_encrypt_decrypt() {
|
||||
let user_name = "ekko.bao";
|
||||
let password = "PASSWORD";
|
||||
let machine_id = get_key();
|
||||
let encrypted_data = encrypt(password,&machine_id, user_name);
|
||||
// println!("encrypted_data is {}", encrypted_data);
|
||||
let ret = decrypt(&encrypted_data, &machine_id).unwrap();
|
||||
println!("decrypt is {}", ret);
|
||||
assert_eq!(password, ret);
|
||||
}
|
364
src/lib.rs
364
src/lib.rs
|
@ -1,34 +1,136 @@
|
|||
|
||||
use log::Log;
|
||||
use percent_encoding::{percent_encode, NON_ALPHANUMERIC};
|
||||
use rand::{random, Rng};
|
||||
use reqwest::header::HeaderMap;
|
||||
use reqwest::{Client, Response};
|
||||
use scraper::{Html, Selector};
|
||||
use core::ascii;
|
||||
use std::error::Error;
|
||||
use std::io;
|
||||
use std::io::{self, Write};
|
||||
use std::time::Duration;
|
||||
use tokio::sync::Mutex;
|
||||
use std::sync::Arc;
|
||||
use tokio::{task, time};
|
||||
use std::collections::BTreeMap;
|
||||
extern crate log;
|
||||
use serde_json::{self, to_string, Value};
|
||||
use serde::Serialize;
|
||||
use std::fs::File;
|
||||
use std::io::BufReader;
|
||||
|
||||
pub mod wclip;
|
||||
pub mod sys_res;
|
||||
pub mod encrypt;
|
||||
|
||||
use sys_res::*;
|
||||
pub struct ClipboardSync {
|
||||
|
||||
#[derive(Debug, Serialize, Default)]
|
||||
pub struct Config {
|
||||
user_name: String,
|
||||
password: String,
|
||||
cookies: String,
|
||||
magic: String,
|
||||
|
||||
save_path: String,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn new(json_file: &str) -> Result<Config, Box<dyn Error>> {
|
||||
let file = File::open(json_file)?;
|
||||
let reader = BufReader::new(file);
|
||||
let json: Value = serde_json::from_reader(reader)?;
|
||||
let user_name = json.get("user_name").expect("not found user_name in info.json").as_str().unwrap().to_string();
|
||||
log::info!("user_name is {}", user_name);
|
||||
let mut password = json.get("password").expect("not found password in info.json").as_str().unwrap().to_string();
|
||||
let magic = match json.get("magic") {
|
||||
Some(magic) => magic.as_str().unwrap().to_string(),
|
||||
None => "~".to_string(),
|
||||
};
|
||||
let cookies = match json.get("cookies") {
|
||||
Some(cookies) => cookies.as_str().unwrap().to_string(),
|
||||
None => "".to_string(),
|
||||
};
|
||||
let gen_cfg = move |user_name:String, password:String|{
|
||||
let cfg = Config {
|
||||
user_name,
|
||||
password,
|
||||
cookies,
|
||||
magic,
|
||||
save_path: json_file.to_string()
|
||||
};
|
||||
cfg
|
||||
};
|
||||
drop(json);
|
||||
if encrypt::is_base64(&password) {
|
||||
let key = encrypt::get_key();
|
||||
let _ = encrypt::decrypt(&password, &key)?;
|
||||
Ok(gen_cfg(user_name, password))
|
||||
} else {
|
||||
let key = encrypt::get_key();
|
||||
password = encrypt::encrypt(&password, &key, &user_name);
|
||||
let cfg = gen_cfg(user_name, password);
|
||||
cfg.update();
|
||||
Ok(cfg)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(&self) {
|
||||
let json = serde_json::json!({
|
||||
"user_name": self.user_name,
|
||||
"password": self.password,
|
||||
"cookies": self.cookies,
|
||||
"magic": self.magic,
|
||||
});
|
||||
let json = serde_json::to_string_pretty(&json).unwrap();
|
||||
let mut f = File::options().truncate(true).write(true).create(true).open(&self.save_path).unwrap();
|
||||
let _ = f.write(json.as_bytes());
|
||||
}
|
||||
|
||||
pub fn user_name(&mut self, value: Option<&str>) -> &str {
|
||||
if let Some(value) = value {
|
||||
self.user_name = value.to_string();
|
||||
self.update();
|
||||
}
|
||||
&self.user_name
|
||||
}
|
||||
pub fn password(&mut self, value: Option<&str>) -> String {
|
||||
if let Some(value) = value {
|
||||
let key = encrypt::get_key();
|
||||
self.password = encrypt::encrypt(&value, &key, &self.user_name);
|
||||
self.update();
|
||||
}
|
||||
let key = encrypt::get_key();
|
||||
encrypt::decrypt(&self.password, &key).expect("password cant decrypt")
|
||||
}
|
||||
|
||||
pub fn cookies(&mut self, value: Option<&str>) -> &str {
|
||||
if let Some(value) = value {
|
||||
self.cookies = value.to_string();
|
||||
self.update();
|
||||
}
|
||||
&self.cookies
|
||||
}
|
||||
|
||||
pub fn magic(&mut self, value: Option<&str>) -> &str {
|
||||
if let Some(value) = value {
|
||||
self.magic = value.to_string();
|
||||
self.update();
|
||||
}
|
||||
&self.magic
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ClipboardSync {
|
||||
web: Client,
|
||||
ip: String,
|
||||
cookies: String,
|
||||
clip: wclip::Wclip,
|
||||
//last message magic
|
||||
cache_magic: String,
|
||||
cfg: Config,
|
||||
}
|
||||
|
||||
const USER_AGENT: &str = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36 Edg/106.0.1370.42";
|
||||
|
||||
fn quote(input: &String) -> String {
|
||||
fn quote(input: &str) -> String {
|
||||
percent_encode(input.as_bytes(), NON_ALPHANUMERIC).to_string()
|
||||
}
|
||||
|
||||
|
@ -36,14 +138,49 @@ pub struct ClipboardMsgs {
|
|||
pub msgs: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum MsgSyncState {
|
||||
None,
|
||||
ForceInVM,
|
||||
NeedSync,
|
||||
}
|
||||
|
||||
// 同步获取消息的线程
|
||||
async fn msg_sync(ctx:Arc<Mutex<ClipboardSync>>){
|
||||
async fn msg_sync(ctx:Arc<Mutex<ClipboardSync>>) {
|
||||
let VM_EXE_NAME = "Code.exe".to_string();
|
||||
let mut ctx = ctx.lock().await;
|
||||
let mut sta = MsgSyncState::None;
|
||||
let mut turn_time;
|
||||
//let _ = ctx.update_msg().await;
|
||||
loop{
|
||||
let _ = ctx.update_msg().await;
|
||||
time::sleep(Duration::new(10, 0)).await;
|
||||
let prog_name = get_foredround_window_name();
|
||||
if prog_name == "VMware Horizon Client"{
|
||||
log::trace!("current state is {:?}", sta);
|
||||
match sta{
|
||||
MsgSyncState::None => {
|
||||
turn_time = 200;
|
||||
let prog_name = get_foredround_window_name();
|
||||
if prog_name == VM_EXE_NAME {
|
||||
sta = MsgSyncState::ForceInVM;
|
||||
turn_time = 0;
|
||||
} else {
|
||||
log::trace!("foreground prog is [{}] {}, waiting: [{}] {}", prog_name, prog_name.len(), VM_EXE_NAME, VM_EXE_NAME.len());
|
||||
}
|
||||
},
|
||||
MsgSyncState::ForceInVM => {
|
||||
turn_time = 100;
|
||||
let prog_name = get_foredround_window_name();
|
||||
if prog_name != VM_EXE_NAME {
|
||||
turn_time = 0;
|
||||
sta = MsgSyncState::NeedSync;
|
||||
}
|
||||
},
|
||||
MsgSyncState::NeedSync => {
|
||||
turn_time = 0;
|
||||
let _ = ctx.update_msg().await;
|
||||
sta = MsgSyncState::None;
|
||||
},
|
||||
}
|
||||
if turn_time != 0 {
|
||||
time::sleep(Duration::new(0, turn_time*1000*1000)).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,26 +191,24 @@ pub async fn start_msg_sync(ctx:Arc<Mutex<ClipboardSync>>) -> Result<task::JoinH
|
|||
|
||||
enum Msg <'a>{
|
||||
// magic str, message context
|
||||
Msg((String, &'a str)),
|
||||
Msg(&'a str),
|
||||
//index of message pack, total message pack number, magic str, message context
|
||||
Sub((u8, u8, String, &'a str)),
|
||||
}
|
||||
|
||||
impl ClipboardSync {
|
||||
pub fn new(ip: &str, user_name: &str, password: &str) -> ClipboardSync {
|
||||
ClipboardSync {
|
||||
user_name: user_name.to_string(),
|
||||
password: password.to_string(),
|
||||
pub fn new(ip: &str, info_file:&str) -> Result<ClipboardSync, Box<dyn Error>> {
|
||||
let cfg = Config::new(info_file)?;
|
||||
Ok(ClipboardSync {
|
||||
web: Client::new(),
|
||||
ip: ip.to_string(),
|
||||
cookies: "".to_string(),
|
||||
clip: wclip::Wclip::new(),
|
||||
cache_magic: "0xff".to_string(),
|
||||
}
|
||||
cfg,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
async fn verify(&self) -> Result<Response, Box<dyn Error>> {
|
||||
async fn verify(&mut self) -> Result<Response, Box<dyn Error>> {
|
||||
// 开始验证
|
||||
let security_check_url = format!("http://{}/SSWeb/rd/j_security_check", self.ip);
|
||||
let mut headers = HeaderMap::new();
|
||||
|
@ -100,11 +235,11 @@ impl ClipboardSync {
|
|||
.parse()
|
||||
.unwrap(),
|
||||
);
|
||||
headers.insert("Cookie", self.cookies.parse().unwrap());
|
||||
headers.insert("Cookie", self.cfg.cookies(None).parse().unwrap());
|
||||
let contents = format!(
|
||||
"j_username={}&j_password={}",
|
||||
quote(&self.user_name),
|
||||
quote(&self.password)
|
||||
quote(self.cfg.user_name(None)),
|
||||
quote(&self.cfg.password(None))
|
||||
);
|
||||
let resp = self
|
||||
.web
|
||||
|
@ -124,7 +259,7 @@ impl ClipboardSync {
|
|||
session = value.split(';').next().unwrap().to_string();
|
||||
}
|
||||
} else {
|
||||
log::error!("cookies not found");
|
||||
log::warn!("cookies not found");
|
||||
}
|
||||
session
|
||||
}
|
||||
|
@ -132,9 +267,10 @@ impl ClipboardSync {
|
|||
let mut headers = HeaderMap::new();
|
||||
headers.insert("User-Agent", USER_AGENT.parse().unwrap());
|
||||
let url = format!("http://{}/SSWeb/rd/copy_paste.jsp", self.ip);
|
||||
|
||||
let response = self.web.get(url).headers(headers).send().await?;
|
||||
self.cookies = ClipboardSync::get_cookies(&response);
|
||||
log::info!("cookies is {}", self.cookies);
|
||||
self.cfg.cookies(Some(&ClipboardSync::get_cookies(&response)));
|
||||
log::info!("cookies is [{}]", self.cfg.cookies(None));
|
||||
let mut resp = response.text().await?;
|
||||
log::trace!("Response: {}", resp);
|
||||
if resp.contains("loginForm") {
|
||||
|
@ -149,7 +285,7 @@ impl ClipboardSync {
|
|||
}
|
||||
}
|
||||
|
||||
pub async fn update_msg(&mut self) -> Result<(), Box<dyn Error>> {
|
||||
pub async fn get_newest_msg(&mut self) -> Result<String, Box<dyn Error>> {
|
||||
//http://ssweb/SSWeb/rd/copy_paste.jsp?d-16544-p=1&d-16544-s=2
|
||||
//d-16544-s 2:时间从靠近现在开始排序 1:时间从最早开始排序
|
||||
//d-16544-o mesage排序,不要设置
|
||||
|
@ -167,6 +303,11 @@ impl ClipboardSync {
|
|||
headers.insert("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6".parse().unwrap());
|
||||
let response = self.web.get(url).headers(headers).send().await?;
|
||||
let resp = response.text().await?;
|
||||
Ok(resp)
|
||||
}
|
||||
|
||||
pub async fn update_msg(&mut self) -> Result<(), Box<dyn Error>> {
|
||||
let resp = self.get_newest_msg().await?;
|
||||
self.msg2clip(&resp).await;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -174,23 +315,21 @@ impl ClipboardSync {
|
|||
//解析可能存在的消息数据
|
||||
fn parse_msg<'a>(msg: &'a str) -> Msg {
|
||||
//x|x|x| -> index|total|magic|
|
||||
let head = &msg[0..7];
|
||||
let body = &msg[7..];
|
||||
let check = head.split('|').filter(|text| {
|
||||
let text = text.as_bytes();
|
||||
let bmsg = msg.as_bytes();
|
||||
let head = &bmsg[0..7];
|
||||
let check = head.split(|c| *c == b'|').filter(|text| {
|
||||
if text.len() == 1 {
|
||||
if text[0] >= b'!' && text[0] < b'|' {true} else {false}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}).map(|x|x.as_bytes()[0] - b'!').collect::<Vec<_>>();
|
||||
}).map(|x|x[0] - b'!').collect::<Vec<_>>();
|
||||
|
||||
if check.len() != 3 {
|
||||
//TODO: get magic
|
||||
return Msg::Msg(("maigic".to_string(), msg))
|
||||
return Msg::Msg(msg)
|
||||
}
|
||||
|
||||
return Msg::Sub((check[0], check[1], check[2].to_string(), body));
|
||||
return Msg::Sub((check[0], check[1], check[2].to_string(), &msg[7..]));
|
||||
}
|
||||
|
||||
//将message解析并放置到剪切板上
|
||||
|
@ -199,19 +338,27 @@ impl ClipboardSync {
|
|||
let document = Html::parse_document(html);
|
||||
// 所有剪切板的数据都是在code这个html lable上的
|
||||
let selector = Selector::parse("code").unwrap();
|
||||
//对于单个消息我们希望发送的时间作为magic,所以这里通过构建一个date selector获得
|
||||
let date_selector = Selector::parse("td.fixline").unwrap();
|
||||
let mut msg_map = BTreeMap::new();
|
||||
let mut magic_ref = "0xff".to_string();
|
||||
let mut is_first = true;
|
||||
let mut msg_index = 0;
|
||||
for element in document.select(&selector).into_iter() {
|
||||
//let text = element.text().collect::<Vec<_>>().concat();
|
||||
let text = element.text().collect::<String>();
|
||||
log::info!("Found: [{}]", text);
|
||||
log::trace!("Found: [{}]", text);
|
||||
let msg = ClipboardSync::parse_msg(text.as_str());
|
||||
match msg {
|
||||
//一整个消息。直接复制到剪切板即可
|
||||
//一整个完整的消息。直接复制到剪切板即可
|
||||
Msg::Msg(msg) => {
|
||||
if magic_ref == "0xff" {
|
||||
self.clip.set(msg.1);
|
||||
// 因为每个date和str都是对应的所以这里直接获取指定位置的date作为magic
|
||||
let magic = document.select(&date_selector).into_iter().nth(msg_index).unwrap().text().collect::<String>();
|
||||
if self.cfg.magic(None) != magic {
|
||||
self.clip.set(msg);
|
||||
self.cfg.magic(Some(&magic));
|
||||
log::info!("magic is {}, msg is {}", self.cfg.magic(None), msg);
|
||||
}
|
||||
break;//处理完毕。直接退出
|
||||
}
|
||||
},
|
||||
|
@ -220,13 +367,13 @@ impl ClipboardSync {
|
|||
magic_ref = magic;
|
||||
} else {
|
||||
if magic_ref != magic { // other message ignore
|
||||
is_first = false;
|
||||
msg_index += 1;
|
||||
continue
|
||||
}
|
||||
}
|
||||
if msg_map.len() == 0 && (
|
||||
self.cache_magic == magic_ref // message is repeated ignore it
|
||||
|| !is_first // we only process the newest msg
|
||||
self.cfg.magic(None) == magic_ref // message is repeated ignore it
|
||||
|| (msg_index != 0) // we only process the newest msg
|
||||
) {
|
||||
break;
|
||||
}
|
||||
|
@ -234,13 +381,140 @@ impl ClipboardSync {
|
|||
msg_map.insert(index, body.to_string());
|
||||
if msg_map.len() as u8 == total {
|
||||
let msg = msg_map.into_iter().map(|(_key, v)| v).collect::<String>();
|
||||
self.cache_magic = magic_ref; // save for next msg
|
||||
self.clip.set(&msg);
|
||||
if self.cfg.magic(None) != magic_ref {
|
||||
log::info!("magic is {}, msg is {}", self.cfg.magic(None), msg);
|
||||
self.clip.set(&msg);
|
||||
self.cfg.magic(Some(&magic_ref)); // save for next msg
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
is_first = false;
|
||||
msg_index += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn send_msg(&mut self, msg: &str) -> Result<(), Box<dyn Error>> {
|
||||
let url = format!("http://{}/SSWeb/rd/copy_paste.jsp?send=y", self.ip);
|
||||
let mut headers = HeaderMap::new();
|
||||
headers.insert("Host", "ssweb".parse().unwrap());
|
||||
headers.insert("Connection", "keep-alive".parse().unwrap());
|
||||
headers.insert("Cache-Control", "max-age=0".parse().unwrap());
|
||||
headers.insert("Origin", "http://ssweb".parse().unwrap());
|
||||
headers.insert("DNT", "1".parse().unwrap());
|
||||
headers.insert("Upgrade-Insecure-Requests", "1".parse().unwrap());
|
||||
headers.insert("Content-Type", "application/x-www-form-urlencoded".parse().unwrap());
|
||||
headers.insert("User-Agent", USER_AGENT.parse().unwrap());
|
||||
headers.insert("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9".parse().unwrap());
|
||||
headers.insert("Referer", "http://ssweb/SSWeb/rd/copy_paste.jsp?d-16544-p=1&d-16544-s=2".parse().unwrap());
|
||||
headers.insert("Accept-Encoding", "gzip, deflate".parse().unwrap());
|
||||
headers.insert("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6".parse().unwrap());
|
||||
headers.insert("Cookie", format!("{}", self.cfg.cookies(None)).parse().unwrap());
|
||||
|
||||
let contents = format!("message={}", msg);
|
||||
let _ = self.web.post(url).headers(headers).body(contents).send().await?;
|
||||
// let resp = response.text().await?;
|
||||
// Ok(resp)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn split_msg(&mut self, msg: &str) -> Result<Vec<String>, i32> {
|
||||
let mut start = 0;
|
||||
let mut msgs = Vec::new();
|
||||
let mut cur = 0;
|
||||
for c in msg.chars() {
|
||||
let byte_count = c.len_utf8();
|
||||
if cur - start + byte_count + 7 >= 300 {
|
||||
//超过限额300个字符,构造一个消息进行发送
|
||||
msgs.push(&msg[start..cur]);
|
||||
start = cur;
|
||||
if msgs.len() > b'|' as usize - b'!' as usize {
|
||||
log::warn!("msg is too long, ignore it");
|
||||
return Err(-1);
|
||||
}
|
||||
}
|
||||
cur += byte_count;
|
||||
}
|
||||
//如果拆包了的话。那么要把最后一点点数据打包一下,不然会丢msg
|
||||
if msgs.len() > 0 && cur != start {
|
||||
msgs.push(&msg[start..cur]);
|
||||
}
|
||||
fn gen_magic(cache: char) -> char {
|
||||
let mut rng = rand::thread_rng();
|
||||
// ASCII 范围从 '!' (33) 到 '|' (124)
|
||||
let start = b'!' as u8;
|
||||
let end = b'|' as u8;
|
||||
let mut ret = cache;
|
||||
//随机生成一个和上次不一样的值即可
|
||||
while ret == cache {
|
||||
ret = rng.gen_range(start..end) as char;
|
||||
}
|
||||
ret
|
||||
}
|
||||
let mut ret = Vec::new();
|
||||
let total = msgs.len() as u32;
|
||||
if total > 0 { //大消息切片为多个小消息
|
||||
let magic = gen_magic(self.cfg.magic(None).chars().next().unwrap());
|
||||
for index in 0..total {
|
||||
//x|x|x| -> index|total|magic|
|
||||
let msg = format!("{}|{}|{}", char::from_u32(b'0' as u32 + index).unwrap(),
|
||||
char::from_u32(b'0' as u32 + total).unwrap(), magic);
|
||||
ret.push(msg + msgs[index as usize]);
|
||||
}
|
||||
self.cfg.magic(Some(&magic.to_string()));
|
||||
} else { //单个消息
|
||||
ret.push(msg.to_string());
|
||||
}
|
||||
Ok(ret)
|
||||
}
|
||||
pub async fn clip2msg(&mut self) {
|
||||
let msg = match self.clip.get() {
|
||||
Some(msg) => match self.split_msg(&msg).await {
|
||||
Ok(msgs) => msgs,
|
||||
Err(_) => return,
|
||||
},
|
||||
None => return,
|
||||
};
|
||||
//遍历所有分包并进行发送
|
||||
for item in msg {
|
||||
let _ = self.send_msg(&item).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_message2clip()
|
||||
{
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
let mut ins = ClipboardSync::new("127.0.0.1", "info.json").unwrap();
|
||||
let mut html = String::new();
|
||||
File::open("message.html").unwrap().read_to_string(&mut html).unwrap();
|
||||
ins.msg2clip(&html).await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_start_msg_sync()
|
||||
{
|
||||
let ins = ClipboardSync::new("127.0.0.1:5000", "info.json").unwrap();
|
||||
let ctx = Arc::new(Mutex::new(ins));
|
||||
let handle = start_msg_sync(ctx.clone()).await.unwrap();
|
||||
time::sleep(Duration::new(10, 0)).await;
|
||||
handle.abort();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_split_msg() {
|
||||
let mut ins = ClipboardSync::new("127.0.0.1:5000", "info.json").unwrap();
|
||||
let raw_msg = "在这个快速发展的世界中,technology is evolving at an unprecedented rate! 我们需要不断学习和适应新的变化。#创新@未来$梦想%实现^挑战&机遇*合作+成长=成功~体验|分享<知识>探索{可能性}。Let's work together to create a better tomorrow! 生活充满了各种可能性,我们要勇敢面对每一个挑战。1234567890!@#$%^&*()_+-=<>?[]{},.。;:‘’“”()【】《》——";
|
||||
let msgs = ins.split_msg(raw_msg).await.unwrap();
|
||||
println!("{:?}", msgs);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_send_send_msg() {
|
||||
let mut ins = ClipboardSync::new("127.0.0.1:5000", "info.json").unwrap();
|
||||
let raw_msg = "在这个快速发展的世界中,technology is evolving at an unprecedented rate! 我们需要不断学习和适应新的变化。#创新@未来$梦想%实现^挑战&机遇*合作+成长=成功~体验|分享<知识>探索{可能性}。Let's work together to create a better tomorrow! 生活充满了各种可能性,我们要勇敢面对每一个挑战。1234567890!@#$%^&*()_+-=<>?[]{},.。;:‘’“”()【】《》——";
|
||||
ins.clip.set(&raw_msg);
|
||||
ins.clip2msg().await;
|
||||
}
|
99
src/main.rs
99
src/main.rs
|
@ -7,6 +7,83 @@ use trust_dns_resolver::{
|
|||
};
|
||||
use tokio::sync::{Mutex};
|
||||
use std::sync::Arc;
|
||||
use clap::{App, Arg, ArgGroup};
|
||||
|
||||
// const SERVER:&str = "172.19.36.79";
|
||||
const SERVER:&str = "127.0.0.1:5000";
|
||||
|
||||
enum Character {
|
||||
Producer,
|
||||
Consumer,
|
||||
}
|
||||
|
||||
fn param_parser() -> (Character, String) {
|
||||
let mut character = Character::Consumer;
|
||||
let matches = App::new("sstar_clipboard_sync")
|
||||
.version("1.0")
|
||||
.author("Ekko.bao")
|
||||
.about("sstar clipboard sync")
|
||||
.arg(
|
||||
Arg::with_name("producer")
|
||||
.short('p')
|
||||
.long("producer")
|
||||
.conflicts_with("consumer")
|
||||
.help("Data producer")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("consumer")
|
||||
.short('c')
|
||||
.long("consumer")
|
||||
.conflicts_with("producer")
|
||||
.help("Data consumer")
|
||||
)
|
||||
.group(clap::ArgGroup::new("Character")
|
||||
.args(&["consumer", "producer"])
|
||||
.required(true)
|
||||
.multiple(false))
|
||||
.arg(
|
||||
Arg::with_name("info")
|
||||
.short('i')
|
||||
.long("info")
|
||||
.value_name("info")
|
||||
.default_value("info.json")
|
||||
.help("The file of running info")
|
||||
)
|
||||
.get_matches();
|
||||
character = if matches.is_present("producer") {
|
||||
Character::Producer
|
||||
} else if matches.is_present("consumer") {
|
||||
Character::Consumer
|
||||
} else {
|
||||
character
|
||||
};
|
||||
let info_file = matches.value_of("info").unwrap();
|
||||
(character, info_file.to_string())
|
||||
}
|
||||
|
||||
async fn producer(info: &str) {
|
||||
let mut ins: ClipboardSync = match ClipboardSync::new(SERVER, &info) {
|
||||
Ok(ins) => ins,
|
||||
Err(e) => {
|
||||
log::error!("create syns instance fail: {}", e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
match ins.login().await {
|
||||
Ok(()) => log::info!("login success"),
|
||||
Err(e) => {
|
||||
log::error!("login fail: {}", e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
let ctx = Arc::new(Mutex::new(ins));
|
||||
let handle = clipboard_sync::start_msg_sync(ctx.clone()).await.unwrap();
|
||||
let _ = handle.await;
|
||||
}
|
||||
|
||||
async fn consumer(_info: &str) {
|
||||
log::warn!("TODO: support Producer in the feature")
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
@ -29,22 +106,14 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
// println!("Error: {}", e);
|
||||
// }
|
||||
// }
|
||||
|
||||
let mut ins = ClipboardSync::new("172.19.36.79", "ekko.bao", "qwer12345;");
|
||||
match ins.login().await {
|
||||
Ok(()) => log::info!("登录成功"),
|
||||
Err(e) => {
|
||||
log::error!("登录失败: {}", e);
|
||||
let (character, info) = param_parser();
|
||||
match character{
|
||||
Character::Producer => {
|
||||
producer(&info).await;
|
||||
}
|
||||
Character::Consumer => {
|
||||
consumer(&info).await;
|
||||
}
|
||||
}
|
||||
let ctx = Arc::new(Mutex::new(ins));
|
||||
let handle = clipboard_sync::start_msg_sync(ctx.clone()).await.unwrap();
|
||||
let _ = handle.await;
|
||||
// 获取 Cookies
|
||||
//if let Some(cookies) = response.headers().get(COOKIE) {
|
||||
// println!("Cookies: {:?}", cookies);
|
||||
//} else {
|
||||
// println!("No cookies found.");
|
||||
//}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
extern crate winapi;
|
||||
extern crate log;
|
||||
use std::path::Path;
|
||||
use winapi::um::winuser::{
|
||||
GetCursorPos, GetSystemMetrics, SM_CXSCREEN, SM_CYSCREEN,GetWindowRect
|
||||
};
|
||||
|
@ -9,8 +8,6 @@ use winapi::shared::windef::{
|
|||
RECT,
|
||||
};
|
||||
use winapi::um::winuser::{GetForegroundWindow, GetWindowThreadProcessId};
|
||||
use std::ffi::OsString;
|
||||
use std::os::windows::ffi::OsStringExt;
|
||||
use winapi::um::processthreadsapi::OpenProcess;
|
||||
use winapi::um::winnt::PROCESS_QUERY_INFORMATION;
|
||||
use winapi::um::psapi::GetProcessImageFileNameW;
|
||||
|
@ -42,15 +39,14 @@ pub fn get_foredround_window_rect() -> Option<(i32, i32, i32, i32)> {
|
|||
println!("GetWindowRect: {:?}", rect);
|
||||
Some((rect.left, rect.top, rect.right, rect.bottom))
|
||||
} else {
|
||||
println!("cant get foregtound window rect");
|
||||
log::error!("cant get foregtound window rect");
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn get_foredround_window_name() -> String {
|
||||
let mut name = OsString::new();
|
||||
let mut name = String::new();
|
||||
unsafe {
|
||||
let foreground_window = GetForegroundWindow();
|
||||
|
||||
|
@ -62,24 +58,26 @@ pub fn get_foredround_window_name() -> String {
|
|||
|
||||
let process_handle = OpenProcess(PROCESS_QUERY_INFORMATION, 0, process_id);
|
||||
if process_handle.is_null() {
|
||||
panic!("Cant open foreground process with {}!", process_id)
|
||||
log::error!("Cant open foreground process with {}!", process_id);
|
||||
return "".to_string();
|
||||
}
|
||||
|
||||
let mut image_name = [0u16; 1024];
|
||||
if GetProcessImageFileNameW(process_handle, image_name.as_mut_ptr() as *mut _, image_name.len() as u32) == 0 {
|
||||
panic!("Cant Get foreground prog name!")
|
||||
log::error!("Cant Get foreground prog name!");
|
||||
return "".to_string();
|
||||
}
|
||||
|
||||
// let mut class_name: [u16; 256] = [0; 256];
|
||||
// GetClassNameW(foreground_window, class_name.as_mut_ptr(), 256);
|
||||
|
||||
name = OsString::from_wide(&image_name);
|
||||
name = String::from_utf16_lossy(&image_name);
|
||||
// let mut class_name_str = OsString::from_wide(&class_name);
|
||||
// log::info!("Class Name: {}", class_name_str.to_string_lossy().to_string());
|
||||
}
|
||||
let path = Path::new(&name);
|
||||
let name = path.file_name().unwrap().to_string_lossy().to_string();
|
||||
println!("Current Proc Name: [{}]", name);
|
||||
let name = name.split('\\').last().unwrap().trim_end_matches('\0').to_string();
|
||||
//let name = path.file_name().unwrap().to_string_lossy().to_string();
|
||||
// println!("Current Proc Name: [{}]", name);
|
||||
name
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user