Compare commits

..

7 Commits

Author SHA1 Message Date
MacDev
2d8baf6fce refactor(SwitchBundle): 重构h5子游戏拆分上传工具 2026-09-21 20:05:29 +08:00
WajeDev
7680b32a4b 书签 2026-06-18 16:14:55 +08:00
WajeDev
b32079c2a2 init 2026-06-18 16:10:43 +08:00
WajeDev
9b5bcc7410 some files 2026-06-18 15:11:23 +08:00
WajeDev
8c8cdab58b back up bj 2026-06-18 15:09:04 +08:00
WajeDev
04497b0435 new domain and key 2026-06-12 16:04:24 +08:00
WajeDev
816c9e1f9d etcpack 2026-06-12 12:14:26 +08:00
33 changed files with 515 additions and 218 deletions

BIN
backup/.aws.zip Normal file

Binary file not shown.

BIN
backup/.sgp_04_23.zip Normal file

Binary file not shown.

BIN
backup/.sgp_0603.zip Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
backup/apkTools.zip Normal file

Binary file not shown.

BIN
backup/bj-Screenshots.7z Normal file

Binary file not shown.

BIN
backup/bjdev-ssh.zip Normal file

Binary file not shown.

View File

@@ -0,0 +1,18 @@
<!DOCTYPE NETSCAPE-Bookmark-file-1>
<!-- This is an automatically generated file.
It will be read and overwritten.
DO NOT EDIT! -->
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
<TITLE>Bookmarks</TITLE>
<H1>Bookmarks</H1>
<DL><p>
<DT><H3 ADD_DATE="1781347875" LAST_MODIFIED="1780466623" PERSONAL_TOOLBAR_FOLDER="true">书签栏</H3>
<DL><p>
<DT><A HREF="https://test.waje-special.com:8443/user/info" ADD_DATE="1776756668">GM-dev</A>
<DT><A HREF="devtools://devtools/bundled/js_app.html?v8only=true&ws=10.101.0.172:6086/00010002-0003-4004-8005-000600070008" ADD_DATE="1776757337">DevTools</A>
<DT><A HREF="https://jenkins.wgame2025.com/" ADD_DATE="1777018929" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADJklEQVR4nGxS3UtTYRh/ztc+jtucm7U5m9s0tmkpgVFISRpFXURfFwWBgRWB4GUYRRdd9B/oXRfVhZhFkKVliHSj5sc0/Goo6rbcl+7jnM257Ww75/ROmLjwgffl5eX5Pc/v93seEg4Jq8FaXqZXviAIsDfW2xoxnJBhGLCBULh7wrHY7fV6U4Vc8n9w2717vQqavqEplUFn+21aIScxEAUQBEEx89v5LBqNXdXpdFdmZ2ez+XziIPjRg4cfLCbzXaWMj3R13NGQQhoT+SwI6KALDLoyWWNDbdXE9HzDumezP4/BC+DW5uYLHpfrltfnE69dalLluCR8/D4JYzPOIoa+YIiQSakWe2WltohBrc0+2NJ6UR8KR7BTVoNYqqRJhVwCDbVmEEURMGRCPkyVR+Fy82l5OJYI/JpbmtxnoFarS/2BAGIq7JgMZVIJiYPFqAOCkoPbF97LWXP5AVWCP2teyAmirUgCG90mKzVUKpPeyUTZRLrwP7/shKGR8b13KMrCxPQipFK7IJVS9MEC2JWWsyqMT8tbz9hxpUJOFQqctJrRNG7uvZsa61D3TThhs+SJhA6OUfRs+gPPO+8ep0iiDA6JCJOAMMMAiZaD4zLgDYQcRSaaDMf+fhkZazJVVan15ap9IFoimFtYheGf05BMcuDfCiMvfOGB0amnLMsm9j3o//ptYM65cWc7EsshGMTiu3v/+W6OhRWoMRtApaKh4/51mHeur7nd7mCRiflwuVyOT4OjLCktAZzAYWrOCRKKgLbbl8FWY4STSPvrvh+M0x0KFjD7EiwWi6nCWDPOZIkKv9efsVcbcEEU8Z43A5DjcwmkOdjz9nPKMb9RIjVa60pLaG1oyz+c3w7caq17JdMc6SyvP6/MZjjQZJnouQYrtdXXC7U4cCNclsf12u0L8WR1VhQl747VUwIbTUbci8dJ1LleZbY/kVdUU7FwAM1DhCSA5v3EMrSTRPAshetNFBnvZXb1DM+naQlJCjkeeZNY8Xg8WyTSvaQ22uMCn9PmwQfdX8UkcZpLJoaUWubxy65TXn8wOuL05ISFRSnPcesoTfgHAAD//1rfB0MAAAAGSURBVAMAg5JfV381m+kAAAAASUVORK5CYII=">Jenkins</A>
<DT><A HREF="https://ksg964l11fam.sg.larksuite.com/wiki/YtjqwNfDniTZ4okRC4bl9W79gO6?sheet=3IwNVv&table=tblQL121XoBMDalX&view=vewxboiv07" ADD_DATE="1779173794" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACiklEQVR4nGxTy0uUURT/nXu/mXHGGR/jgyRrI1SroJf5GCNNKkU3iQUF0aKCVkHQslV/RJuINrZIkggptcRIUXuQ0CZcuAnFLEYxRz/HmXtv536fj5nBw8f9uOeee36/8zv3OLA2dt45Gw5HksveDhXIt6T1xQF3Vakfl0bWc8/ILidHO7qdoHyut7QGDBGIcoMMyHiRZDaMxkAq5DyaTbxZs2eOXYRAiKSI2zghJCQJFJoxBsqoikB58H5sOX0EL9GNXmgvgTZGk9JGaOj1zAa52iV7QWwTUQwbkkHEZFRnVtJGBEXHifjl+hkamvIZcKjFTakUNVWeokTFGQqKADZV2ksQcSKYTc2Z1wvDJA2zE6QFoda/u20WLaXW0V7dgraqZsy7v3GhOoFzlQ1YdJdw6/BV6qntxGrmH4MJYlJqV4OdGuF9Gv0Lg3g4fQ/R5ghctYkH03chGp/hWKyO0jpjckXeTUDsEyyevdBV045YSx9aq5qscChpeYFEZT0mk988gS2WLbuAwR4Ts7PJ6zd5ID7Ynt/TgMW3zffULguWYGTpE+6MX8d7/g8ujuL2+A3+f0CRLOJInQewx4DdIVb+59qcuXmoh1TjU3TWtEHx2zINT9Bb24Wp5e/e06McCl4CLksqzl0aKDGv5t8S122ORuto9M8ExwscDB/A2N9JTCS/IiqLmWkBA53FvGRVDJksL+j7NUBptWUkN8zA18SihkXYFMsi20Fjy/YT8NlM/9CX0/HOd4F4qCO7uoVypyyP5o7xNdJckmQ0Fk34Cch2H2ptwrkWXUk/JiGuZLWKWC8fFQyV5c6vXGmhFdJ+dwrs+PDF4nCplHa09xtra3a0P7vuBlo/Zv8DAAD//9oe8JgAAAAGSURBVAMAcKAbn82j090AAAAASUVORK5CYII=">app版本</A>
<DT><A HREF="https://jira.wgame2025.com/browse/WAJE-269?filter=10101" ADD_DATE="1779765803" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABdklEQVR4nIxTQVICMRDsJJTlcT16El/ginhWf4A/gIMUN+UF6gvQG8JBfIH8AO4C7g/gZOlJjmpB4mQ26wZ3S5yqrSQzPb2TnkkBf9lB/Z3XpdxH1J7lQcTKqVS/IE+L3D0sP5tQGwnBLgr6HAY2fo1R5ypJkcg1EyDqzTlRmvjvRgRxSOzkV1BuHGPUHvK6+IiY4LclmMOzEE/dKCUIG0UoPaUdJYk+xnc1hNUAhc2Q4wvMuIpyvUXXqJCnCCFPLJnwBJtygMs0NSIKYj3sGU1IGcHogUPPMe5srWog8JDuRQvKDGkX8adln5IfPextVsTF141LsBZAi3sS8ZQ/xcmBi80cFqkGiVlxtBh44IQw/MHYrjgBswT5JKlZbSbdnu9SGdDL5BXbpTfSobIumQtCnikqnTvhI8VeHjRLYGdCi2fq89EKiR1jO0hrCZS5dBlV5+mnJPQe1hLApHfXakhtbHrByj8IvH7b8eVnzEMVm72iZ98AAAD//x6gYOcAAAAGSURBVAMAppSQxic+0AQAAAAASUVORK5CYII=">jira</A>
<DT><A HREF="https://www.figma.com/design/Hj3HAzj1sevpK88AxAH9xz/Waje-New?node-id=2-2&m=dev" ADD_DATE="1780466623" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACfUlEQVR4nHRSvU8UURCfmbe37B7cct4RBYxKDImJMTbIJTZWKlBg4p9gYoyEaKeJ3VkaS2IidhYmfnVAogUdFYHGWJnYWEgEA3t73LK3H2+Y3fvIQeBt9r15781v5vd+MwacMHim5Oy27dL4TPccFz54x30xA8gqBu9ND4+ZudyiRphgllMycGDsFqBhMOh0jxsQJvO48P53B0PdrHJNAs5bdFfuygqhbCCWUGEJkMqSqgy2PQWK3qS+HRy1aTBMgCVm5SDkUJIlkQaO07zyZTNjAkEQis8kzM5aGaYTIKUDmxDIsm6bZBLEoORHjgmVIiFLqCMlDMwE5RlLSwG3n089Ymgn+POg0Qw+RlTUERahSUWAwHchiWv7fU4InvdF/foxl/p2cEYLzNn8QrF52YKhAWoQkkYjgp3Va3/vr45feM2aKtvKcjxfnFewi+kyqIqgV4vJu+E83G5yP0VQAB8KuZWLV165g/mbHlk8eAamRm1+C1U+KqJE4hERkVlN1kMIiVhjoqGZZ8cgXTHqEBooysoqeW/ASCo4ck8Axi0RkZHXC31gkiilkGCggS5o2oQimOKk0JEVYR22UsH5qIhVQF38iQ/r+/DJt8PYt5twYDWjETeai+vwWfpqW9fgawI4D1XUrSK2SyGblir/H5/HnbOLg17/NAkJAXl7ledDched+879/6awASe1chbgZRXz9+gbDjl3ol03lvZVHEdeGI9egolHnvQCA7doZ3ZvGbPsG2CnnchuI1JaIWqSDjQgzHlxF9ADPFYFCbEMgSZag4KVywI6fUojr8H1Z37G8JRB7SeIilUdRPFTXWusyD5k118OCJ+0O+bUcQgAAP//N3B/bwAAAAZJREFUAwBYKhHkeb+KZAAAAABJRU5ErkJggg==">Waje – Figma</A>
</DL><p>
</DL><p>

