Skip to content

Commit

Permalink
updated to v2.11.2 (burlconfig.conf can export cipher type)
Browse files Browse the repository at this point in the history
  • Loading branch information
michael811125 committed May 18, 2024
1 parent cc7eb56 commit c211d26
Show file tree
Hide file tree
Showing 10 changed files with 177 additions and 22 deletions.
55 changes: 49 additions & 6 deletions Assets/OxGFrame/AssetLoader/Scripts/Editor/Bundle/BundleHelper.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
using Newtonsoft.Json;
using NUnit.Framework;
using OxGFrame.AssetLoader.Bundle;
using OxGFrame.AssetLoader.Utility;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Text;
using UnityEditor;
using UnityEngine;
using YooAsset.Editor;
Expand Down Expand Up @@ -158,18 +161,20 @@ public static void ExportIndividualDlcBundles(string inputPath, string outputPat
/// <summary>
/// 產生 Bundle URL 配置檔至輸出路徑 (Export BundleUrlConfig to StreamingAssets [for Built-in])
/// </summary>
/// <param name="productName"></param>
/// <param name="appVersion"></param>
/// <param name="bundleIp"></param>
/// <param name="bundleFallbackIp"></param>
/// <param name="storeLink"></param>
/// <param name="outputPath"></param>
public static void ExportBundleUrlConfig(string bundleIp, string bundleFallbackIp, string storeLink, string outputPath)
/// <param name="cipher"></param>
public static void ExportBundleUrlConfig(string bundleIp, string bundleFallbackIp, string storeLink, string outputPath, bool cipher)
{
if (!Directory.Exists(outputPath)) Directory.CreateDirectory(outputPath);

if (string.IsNullOrEmpty(bundleIp)) bundleIp = "127.0.0.1";
if (string.IsNullOrEmpty(bundleFallbackIp)) bundleFallbackIp = "127.0.0.1";
if (string.IsNullOrEmpty(storeLink)) storeLink = "http://";

IEnumerable<string> contents = new string[]
IEnumerable<string> texts = new string[]
{
@$"# {PatchSetting.BUNDLE_IP} = First CDN Server IP or Domain (Plan A)",
@$"# {PatchSetting.BUNDLE_FALLBACK_IP} = Second CDN Server IP or Domain (Plan B)",
Expand All @@ -184,10 +189,48 @@ public static void ExportBundleUrlConfig(string bundleIp, string bundleFallbackI
string bundleUrlFileName = $"{PatchSetting.setting.bundleUrlCfgName}{PatchSetting.BUNDLE_URL_CFG_EXTENSION}";
string fullOutputPath = Path.Combine(outputPath, bundleUrlFileName);

string content = string.Empty;
int idx = 0;
foreach (string txt in texts)
{
if (cipher)
{
// Without useless texts
if (idx < texts.ToArray().Length - 3)
{
idx++;
continue;
}
}
content += txt + "\n";
}

byte[] writeBuffer;
byte[] data = Encoding.UTF8.GetBytes(content);

if (cipher)
{
// Encrypt
for (int i = 0; i < data.Length; i++)
{
data[i] ^= BundleConfig.cipher << 1;
}

// Write data with header
int pos = 0;
byte[] dataWithHeader = new byte[data.Length + 2];
// Write header (non-encrypted)
BundleConfig.WriteInt16(BundleConfig.cipherHeader, dataWithHeader, ref pos);
Buffer.BlockCopy(data, 0, dataWithHeader, pos, data.Length);
writeBuffer = dataWithHeader;
}
else
writeBuffer = data;

// 寫入配置文件
File.WriteAllLines(fullOutputPath, contents, System.Text.Encoding.UTF8);
File.WriteAllBytes(fullOutputPath, writeBuffer);

Debug.Log($"<color=#00FF00>【Export {bundleUrlFileName} Completes】</color>");
Debug.Log($"<color=#00FF00>【Export Source is Cipher: {cipher}, {bundleUrlFileName} Completes】</color>");
}
#endregion

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ private void _DrawHT2XorPlusView()
GUILayout.Label(new GUIContent("Head-Tail 2 XOR Plus Settings"), centeredStyle);
EditorGUILayout.Space();

var labelWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = 200;
this.hXorPlusKey = EditorGUILayout.IntField("Head XOR Plus KEY (0 ~ 255)", this.hXorPlusKey);
if (this.hXorPlusKey < 0) this.hXorPlusKey = 0;
Expand All @@ -276,6 +277,7 @@ private void _DrawHT2XorPlusView()
this.j2XorPlusKey = EditorGUILayout.IntField("Jump 2 XOR Plus KEY (0 ~ 255)", this.j2XorPlusKey);
if (this.j2XorPlusKey < 0) this.j2XorPlusKey = 0;
else if (this.j2XorPlusKey > 255) this.j2XorPlusKey = 255;
EditorGUIUtility.labelWidth = labelWidth;

this._DrawOperateButtonsView(this.cryptogramType);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,10 @@ private void _DrawBundleIPTextFieldView()

EditorGUILayout.BeginHorizontal();
EditorGUI.BeginChangeCheck();
this.bundleIp = EditorGUILayout.TextField("Bundle IP", this.bundleIp);
var labelWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = 180;
this.bundleIp = EditorGUILayout.TextField("Bundle IP or Domain", this.bundleIp);
EditorGUIUtility.labelWidth = labelWidth;
if (EditorGUI.EndChangeCheck()) EditorStorage.SaveData(keySaver, "bundleIp", this.bundleIp);
EditorGUILayout.EndHorizontal();
}
Expand All @@ -101,7 +104,10 @@ private void _DrawBundleFallbackIPTextFieldView()

EditorGUILayout.BeginHorizontal();
EditorGUI.BeginChangeCheck();
this.bundleFallbackIp = EditorGUILayout.TextField("Bundle Fallback IP", this.bundleFallbackIp);
var labelWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = 180;
this.bundleFallbackIp = EditorGUILayout.TextField("Bundle Fallback IP or Domain", this.bundleFallbackIp);
EditorGUIUtility.labelWidth = labelWidth;
if (EditorGUI.EndChangeCheck()) EditorStorage.SaveData(keySaver, "bundleFallbackIp", this.bundleFallbackIp);
EditorGUILayout.EndHorizontal();
}
Expand All @@ -112,7 +118,10 @@ private void _DrawStoreLinkTextFieldView()

EditorGUILayout.BeginHorizontal();
EditorGUI.BeginChangeCheck();
var labelWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = 180;
this.storeLink = EditorGUILayout.TextField("Store Link", this.storeLink);
EditorGUIUtility.labelWidth = labelWidth;
if (EditorGUI.EndChangeCheck()) EditorStorage.SaveData(keySaver, "storeLink", this.storeLink);
EditorGUILayout.EndHorizontal();
}
Expand All @@ -132,11 +141,22 @@ private void _DrawProcessButtonView()
// process button
Color bc = GUI.backgroundColor;
GUI.backgroundColor = new Color32(255, 185, 83, 255);
if (GUILayout.Button("Process", GUILayout.MaxWidth(100f)))
if (GUILayout.Button("Cipher Process", GUILayout.MaxWidth(110f)))
{
string outputPath = Application.streamingAssetsPath;
BundleHelper.ExportBundleUrlConfig(this.bundleIp, this.bundleFallbackIp, this.storeLink, outputPath);
EditorUtility.DisplayDialog("Process Message", "Export BundleUrlConfig To StreamingAssets.", "OK");
BundleHelper.ExportBundleUrlConfig(this.bundleIp, this.bundleFallbackIp, this.storeLink, outputPath, true);
EditorUtility.DisplayDialog("Process Message", "Export [Cipher] BundleUrlConfig To StreamingAssets.", "OK");
AssetDatabase.Refresh();
string bundleUrlFileName = $"{PatchSetting.setting.bundleUrlCfgName}{PatchSetting.BUNDLE_URL_CFG_EXTENSION}";
if (this.autoReveal) EditorUtility.RevealInFinder($"{outputPath}/{bundleUrlFileName}");
}
GUI.backgroundColor = bc;
GUI.backgroundColor = new Color32(255, 185, 83, 255);
if (GUILayout.Button("Plaintext Process", GUILayout.MaxWidth(125f)))
{
string outputPath = Application.streamingAssetsPath;
BundleHelper.ExportBundleUrlConfig(this.bundleIp, this.bundleFallbackIp, this.storeLink, outputPath, false);
EditorUtility.DisplayDialog("Process Message", "Export [Plaintext] BundleUrlConfig To StreamingAssets.", "OK");
AssetDatabase.Refresh();
string bundleUrlFileName = $"{PatchSetting.setting.bundleUrlCfgName}{PatchSetting.BUNDLE_URL_CFG_EXTENSION}";
if (this.autoReveal) EditorUtility.RevealInFinder($"{outputPath}/{bundleUrlFileName}");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ private void _DrawHT2XorPlusView()
EditorGUILayout.Space();

EditorGUI.BeginChangeCheck();
var labelWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = 200;
this.hXorPlusKey = EditorGUILayout.IntField("Head XOR Plus KEY (0 ~ 255)", this.hXorPlusKey);
if (this.hXorPlusKey < 0) this.hXorPlusKey = 0;
Expand All @@ -269,6 +270,7 @@ private void _DrawHT2XorPlusView()
this.j2XorPlusKey = EditorGUILayout.IntField("Jump 2 XOR Plus KEY (0 ~ 255)", this.j2XorPlusKey);
if (this.j2XorPlusKey < 0) this.j2XorPlusKey = 0;
else if (this.j2XorPlusKey > 255) this.j2XorPlusKey = 255;
EditorGUIUtility.labelWidth = labelWidth;
if (EditorGUI.EndChangeCheck()) this._isDirty = true;

this._DrawOperateButtonsView(this.cryptogramType);
Expand Down
86 changes: 82 additions & 4 deletions Assets/OxGFrame/AssetLoader/Scripts/Runtime/Bundle/BundleConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
using MyBox;
using Newtonsoft.Json;
using OxGFrame.AssetLoader.Utility.SecureMemory;
using OxGKit.LoggingSystem;
using OxGKit.Utilities.Request;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEngine;

namespace OxGFrame.AssetLoader.Bundle
Expand Down Expand Up @@ -57,6 +59,16 @@ public class CryptogramType
}

