Hot fix support v4 and v5

Hot fix support v4 and v5
	Hot fix support v4 and v5
	Temporary disable transfer item
	Hot fix support v4 and v5
This commit is contained in:
HuLiNap 2025-03-21 12:53:01 +07:00
parent bacb2d7f0b
commit 32a48ba1bb
7 changed files with 219 additions and 47 deletions

View file

@ -1,43 +1,45 @@
{
"avatar_config": [
{
"name": "Castorice",
"id": 1407,
"hp": 100,
"sp": 50,
"level": 80,
"promotion": 6,
"rank": 6,
"lightcone": {
"id": 23040,
"rank": 5,
"level": 80,
"promotion": 6
},
"relics": [
"61241,15,1,4,8:2:4,11:2:0,4:2:2,9:3:6",
"61242,15,1,4,8:3:6,9:3:0,4:2:0,11:1:0",
"61243,15,5,4,8:3:3,4:4:8,11:1:1,1:1:2",
"61244,15,1,4,9:3:0,1:2:4,8:3:0,11:1:1",
"63195,15,9,4,9:3:6,8:3:0,4:2:4,11:1:0",
"63196,15,3,4,1:2:4,11:2:0,9:3:6,8:2:0"
],
"use_technique": true
"name": "Castorice",
"id": 1407,
"hp": 100,
"sp": 50,
"level": 80,
"promotion": 6,
"rank": 6,
"lightcone": {
"id": 23040,
"rank": 5,
"level": 80,
"promotion": 6
},
"relics": [
"61241,15,1,4,9:3000:6000,8:3000:6000,4:2000:4000,11:1000:2000",
"61242,15,1,4,8:3000:6000,9:3000:6000,4:2000:4000,1:1000:2000",
"61243,15,5,4,8:3000:6000,4:4000:8000,1:1000:2000,11:1000:2000",
"61244,15,1,4,8:4000:8000,9:3000:6000,1:1000:2000,11:1000:2000",
"63195,15,9,4,4:1000:2000,8:3000:6000,9:4000:8000,11:1000:2000",
"63196,15,3,4,8:3000:6000,9:4000:8000,1:1000:2000,11:1000:2000"
],
"use_technique": true
}
],
"battle_config": {
"battle_id": 1,
"stage_id": 420244,
"stage_id": 30113122,
"cycle_count": 30,
"monster_wave": [
[
203401404
8003020,
2023010,
8003020
],
[
3004020
]
],
"monster_level": 90,
"blessings": [
3111051,
3110008
]
"monster_level": 95,
"blessings": []
}
}

View file