26
backup/build.bat Normal file
View File

@@ -0,0 +1,26 @@
::D:\CocosDashboard_1.1.1\resources\.editors\Creator\2.4.8\CocosCreator.exe
::D:\Git\Whot\WhotClient\build\jsb-default\frameworks\runtime-src\proj.android-studio\app
@set PROJ=D:\Git\Whot\WhotClient
@set VER=1.0.0
@set CODE=120230705
cd /d %PROJ%
node tools/setEtc1.js
D:\CocosDashboard_1.1.1\resources\.editors\Creator\2.4.8\CocosCreator.exe --path .\ --build "platform=android;buildPath=.\build;debug=false;md5Cache=false;optimizeHotUpdate=false;useDebugKeystore=true;orientation={'landscapeLeft': true};template=default;apiLevel=android-31;encryptJs=true;xxteaKey=2480c0d5-16e0-45;appABIs=['armeabi-v7a','arm64-v8a'];packageName=com.hfhy.waje.special;"
@set ASPROJ=%PROJ%\build\jsb-default\frameworks\runtime-src\proj.android-studio\app
@set APKDIR=D:\share\publish\android\whot\release\%VER%
mkdir %APKDIR%
cd /d %ASPROJ%
call D:\Gradle\gradle-6.7.1\bin\gradle assemblespecialRelease -PVERSION_NAME=%VER% -PVERSION_CODE=%CODE%
call D:\Gradle\gradle-6.7.1\bin\gradle bundlespecialRelease -PVERSION_NAME=%VER% -PVERSION_CODE=%CODE%
move %ASPROJ%\build\outputs\apk\special\release\whotClient-special-release.apk %APKDIR%\special_release_v%VER%.apk
move %ASPROJ%\build\outputs\bundle\specialRelease\whotClient-special-release.aab %APKDIR%\special_release_v%VER%.aab
::xcopy /y /k /e /c %APKDIR%\lubo_release_v%VER%.apk G:\
::xcopy /y /k /e /c %APKDIR%\whot_release_v%VER%.aab G:\
pause