#region 執行配置
/// <summary>
/// 配置檔標檔頭
/// </summary>
public const short cipherHeader = 0x584F;

/// <summary>
/// 配置檔金鑰
/// </summary>
public const byte cipher = 0x4D;

/// <summary>
/// Patch 執行模式
/// </summary>
Expand Down Expand Up @@ -171,6 +183,40 @@ internal static void ReleaseSecureString()
/// </summary>
private static AppConfig _appConfig = null;

#region Header Helper
public static void WriteInt16(short value, byte[] buffer, ref int pos)
{
WriteUInt16((ushort)value, buffer, ref pos);
}

internal static void WriteUInt16(ushort value, byte[] buffer, ref int pos)
{
buffer[pos++] = (byte)value;
buffer[pos++] = (byte)(value >> 8);
}

public static short ReadInt16(byte[] buffer, ref int pos)
{
if (BitConverter.IsLittleEndian)
{
short value = (short)((buffer[pos]) | (buffer[pos + 1] << 8));
pos += 2;
return value;
}
else
{
short value = (short)((buffer[pos] << 8) | (buffer[pos + 1]));
pos += 2;
return value;
}
}

internal static ushort ReadUInt16(byte[] buffer, ref int pos)
{
return (ushort)ReadInt16(buffer, ref pos);
}
#endregion