@ -67,7 +67,7 @@ pub fn onVerifyLogin(req: *httpz.Request, res: *httpz.Response) !void {
.message = "OK",
.data = .{
.account = .{
.arean_code = "/hkrpg_global/mdk/shield/api/login",
.area_code = "**",
.country = "CN",
.is_email_verify = "1",
.email = "ReversedRoooms@StarRail.com",

View file

@ -4,7 +4,7 @@ const protocol = @import("protocol");
const HttpClient = @import("tls12");
const Base64Encoder = @import("std").base64.standard.Encoder;
const Base64Decoder = @import("std").base64.standard.Decoder;
const hotfixInfo = @import("hotfix.zig");
const CNPROD_HOST = "prod-gf-cn-dp01.bhsr.com";
const CNBETA_HOST = "beta-release01-cn.bhsr.com";
const OSPROD_HOST = "prod-official-asia-dp01.starrails.com";
@ -39,13 +39,20 @@ pub fn onQueryGateway(req: *httpz.Request, res: *httpz.Response) !void {
var proto = protocol.Gateserver.init(res.arena);
const query = try req.query();
const version = query.get("version") orelse "";
std.log.info("Get Version >> {s}", .{version});
const dispatch_seed = query.get("dispatch_seed") orelse "";
std.log.info("Get DispatchSeed >> {s}", .{dispatch_seed});
const host = selectHost(version);
const gatewayUrl = constructUrl(host, version, dispatch_seed);
std.log.info("Constructed Gateway URL >> {s}", .{gatewayUrl});
const hotfix = try hotfixInfo.Parser(res.arena, "hotfix.json", version);
var assetBundleUrl: []const u8 = undefined;
var exResourceUrl: []const u8 = undefined;
var luaUrl: []const u8 = undefined;
var iFixUrl: []const u8 = undefined;
//var luaVersion: []const u8 = undefined;
//var iFixVersion: []const u8 = undefined;
//HTTP Request
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
@ -78,14 +85,28 @@ pub fn onQueryGateway(req: *httpz.Request, res: *httpz.Response) !void {
//Gateserver Protobuf Decode
const gateserver_proto = try protocol.Gateserver.decode(decoded_data, res.arena);
assetBundleUrl = gateserver_proto.asset_bundle_url.Owned.str;
exResourceUrl = gateserver_proto.ex_resource_url.Owned.str;
luaUrl = gateserver_proto.lua_url.Owned.str;
//std.log.info("\x1b[33;1mEncoded Gateway Response >> {s}\x1b[0m", .{gateway_response_body});
//std.log.info("\x1b[32;1mDecoded Gateway Response >> {s}\x1b[0m", .{decoded_data});
//std.log.info("\x1b[33;1mProtobuf Message >> {}\x1b[0m", .{gateserver_proto});
assetBundleUrl = hotfix.assetBundleUrl;
exResourceUrl = hotfix.exResourceUrl;
luaUrl = hotfix.luaUrl;
iFixUrl = hotfix.iFixUrl;
if (assetBundleUrl.len == 0 or exResourceUrl.len == 0 or luaUrl.len == 0 or iFixUrl.len == 0) {
assetBundleUrl = gateserver_proto.asset_bundle_url.Owned.str;
exResourceUrl = gateserver_proto.ex_resource_url.Owned.str;
luaUrl = gateserver_proto.lua_url.Owned.str;
iFixUrl = gateserver_proto.ifix_url.Owned.str;
try hotfixInfo.putValue(version, assetBundleUrl, exResourceUrl, luaUrl, iFixUrl);
}
std.log.info("Get Version >> {s}", .{version});
std.log.info("Get AssetBundleUrl >> {s}", .{assetBundleUrl});
std.log.info("Get ExResourceUrl >> {s}", .{exResourceUrl});
std.log.info("Get LuaUrl >> {s}", .{luaUrl});
std.log.info("Get IFixUrl >> {s}", .{iFixUrl});
proto.retcode = 0;
proto.port = 23301;

95
dispatch/src/hotfix.zig Normal file
View file

@ -0,0 +1,95 @@
const std = @import("std");
const Allocator = std.mem.Allocator;
const hotfixInfo = struct {
clientVersion: []const u8,
assetBundleUrl: []const u8,
exResourceUrl: []const u8,
luaUrl: []const u8,
iFixUrl: []const u8,
};
pub fn Parser(allocator: Allocator, filename: []const u8, version: []const u8) !hotfixInfo {
const file = try std.fs.cwd().openFile(filename, .{});
defer file.close();
const file_size = try file.getEndPos();
const buffer = try file.readToEndAlloc(allocator, file_size);
defer allocator.free(buffer);
var json_tree = try std.json.parseFromSlice(std.json.Value, allocator, buffer, .{ .ignore_unknown_fields = true });
defer json_tree.deinit();
const version_node = json_tree.value.object.get(version) orelse {
return hotfixInfo{
.clientVersion = version,
.assetBundleUrl = "",
.exResourceUrl = "",
.luaUrl = "",
.iFixUrl = "",
};
};
return getValue(version_node, version);
}
fn getValue(node: std.json.Value, client_version: []const u8) !hotfixInfo {
if (node != .object) return error.InvalidJsonStructure;
const obj = node.object;
const assetBundleUrl = obj.get("asset_bundle_url") orelse return error.MissingAssetBundleUrl;
const exResourceUrl = obj.get("ex_resource_url") orelse return error.MissingExResourceUrl;
const luaUrl = obj.get("lua_url") orelse return error.MissingLuaUrl;
const iFixUrl = obj.get("ifix_url") orelse return error.MissingIFixUrl;
if (assetBundleUrl != .string or
exResourceUrl != .string or
luaUrl != .string or
iFixUrl != .string) return error.InvalidUrlFormat;
return hotfixInfo{
.clientVersion = client_version,
.assetBundleUrl = assetBundleUrl.string,
.exResourceUrl = exResourceUrl.string,
.luaUrl = luaUrl.string,
.iFixUrl = iFixUrl.string,
};
}
pub fn putValue(version: []const u8, assetBundleUrl: []const u8, exResourceUrl: []const u8, luaUrl: []const u8, iFixUrl: []const u8) !void {
const file = try std.fs.cwd().openFile("hotfix.json", .{ .mode = .read_write });
defer file.close();
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();
const file_size = try file.getEndPos();
const buffer0 = try file.readToEndAlloc(allocator, file_size);
defer allocator.free(buffer0);
var json_tree = try std.json.parseFromSlice(std.json.Value, allocator, buffer0, .{ .ignore_unknown_fields = true });
defer json_tree.deinit();
var root = json_tree.value.object;
var new_version = std.json.ObjectMap.init(allocator);
try new_version.put("asset_bundle_url", .{ .string = assetBundleUrl });
try new_version.put("ex_resource_url", .{ .string = exResourceUrl });
try new_version.put("ifix_url", .{ .string = iFixUrl });
try new_version.put("ifix_version", .{ .string = "0" });
try new_version.put("lua_url", .{ .string = luaUrl });
try new_version.put("lua_version", .{ .string = "" });
try root.put(version, .{ .object = new_version });
const json_value = std.json.Value{ .object = root };
var buffer = std.ArrayList(u8).init(allocator);
try std.json.stringify(json_value, .{ .whitespace = .indent_4 }, buffer.writer());
const new_file = try std.fs.cwd().createFile("hotfix.json", .{ .truncate = true });
defer new_file.close();
try new_file.writeAll(buffer.items);
}

View file

@ -221,19 +221,19 @@ pub fn onDoGacha(session: *Session, packet: *const Packet, allocator: std.mem.Al
gacha_item.gacha_item = .{ .ItemId = id };
gacha_item.is_new = false;
var back_item = std.ArrayList(protocol.Item).init(allocator);
var transfer_item = std.ArrayList(protocol.Item).init(allocator);
if (id < 10000) {
if (isInList(id, &GachaData.RateUp) or isInList(id, &GachaData.StandardBanner)) {
try transfer_item.appendSlice(&[_]protocol.Item{
.{ .ItemId = id + 10000, .Num = 1 },
.{ .ItemId = 252, .Num = 20 },
});
} else {
try transfer_item.append(.{ .ItemId = 252, .Num = 20 });
}
}
//var transfer_item = std.ArrayList(protocol.Item).init(allocator);
//if (id < 10000) {
// if (isInList(id, &GachaData.RateUp) or isInList(id, &GachaData.StandardBanner)) {
// try transfer_item.appendSlice(&[_]protocol.Item{
// .{ .ItemId = id + 10000, .Num = 1 },
// .{ .ItemId = 252, .Num = 20 },
// });
// } else {
// try transfer_item.append(.{ .ItemId = 252, .Num = 20 });
// }
//}
try back_item.append(.{ .ItemId = 252, .Num = 20 });
gacha_item.transfer_item_list = .{ .ItemList_ = transfer_item };
//gacha_item.transfer_item_list = .{ .ItemList_ = transfer_item };
gacha_item.token_item = .{ .ItemList_ = back_item };
try rsp.gacha_item_list.append(gacha_item);
}

50
hotfix.json Normal file
View file

@ -0,0 +1,50 @@
{
"OSBETAWin3.1.51": {
"asset_bundle_url": "https://autopatchos.starrails.com/asb/BetaLive/output_9573347_b03981f01966",
"ex_resource_url": "https://autopatchos.starrails.com/design_data/BetaLive/output_9574749_cf833d944ab2",
"ifix_url": "https://autopatchos.starrails.com/ifix/BetaLive/output_0_40d2ce0253",
"ifix_version": "0",
"lua_url": "https://autopatchos.starrails.com/lua/BetaLive/output_9567078_0e2b6acf6a2f",
"lua_version": "9567078"
},
"CNBETAWin3.1.51": {
"asset_bundle_url": "https://autopatchcn.bhsr.com/asb/BetaLive/output_9573347_b03981f01966",
"ex_resource_url": "https://autopatchcn.bhsr.com/design_data/BetaLive/output_9574749_cf833d944ab2",
"ifix_url": "https://autopatchcn.bhsr.com/ifix/BetaLive/output_0_40d2ce0253",
"ifix_version": "0",
"lua_url": "https://autopatchcn.bhsr.com/lua/BetaLive/output_9567078_0e2b6acf6a2f",
"lua_version": "9567078"
},
"OSBETAWin3.1.52": {
"asset_bundle_url": "https://autopatchos.starrails.com/asb/BetaLive/output_9614772_b674c1e08556",
"ex_resource_url": "https://autopatchos.starrails.com/design_data/BetaLive/output_9614804_4a927001828b",
"ifix_url": "https://autopatchos.starrails.com/ifix/BetaLive/output_0_40d2ce0253",
"ifix_version": "0",
"lua_url": "https://autopatchos.starrails.com/lua/BetaLive/output_9615588_bd4aff54bc1a",
"lua_version": "9615588"
},
"CNBETAWin3.1.52": {
"asset_bundle_url": "https://autopatchcn.bhsr.com/asb/BetaLive/output_9614772_b674c1e08556",
"ex_resource_url": "https://autopatchcn.bhsr.com/design_data/BetaLive/output_9614804_4a927001828b",
"ifix_url": "https://autopatchcn.bhsr.com/ifix/BetaLive/output_0_40d2ce0253",
"ifix_version": "0",
"lua_url": "https://autopatchcn.bhsr.com/lua/BetaLive/output_9615588_bd4aff54bc1a",
"lua_version": "9615588"
},
"OSBETAWin3.1.54": {
"asset_bundle_url": "https://autopatchos.starrails.com/asb/BetaLive/output_9773985_63c011ff01b8",
"ex_resource_url": "https://autopatchos.starrails.com/design_data/BetaLive/output_9770613_f97f7e40c819",
"ifix_url": "https://autopatchos.starrails.com/ifix/BetaLive/output_0_40d2ce0253",
"ifix_version": "0",
"lua_url": "https://autopatchos.starrails.com/lua/BetaLive/output_9756910_bc358954a8d7",
"lua_version": ""
},
"OSBETAWin3.1.55": {
"asset_bundle_url": "https://autopatchos.starrails.com/asb/BetaLive/output_9812860_72466f10a7ed",
"ex_resource_url": "https://autopatchos.starrails.com/design_data/BetaLive/output_9823582_b52f858ff4ab",
"ifix_url": "https://autopatchos.starrails.com/ifix/BetaLive/output_0_40d2ce0253",
"ifix_version": "0",
"lua_url": "https://autopatchos.starrails.com/lua/BetaLive/output_9813028_57821b09ee05",
"lua_version": ""
}
}

4
run-mian.bat Normal file
View file

@ -0,0 +1,4 @@
@echo
start zig build run-dispatch
start zig build run-gameserver