5
backup/buildT.cmd Normal file
View File

@@ -0,0 +1,5 @@
set JAVA_HOME=D:\Program Files\Java\jdk-17
cd /d E:\Git\S\D\whot\WhotClient\build\jsb-default\frameworks\runtime-src\proj.android-studio\app
call D:\Gradle\gradle-8.13\bin\gradle clean
call D:\Gradle\gradle-8.13\bin\gradle assemblewajebetDebug -PVERSION_NAME=2.10.45 -PVERSION_CODE=120240125
pause

28
backup/build_pure.bat Normal file
View File

@@ -0,0 +1,28 @@
::D:\CocosDashboard_1.1.1\resources\.editors\Creator\2.4.8\CocosCreator.exe
::D:\Git\Whot\WhotClient\build\jsb-default\frameworks\runtime-src\proj.android-studio\app
@set PROJ=D:\Git\Whot\WhotClient
@set VER=1.0.0
@set CODE=120230705
@set PackType=special
cd /d %PROJ%
node tools/setEtc1.js
D:\CocosDashboard_1.1.1\resources\.editors\Creator\2.4.8\CocosCreator.exe --path .\ --build "platform=android;buildPath=.\build;debug=false;md5Cache=false;optimizeHotUpdate=false;useDebugKeystore=true;orientation={'landscapeLeft': true};template=default;apiLevel=android-31;encryptJs=true;xxteaKey=2480c0d5-16e0-45;appABIs=['armeabi-v7a','arm64-v8a'];packageName=com.hfhy.waje.special"
@set ASPROJ=%PROJ%\build\jsb-default\frameworks\runtime-src\proj.android-studio\app
@set APKDIR=D:\share\publish\android\whot\release\%VER%
mkdir %APKDIR%
cd /d %ASPROJ%
call D:\Gradle\gradle-6.7.1\bin\gradle clean
call D:\Gradle\gradle-6.7.1\bin\gradle assemble%PackType%Release -PVERSION_NAME=%VER% -PVERSION_CODE=%CODE%
call D:\Gradle\gradle-6.7.1\bin\gradle bundle%PackType%Release -PVERSION_NAME=%VER% -PVERSION_CODE=%CODE%
move %ASPROJ%\build\outputs\apk\%PackType%\release\whotClient-%PackType%-release.apk %APKDIR%\%PackType%_release_v%VER%.apk
move %ASPROJ%\build\outputs\bundle\%PackType%Release\whotClient-%PackType%-release.aab %APKDIR%\%PackType%_release_v%VER%.aab
::xcopy /y /k /e /c %APKDIR%\lubo_release_v%VER%.apk G:\
::xcopy /y /k /e /c %APKDIR%\lubo_release_v%VER%.aab G:\
pause