/// <summary>
/// 取得 burlconfig 佈署配置檔的數據
/// </summary>
Expand All @@ -182,19 +228,51 @@ public static async UniTask<string> GetValueFromUrlCfg(string key)
{
string bundleUrlFileName = $"{PatchSetting.setting.bundleUrlCfgName}{PatchSetting.BUNDLE_URL_CFG_EXTENSION}";
string pathName = Path.Combine(GetRequestStreamingAssetsPath(), bundleUrlFileName);
var content = await Requester.RequestText(pathName, null, null, null, false);
if (string.IsNullOrEmpty(content)) return string.Empty;
var data = await Requester.RequestBytes(pathName);
if (data.Length == 0)
return string.Empty;

#region Check data type
string content;
int pos = 0;

// Read header (non-encrypted)
var header = ReadInt16(data, ref pos);
if (header == cipherHeader)
{
// Read data without header
byte[] dataWithoutHeader = new byte[data.Length - 2];
Buffer.BlockCopy(data, pos, dataWithoutHeader, 0, data.Length - pos);
// Decrypt
for (int i = 0; i < dataWithoutHeader.Length; i++)
{
dataWithoutHeader[i] ^= cipher << 1;
}
// To string
content = Encoding.UTF8.GetString(dataWithoutHeader);
Logging.Print<Logger>($"<color=#4eff9e>[Source is Cipher] Check -> burlconfig.conf:</color>\n{content}");
}
else
{
content = Encoding.UTF8.GetString(data);
Logging.Print<Logger>($"<color=#4eff9e>[Source is Plaintext] Check -> burlconfig.conf:</color>\n{content}");
}
#endregion

// Parsing
var allWords = content.Split('\n');
var lines = new List<string>(allWords);

_urlCfgFileMap = new Dictionary<string, string>();
foreach (var readLine in lines)
{
if (readLine.IndexOf('#') != -1 && readLine[0] == '#') continue;
if (readLine.IndexOf('#') != -1 && readLine[0] == '#')
continue;
var args = readLine.Split(' ', 2);
if (args.Length >= 2)
{
if (!_urlCfgFileMap.ContainsKey(args[0])) _urlCfgFileMap.Add(args[0], args[1].Replace("\n", "").Replace("\r", ""));
if (!_urlCfgFileMap.ContainsKey(args[0]))
_urlCfgFileMap.Add(args[0], args[1].Replace("\n", "").Replace("\r", ""));
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions Assets/OxGFrame/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# CHANGELOG

## [2.11.2] - 2024-05-18
- Added burlconfig.conf can export cipher type (If the output is ciphertext, it will automatically determine whether to execute with the decryption process).
- Cipher process.
- Plaintext process.

## [2.11.1] - 2024-05-17
- Added HT2XORPlus encryption stronger than HT2XOR (Recommended).
- Updated YooAsset to v2.1.2 (new commits).
Expand Down
4 changes: 2 additions & 2 deletions Assets/OxGFrame/MediaFrame/Scripts/Editor/MediaHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public static void ExportMediaUrlConfig(string audioUrlset, string videoUrlset,
if (string.IsNullOrEmpty(audioUrlset)) audioUrlset = "127.0.0.1/audio/";
if (string.IsNullOrEmpty(videoUrlset)) videoUrlset = "127.0.0.1/video/";

IEnumerable<string> contents = new string[]
IEnumerable<string> texts = new string[]
{
@$"# {MediaConfig.AUDIO_URLSET} = Audio Source Url Path",
@$"# {MediaConfig.VIDEO_URLSET} = Video Source Url Path",
Expand All @@ -33,7 +33,7 @@ public static void ExportMediaUrlConfig(string audioUrlset, string videoUrlset,
string fullOutputPath = Path.Combine(outputPath, MediaConfig.MEDIA_URL_CFG_NAME);

// 寫入配置文件
File.WriteAllLines(fullOutputPath, contents, System.Text.Encoding.UTF8);
File.WriteAllLines(fullOutputPath, texts, System.Text.Encoding.UTF8);

Debug.Log($"<color=#00FF00>【Export {MediaConfig.MEDIA_URL_CFG_NAME} Completes】</color>");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ public async UniTask<string> GetFileText()

case RequestType.StreamingAssets:
string pathName = System.IO.Path.Combine(GetRequestStreamingAssetsPath(), this.fullPathName);
if (string.IsNullOrEmpty(_urlCfgContent)) _urlCfgContent = await OxGKit.Utilities.Request.Requester.RequestText(pathName, null, null, null, false);
if (string.IsNullOrEmpty(_urlCfgContent))
_urlCfgContent = await OxGKit.Utilities.Request.Requester.RequestText(pathName, null, null, null, false);
return _urlCfgContent;
}

Expand Down Expand Up @@ -210,7 +211,8 @@ public void SetNames(string assetName, string mediaName)
public const string AUDIO_URLSET = "audio_urlset";
public static string GetValueFromUrlCfg(string urlCfg, string key)
{
if (string.IsNullOrEmpty(urlCfg)) return string.Empty;
if (string.IsNullOrEmpty(urlCfg))
return string.Empty;

var content = urlCfg;
var allWords = content.Split('\n');
Expand All @@ -220,7 +222,8 @@ public static string GetValueFromUrlCfg(string urlCfg, string key)
foreach (var readLine in lines)
{
Logging.Print<Logger>($"readline: {readLine}");
if (readLine.IndexOf('#') != -1 && readLine[0] == '#') continue;
if (readLine.IndexOf('#') != -1 && readLine[0] == '#')
continue;
var args = readLine.Split(' ', 2);
if (args.Length >= 2)
{
Expand Down
2 changes: 1 addition & 1 deletion Assets/OxGFrame/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "com.michaelo.oxgframe",
"displayName": "OxGFrame",
"description": "The OxGFrame is a framework based on Unity for accelerating game development. Supports multi-platform Win, OSX, Android, iOS, WebGL.",
"version": "2.11.1",
"version": "2.11.2",
"unity": "2021.3",
"license": "MIT",
"samples": [
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,9 @@ if (isInitialized)

#### Bundle [burlconfig] (Bundle URL Config) 格式

格式如下 **(store_link 針對非 Android, iOS 平台的,可以設置主程式下載的 link)**
格式如下,以下為明文類型 **(store_link 針對非 Android, iOS 平台的,可以設置主程式下載的 link)**
- 支持 Cipher Type (密文類型)
- 支持 Plaintext Type (明文類型)

```
# bundle_ip = First CDN Server IP or Domain (Plan A)
Expand Down

0 comments on commit c211d26

Please sign in to comment.