BIN
backup/etcpack.exe Normal file

Binary file not shown.

BIN
backup/etcpacktool.exe Normal file

Binary file not shown.

6
backup/password.txt Normal file
View File

@@ -0,0 +1,6 @@
outlook
wajedev@outlook.com
wajeGame2026
cocos
dev2026
1...q...

View File

@@ -0,0 +1,2 @@
用户名,密码,控制台登录 URL
s3-hk,dYG|E86+,https://866435064587.signin.aws.amazon.com/console
1 用户名 密码 控制台登录 URL
2 s3-hk dYG|E86+ https://866435064587.signin.aws.amazon.com/console

View File

@@ -0,0 +1,3 @@
auto connect:i:1
full address:s:ec2-18-163-75-183.ap-east-1.compute.amazonaws.com
username:s:Administrator

23
backup/test.cmd Normal file
View File

@@ -0,0 +1,23 @@
@set ROBOT_KEY=924d16d1-3caf-488f-b89b-0802b910c26b
@set TOOLPATH=D:\Jenkins\tools
@set PROJ=D:\W\SS\D\WhotClient
@set CODE=120240125
@set APKTYPE=debug
@set VER=%Version%
@set BRANCH=SpecialSkin_master
@set GRADLE=D:\Gradle\gradle-8.13\bin\gradle
@set VER=2.11.0
@set JAVA_HOME=D:\Program Files\Java\jdk-17
@set ASPROJ=%PROJ%\build\jsb-default\frameworks\runtime-src\proj.android-studio\app
@set SHAREDIR=D:\share\publish\android\special\debug\%VER%
set list=special opay wajebet palmgame xender
for %%i in (%list%) do (
echo build %%i
echo apk=test_%%i_%APKTYPE%_v%VER%.apk
echo buildDir=%ASPROJ%\build\outputs\apk\%%i\%APKTYPE%
echo assemble%%iDebug -PVERSION_NAME=%VER% -PVERSION_CODE=%CODE%
echo %ASPROJ%\build\outputs\apk\%%i\%APKTYPE%\whotClient-%%i-%APKTYPE%.apk to %SHAREDIR%\test_%%i_%APKTYPE%_v%VER%.apk /y
)
pause

Binary file not shown.

2
backup/vpn.txt Normal file
View File

@@ -0,0 +1,2 @@
https://liangxin.xyz/api/v1/liangxin?OwO=5283cdcedb78ceb09e5d92d1f12f016e#%E8%89%AF%E5%BF%83%E4%BA%91
https://sub.grempt.com/link/206326/9069266d26c00da2f69f#9069266d26c00da2f69f

BIN
docs/20251009-145903.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 KiB

BIN
docs/20251009-151651.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 685 KiB

BIN
etcPack/etcpack.exe Normal file

Binary file not shown.

BIN
etcPack/etcpacktool.exe Normal file

Binary file not shown.

BIN
python.zip Normal file

Binary file not shown.

7
python/main.py Normal file
View File

@@ -0,0 +1,7 @@
import sys
from switch_bundle_common import main
if __name__ == '__main__':
main(sys.argv)

View File

@@ -1,109 +0,0 @@
import os
import sys
import subprocess
import hvac
if len(sys.argv) < 3:
exit()
if '123!@#' != sys.argv[2]:
exit()
ProjDir = sys.argv[1]
BuildDir = ProjDir + '\\build\\web-mobile\\'
SubgamePath = 's3://web-h5game-test/internal/'
# Vault 地址和 Token
VAULT_ADDR = 'https://keys.wehavefun.email'
VAULT_TOKEN = 'hvs.CAESIJNR6tvdIBSvRuI8r_O_82yjqu6eztxKQtk2oEGmOrFSGh4KHGh2cy5KSmlmS2xIbHprcDUwOUlIOVJ3TzdjUWQ'
# 创建客户端
client = hvac.Client(url=VAULT_ADDR, token=VAULT_TOKEN)
if client.is_authenticated():
secret = client.secrets.kv.v2.read_secret_version(
path='default',
mount_point='aws',
raise_on_deleted_version=True
)
SwitchBundle = secret['data']['data']['switchBundle']
if "1" != SwitchBundle:
print("script exit, switchBundle status is " + SwitchBundle)
exit()
else:
print("running script failed!")
exit()
print("start running script...")
BundleConfig = {
'6001': 'whot',
'6002': 'whot',
'6003': 'whot',
'6005': 'BRWhot',
'2001': 'roulette',
'2002': 'wajeSpin',
'2003': 'bottleSpin',
'2004': 'blackjack',
'2006': 'betterjack',
'6007': 'BRWhot',
'2008': 'slots',
'2005': 'christmas',
}
unlinkArray = [
'cocos2d-js.109f3.js',
'cocos2d-js-min.13181.js',
'physics.9d2de.js',
'physics-min.ce5ee.js',
'style-desktop.dfd76.css',
'style-mobile.6e9cd.css',
'splash.85cfd.png'
]
def remove_folder(path):
print('remove path: ', path)
if os.path.exists(path):
if os.path.isfile(path) or os.path.islink(path):
os.remove(path)
else:
for filename in os.listdir(path):
remove_folder(os.path.join(path, filename))
os.rmdir(path)
# 上传src相共用文件
SrcDir = BuildDir + '\\src\\'
SrcDst = SubgamePath + 'lib/src/'
rmResult = subprocess.run(['cmd', '/c', 'aws s3 rm ' + SrcDst + ' --recursive'], capture_output=True, text=True)
print('remove dir src result: ', rmResult)
cmd = 'call aws s3 cp '+ SrcDir +' '+SrcDst + ' --recursive --region ap-east-1'
result = subprocess.run(['cmd', '/c', cmd], capture_output=True, text=True)
print('upload dir src result: ', result)
remove_folder(SrcDir)
for filename in os.listdir(BuildDir):
file_path = os.path.join(BuildDir, filename)
if filename in unlinkArray:
os.remove(file_path)
for gameid in BundleConfig:
awsPath = SubgamePath + gameid + '/assets/' + BundleConfig[gameid] +'/'
rmResult = subprocess.run(['cmd', '/c', 'aws s3 rm ' + awsPath + ' --recursive'], capture_output=True, text=True)
print('remove game gameid: ', gameid, ' result: ', rmResult)
subgameDir = BuildDir + 'assets\\' + BundleConfig[gameid] +'\\'
cmd = 'call aws s3 cp '+ subgameDir +' '+awsPath + ' --recursive --region ap-east-1'
result = subprocess.run(['cmd', '/c', cmd], capture_output=True, text=True)
print(result)
for gameid in BundleConfig:
awsPath = SubgamePath + gameid + '/assets/' + BundleConfig[gameid] +'/'
subgameDir = BuildDir + 'assets\\' + BundleConfig[gameid]
remove_folder(subgameDir)
for gameid in BundleConfig:
awsPath = SubgamePath + gameid + '/'
cmd = 'call aws s3 cp '+ BuildDir +' '+awsPath + ' --recursive --region ap-east-1'
result = subprocess.run(['cmd', '/c', cmd], capture_output=True, text=True)
print('upload game gameid: ', gameid, ' result: ', result)

View File

@@ -1,109 +0,0 @@
import os
import sys
import subprocess
import hvac
if len(sys.argv) < 3:
exit()
if '123!@#' != sys.argv[2]:
exit()
ProjDir = sys.argv[1]
BuildDir = ProjDir + '\\build\\web-mobile\\'
SubgamePath = 's3://web-h5game-prod/internal/'
# Vault 地址和 Token
VAULT_ADDR = 'https://keys.wehavefun.email'
VAULT_TOKEN = 'hvs.CAESIJNR6tvdIBSvRuI8r_O_82yjqu6eztxKQtk2oEGmOrFSGh4KHGh2cy5KSmlmS2xIbHprcDUwOUlIOVJ3TzdjUWQ'
# 创建客户端
client = hvac.Client(url=VAULT_ADDR, token=VAULT_TOKEN)
if client.is_authenticated():
secret = client.secrets.kv.v2.read_secret_version(
path='default',
mount_point='aws',
raise_on_deleted_version=True
)
SwitchBundle = secret['data']['data']['switchBundle']
if "1" != SwitchBundle:
print("script exit, switchBundle status is " + SwitchBundle)
exit()
else:
print("running script failed!")
exit()
print("start running script...")
BundleConfig = {
'6001': 'whot',
'6002': 'whot',
'6003': 'whot',
'6005': 'BRWhot',
'2001': 'roulette',
'2002': 'wajeSpin',
'2003': 'bottleSpin',
'2004': 'blackjack',
'2006': 'betterjack',
'6007': 'BRWhot',
'2008': 'slots',
'2005': 'christmas',
}
unlinkArray = [
'cocos2d-js.109f3.js',
'cocos2d-js-min.13181.js',
'physics.9d2de.js',
'physics-min.ce5ee.js',
'style-desktop.dfd76.css',
'style-mobile.6e9cd.css',
'splash.85cfd.png'
]
def remove_folder(path):
print('remove path: ', path)
if os.path.exists(path):
if os.path.isfile(path) or os.path.islink(path):
os.remove(path)
else:
for filename in os.listdir(path):
remove_folder(os.path.join(path, filename))
os.rmdir(path)
SrcDir = BuildDir + '\\src\\'
SrcDst = SubgamePath + 'lib/src/'
rmResult = subprocess.run(['cmd', '/c', 'aws s3 rm ' + SrcDst + ' --recursive'], capture_output=True, text=True)
print('remove dir src result: ', rmResult)
cmd = 'call aws s3 cp '+ SrcDir +' '+SrcDst + ' --recursive --region eu-west-3'
result = subprocess.run(['cmd', '/c', cmd], capture_output=True, text=True)
print('upload dir src result: ', result)
remove_folder(SrcDir)
for filename in os.listdir(BuildDir):
file_path = os.path.join(BuildDir, filename)
if filename in unlinkArray:
os.remove(file_path)
for gameid in BundleConfig:
awsPath = SubgamePath + gameid + '/assets/' + BundleConfig[gameid] +'/'
rmResult = subprocess.run(['cmd', '/c', 'aws s3 rm ' + awsPath + ' --recursive'], capture_output=True, text=True)
print('remove game gameid: ', gameid, ' result: ', rmResult)
subgameDir = BuildDir + 'assets\\' + BundleConfig[gameid] +'\\'
cmd = 'call aws s3 cp '+ subgameDir +' '+awsPath + ' --recursive --region eu-west-3'
result = subprocess.run(['cmd', '/c', cmd], capture_output=True, text=True)
print(result)
for gameid in BundleConfig:
awsPath = SubgamePath + gameid + '/assets/' + BundleConfig[gameid] +'/'
subgameDir = BuildDir + 'assets\\' + BundleConfig[gameid]
remove_folder(subgameDir)
for gameid in BundleConfig:
awsPath = SubgamePath + gameid + '/'
cmd = 'call aws s3 cp '+ BuildDir +' '+awsPath + ' --recursive --region eu-west-3'
result = subprocess.run(['cmd', '/c', cmd], capture_output=True, text=True)
print('upload game gameid: ', gameid, ' result: ', result)

View File

@@ -0,0 +1,196 @@
"""Shared Vault authorization and bundle publishing for both environments."""
import os
import sys
import subprocess
import hashlib
from vault_options import parse_vault_options, read_switch_bundle
REGION_CONFIG = {
'dev': 'ap-east-1',
'prod': 'eu-west-3',
}
OSS_PATH_CONFIG = {
'dev': {
'waje': 's3://web-h5game-test-waje/internal/',
'wtan': 's3://web-h5game-test-wtan/internal/',
},
'prod': {
'waje': 's3://web-h5game-prod/internal/',
'wtan': ''
},
}
PROFILE_CONFIG = {
'dev': {
'waje': 'h5-new',
'wtan': 'h5-new',
},
'prod': {
'waje': 'default',
'wtan': 'h5-new',
}
}
VAULT_ADDR = 'https://keys.i-see--you.icu'
VAULT_TOKEN = 'hvs.CAESIJrOb65T9ylAMyzlqQOJjI-yutFmTysRbvYbN3IpGra5Gh4KHGh2cy5GeXU4N3FuVEhIQ3A5YmpIM1BETFdYMDc'
BUNDLE_CONFIG = {
'6001': 'whot',
'6002': 'whot',
'6003': 'whot',
'6005': 'BRWhot',
'2001': 'roulette',
'2002': 'wajeSpin',
'2003': 'bottleSpin',
'2004': 'blackjack',
'2006': 'betterjack',
'6007': 'BRWhot',
'2008': 'slots',
'2005': 'christmas',
}
UNLINK_ARRAY = [
'cocos2d-js.109f3.js',
'cocos2d-js-min.13181.js',
'physics.9d2de.js',
'physics-min.ce5ee.js',
'style-desktop.dfd76.css',
'style-mobile.6e9cd.css',
'splash.85cfd.png',
]
def create_vault_client(**kwargs):
"""Create the default Vault client only when a real publish is run."""
import hvac
return hvac.Client(**kwargs)
def remove_folder(path):
print('remove path: ', path)
if os.path.exists(path):
if os.path.isfile(path) or os.path.islink(path):
os.remove(path)
else:
for filename in os.listdir(path):
remove_folder(os.path.join(path, filename))
os.rmdir(path)
def run_publish(proj_dir, subgame_path, region, profile,
run_command=subprocess.run):
"""Upload shared resources and bundles, then publish each game's shell."""
build_dir = proj_dir + '\\build\\web-mobile\\'
src_dir = build_dir + '\\src\\'
src_dst = subgame_path + 'lib/src/'
remove_result = run_command(
['cmd', '/c', 'aws s3 rm ' + src_dst + ' --recursive' + ' --profile ' + profile + ' --region ' + region],
capture_output=True,
text=True,
)
print('remove dir src result: ', remove_result)
command = (
'call aws s3 cp ' + src_dir + ' ' + src_dst
+ ' --recursive'
+ ' --profile ' + profile
+ ' --region ' + region
)
result = run_command(
['cmd', '/c', command],
capture_output=True,
text=True,
)
print('upload dir src result: ', result)
remove_folder(src_dir)
for filename in os.listdir(build_dir):
file_path = os.path.join(build_dir, filename)
if filename in UNLINK_ARRAY:
os.remove(file_path)
for gameid in BUNDLE_CONFIG:
aws_path = (
subgame_path + gameid + '/assets/'
+ BUNDLE_CONFIG[gameid] + '/'
)
remove_result = run_command(
['cmd', '/c', 'aws s3 rm ' + aws_path + ' --recursive' + ' --profile ' + profile + ' --region ' + region],
capture_output=True,
text=True,
)
print('remove game gameid: ', gameid, ' result: ', remove_result)
subgame_dir = build_dir + 'assets\\' + BUNDLE_CONFIG[gameid] + '\\'
command = (
'call aws s3 cp ' + subgame_dir + ' ' + aws_path
+ ' --recursive'
+ ' --profile ' + profile
+ ' --region ' + region
)
result = run_command(
['cmd', '/c', command],
capture_output=True,
text=True,
)
print(result)
for gameid in BUNDLE_CONFIG:
subgame_dir = build_dir + 'assets\\' + BUNDLE_CONFIG[gameid]
remove_folder(subgame_dir)
for gameid in BUNDLE_CONFIG:
aws_path = subgame_path + gameid + '/'
command = (
'call aws s3 cp ' + build_dir + ' ' + aws_path
+ ' --recursive'
+ ' --profile ' + profile
+ ' --region ' + region
)
result = run_command(
['cmd', '/c', command],
capture_output=True,
text=True,
)
print('upload game gameid: ', gameid, ' result: ', result)
def main(argv, client_factory=None, publish=None):
"""Parse the legacy CLI arguments and publish when Vault permits it."""
proj_dir, pwd, env, cat, vault_path, vault_mount_point = parse_vault_options(argv)
if len(argv) < 5:
print('argv error!')
sys.exit(-1)
md5_obj = hashlib.md5()
md5_obj.update((env + cat).encode('utf-8'))
hash_value = md5_obj.hexdigest()
print('hash = ' + hash_value)
if hash_value != pwd:
print('argv verify failed!')
sys.exit(-2)
if client_factory is None:
client_factory = create_vault_client
if publish is None:
publish = run_publish
client = client_factory(url=VAULT_ADDR, token=VAULT_TOKEN)
if client.is_authenticated():
secret = read_switch_bundle(client, vault_path, vault_mount_point)
switch_bundle = secret['data']['data']['enable']
print(switch_bundle)
if '1' != switch_bundle:
print('script exit, switchBundle status is ' + switch_bundle)
sys.exit(-999)
else:
print('running script failed!')
sys.exit(-1000)
print('start running script...')
publish(proj_dir, OSS_PATH_CONFIG[env][cat], REGION_CONFIG[env], PROFILE_CONFIG[env][cat])

View File

@@ -0,0 +1,104 @@
import runpy
import unittest
from pathlib import Path
from unittest.mock import patch
from switch_bundle_common import main
class _FakeVaultV2(object):
def __init__(self, switch_bundle='1'):
self.calls = []
self.switch_bundle = switch_bundle
def read_secret_version(self, **kwargs):
self.calls.append(kwargs)
return {'data': {'data': {'switchBundle': self.switch_bundle}}}
class _FakeClient(object):
def __init__(self, authenticated=True, switch_bundle='1'):
self.authenticated = authenticated
self.v2 = _FakeVaultV2(switch_bundle)
self.secrets = self
self.kv = self
def is_authenticated(self):
return self.authenticated
class SwitchBundleCommonTests(unittest.TestCase):
def test_main_passes_vault_options_and_environment_to_publish(self):
client = _FakeClient()
publish_calls = []
main(
['switchBundle.py', 'project', '123!@#', 'release', 'production'],
's3://web-h5game-test/internal/',
'ap-east-1',
client_factory=lambda **kwargs: client,
publish=lambda *args: publish_calls.append(args),
)
self.assertEqual(
client.v2.calls[0]['path'],
'release',
)
self.assertEqual(
client.v2.calls[0]['mount_point'],
'production',
)
self.assertEqual(
publish_calls,
[('project', 's3://web-h5game-test/internal/', 'ap-east-1')],
)
def test_main_skips_publish_when_password_is_invalid(self):
client_calls = []
publish_calls = []
main(
['switchBundle.py', 'project', 'wrong-password'],
's3://web-h5game-test/internal/',
'ap-east-1',
client_factory=lambda **kwargs: client_calls.append(kwargs),
publish=lambda *args: publish_calls.append(args),
)
self.assertEqual(client_calls, [])
self.assertEqual(publish_calls, [])
def test_main_skips_publish_when_vault_does_not_allow_it(self):
for authenticated, switch_bundle in [(False, '1'), (True, '0')]:
with self.subTest(authenticated=authenticated, switch_bundle=switch_bundle):
client = _FakeClient(authenticated, switch_bundle)
publish_calls = []
main(
['switchBundle.py', 'project', '123!@#'],
's3://web-h5game-test/internal/',
'ap-east-1',
client_factory=lambda **kwargs: client,
publish=lambda *args: publish_calls.append(args),
)
self.assertEqual(publish_calls, [])
self.assertEqual(len(client.v2.calls), int(authenticated))
def test_entry_points_keep_their_publish_destinations(self):
environments = [
('switchBundle.py', 's3://web-h5game-test/internal/', 'ap-east-1'),
('switchBundleR.py', 's3://web-h5game-prod/internal/', 'eu-west-3'),
]
for filename, destination, region in environments:
with self.subTest(filename=filename):
script = str(Path(__file__).with_name(filename))
argv = [script, 'project', '123!@#', 'release', 'production']
with patch('sys.argv', argv), patch('switch_bundle_common.main') as entry:
runpy.run_path(script, run_name='__main__')
entry.assert_called_once_with(argv, destination, region)
if __name__ == '__main__':
unittest.main()

View File

@@ -0,0 +1,66 @@
import unittest
from vault_options import parse_vault_options, read_switch_bundle
class _FakeVaultV2(object):
def __init__(self):
self.calls = []
def read_secret_version(self, **kwargs):
self.calls.append(kwargs)
return {'data': {'data': {'switchBundle': '1'}}}
class _FakeClient(object):
def __init__(self):
self.v2 = _FakeVaultV2()
self.secrets = self
self.kv = self
class ParseVaultOptionsTests(unittest.TestCase):
def test_uses_default_path_and_mount_point(self):
options = parse_vault_options(['switchBundle.py', 'project', '123!@#'])
self.assertEqual(options, ('default', 'aws'))
def test_reads_path_and_mount_point_after_existing_arguments(self):
options = parse_vault_options(
['switchBundle.py', 'project', '123!@#', 'release', 'production']
)
self.assertEqual(options, ('release', 'production'))
def test_uses_default_mount_point_when_only_path_is_provided(self):
options = parse_vault_options(
['switchBundle.py', 'project', '123!@#', 'release']
)
self.assertEqual(options, ('release', 'aws'))
def test_passes_path_and_mount_point_to_vault(self):
client = _FakeClient()
read_switch_bundle(client, 'release', 'production')
self.assertEqual(
client.v2.calls,
[{
'path': 'release',
'mount_point': 'production',
'raise_on_deleted_version': True,
}],
)
def test_uses_default_vault_settings_when_not_provided(self):
client = _FakeClient()
read_switch_bundle(client)
self.assertEqual(client.v2.calls[0]['path'], 'default')
self.assertEqual(client.v2.calls[0]['mount_point'], 'aws')
if __name__ == '__main__':
unittest.main()

29
python/vault_options.py Normal file
View File

@@ -0,0 +1,29 @@
DEFAULT_VAULT_PATH = 'dev'
DEFAULT_VAULT_MOUNT_POINT = 'tokens'
def parse_vault_options(argv):
"""Return the Vault path and mount point from the script arguments.
The first two arguments are already used by the publishing scripts for
the project directory and access password. Vault settings therefore
remain optional arguments 3 and 4 so existing invocations keep working.
"""
proj = argv[1]
pwd = argv[2]
env = argv[3]
cat = argv[4]
path = argv[5] if len(argv) > 5 else DEFAULT_VAULT_PATH
mount_point = argv[6] if len(argv) > 6 else DEFAULT_VAULT_MOUNT_POINT
return proj, pwd, env, cat, path, mount_point
def read_switch_bundle(
client,
path=DEFAULT_VAULT_PATH,
mount_point=DEFAULT_VAULT_MOUNT_POINT):
return client.secrets.kv.v2.read_secret_version(
path=path,
mount_point=mount_point,
raise_on_deleted_version=True
)