Compare commits
46 Commits
Author | SHA1 | Date |
---|---|---|
CakeLancelot | a3856cdc9d | |
CakeLancelot | 672d7e2b42 | |
CakeLancelot | d5b58d96da | |
CakeLancelot | 06869164a1 | |
CakeLancelot | 99c80c9c7b | |
Gent Semaj | 4196766a2b | |
Gent Semaj | 7922fc060a | |
Gent Semaj | 5bf1ce01e3 | |
Gent Semaj | 27143ccb01 | |
Gent Semaj | 349e7b6e07 | |
Gent Semaj | 9fd6441606 | |
Gent Semaj | 8b1bd5b1ee | |
Gent Semaj | 4f7b6b28e4 | |
Gent Semaj | 99193a198b | |
CakeLancelot | 249af1d2d3 | |
gsemaj | c7b4182a4b | |
FinnHornhoover | b70816fa64 | |
dongresource | 9deba1956f | |
dongresource | 1a3a530c7f | |
dongresource | f62f3af483 | |
gsemaj | f02c960497 | |
gsemaj | e0e0b3c5e3 | |
gsemaj | 615bd3d9a3 | |
gsemaj | 4d6490933d | |
gsemaj | 073666e6f4 | |
gsemaj | 7af28d8e70 | |
gsemaj | 3bb3df7a2d | |
gsemaj | f6dc2d690f | |
gsemaj | af2988e062 | |
gsemaj | 03a3e21532 | |
gsemaj | 20d5f6231c | |
gsemaj | 131297552e | |
gsemaj | ef8ae1fb6e | |
gsemaj | 3aabb35f33 | |
gsemaj | 7b750db9f9 | |
gsemaj | aa564926a0 | |
gsemaj | 2496f04987 | |
gsemaj | 916857edc3 | |
gsemaj | 3791e889c8 | |
gsemaj | d0e67d55c9 | |
gsemaj | 869d5b1976 | |
gsemaj | 8725dd1e4e | |
gsemaj | 8fbe59e5a1 | |
gsemaj | a53fb21621 | |
gsemaj | 9dd5db86eb | |
gsemaj | 4ace5f065f |
|
@ -0,0 +1,136 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# OG racing score conversion script
|
||||
#
|
||||
# This script is meant to update racing scoreboards from Retro-style scores
|
||||
# to OG-accurate scores. Be careful to only run this once!
|
||||
#
|
||||
# The script will create a backup of your DB, as well as a log file
|
||||
# containing a record of all the changes that were made. Make sure to
|
||||
# preserve this log file in case you need to reference it in the future.
|
||||
#
|
||||
# If something goes wrong with the first invocation, you'll need to move the
|
||||
# DB backup and log files out of the way before the script can be re-run.
|
||||
#
|
||||
# If all goes well, you should see different, OG-true scores in IZ scoreboards.
|
||||
#
|
||||
# Do not hesitate to ask the OF developers for assistance if necessary.
|
||||
|
||||
import sys
|
||||
import os.path
|
||||
import shutil
|
||||
import logging
|
||||
import json
|
||||
from math import exp
|
||||
|
||||
import sqlite3
|
||||
|
||||
LOGFILE = 'ogracing.log'
|
||||
DRY_RUN = False # set to True if testing the script
|
||||
CAP_SCORES = True # set to False to disable capping scores to the IZ maximum
|
||||
|
||||
class EpData:
|
||||
max_score = 0
|
||||
pod_factor = 0
|
||||
max_pods = 0
|
||||
max_time = 0
|
||||
time_factor = 0
|
||||
scale_factor = 0
|
||||
|
||||
class RaceResult:
|
||||
epid = 0
|
||||
playerid = 0
|
||||
score = 0
|
||||
timestamp = 0
|
||||
ring_count = 0
|
||||
time = 0
|
||||
|
||||
def check_version(cur):
|
||||
cur.execute("SELECT Value FROM Meta WHERE Key = 'DatabaseVersion';")
|
||||
ver = cur.fetchone()[0]
|
||||
|
||||
if ver < 2:
|
||||
sys.exit('fatal: you must first upgrade your DB version to 2 by running the server at least once')
|
||||
|
||||
def load_epinfo():
|
||||
epinfo = {}
|
||||
with open("drops.json", "r") as f:
|
||||
dat = json.load(f)["Racing"]
|
||||
for key in dat:
|
||||
val = dat[key]
|
||||
epdata = EpData()
|
||||
epid = int(val["EPID"])
|
||||
epdata.max_score = int(val["ScoreCap"])
|
||||
epdata.pod_factor = float(val["PodFactor"])
|
||||
epdata.max_pods = int(val["TotalPods"])
|
||||
epdata.max_time = int(val["TimeLimit"])
|
||||
epdata.time_factor = float(val["TimeFactor"])
|
||||
epdata.scale_factor = float(val["ScaleFactor"])
|
||||
epinfo[epid] = epdata
|
||||
return epinfo
|
||||
|
||||
|
||||
def get_results(cur):
|
||||
results = []
|
||||
cur.execute('SELECT EPID, PlayerID, Timestamp, RingCount, Time, Score FROM RaceResults;')
|
||||
for x in cur.fetchall():
|
||||
result = RaceResult()
|
||||
result.epid = int(x[0])
|
||||
result.playerid = int(x[1])
|
||||
result.timestamp = int(x[2])
|
||||
result.ring_count = int(x[3])
|
||||
result.time = int(x[4])
|
||||
result.score = int(x[5])
|
||||
results.append(result)
|
||||
return results
|
||||
|
||||
def process_result(cur, result, epinfo):
|
||||
epdata = epinfo[result.epid]
|
||||
pod_score = (epdata.pod_factor * result.ring_count) / epdata.max_pods
|
||||
time_score = (epdata.time_factor * result.time) / epdata.max_time
|
||||
newscore = int(exp(pod_score - time_score + epdata.scale_factor))
|
||||
if CAP_SCORES and newscore > epdata.max_score:
|
||||
logging.warning('score {} greater than max ({}) for epid {}, capping'.format(newscore, epdata.max_score, result.epid))
|
||||
print('warning: score {} greater than max ({}) for epid {}, capping'.format(newscore, epdata.max_score, result.epid))
|
||||
newscore = epdata.max_score
|
||||
logging.info('* {} -> {} (EPID: {}, pods: {}, time: {})'.format(result.score, newscore, result.epid, result.ring_count, result.time))
|
||||
if not DRY_RUN:
|
||||
cur.execute('UPDATE RaceResults SET Score = ? WHERE (PlayerID, Timestamp) = (?, ?);', (newscore, result.playerid, result.timestamp))
|
||||
|
||||
def main(path):
|
||||
if os.path.isfile(LOGFILE):
|
||||
sys.exit('fatal: a log file named {} already exists. refusing to modify.'.format(LOGFILE))
|
||||
|
||||
logging.basicConfig(filename=LOGFILE, level=20, format='%(levelname)s: %(message)s')
|
||||
|
||||
if not os.path.isfile(path):
|
||||
sys.exit('fatal: {} is not a file'.format(path))
|
||||
|
||||
bakpath = path + '.ogracing.bak'
|
||||
|
||||
if os.path.isfile(bakpath):
|
||||
sys.exit('fatal: a DB backup named {} already exists. refusing to overwrite.'.format(bakpath))
|
||||
|
||||
shutil.copy(path, bakpath)
|
||||
logging.info('saved database backup to {}'.format(bakpath))
|
||||
print('saved database backup to {}'.format(bakpath))
|
||||
|
||||
epinfo = load_epinfo()
|
||||
|
||||
with sqlite3.connect(path) as db:
|
||||
cur = db.cursor()
|
||||
|
||||
check_version(cur)
|
||||
|
||||
results = get_results(cur)
|
||||
|
||||
for result in results:
|
||||
process_result(cur, result, epinfo)
|
||||
|
||||
logging.info('done.')
|
||||
print('done.')
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) != 2:
|
||||
sys.exit('usage: {} database.db'.format(sys.argv[0]))
|
||||
main(sys.argv[1])
|
|
@ -0,0 +1,2 @@
|
|||
__pycache__
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
# dx2cg
|
||||
Tools for converting d3d9 shader assembly to HLSL/Cg.
|
||||
- `disassembler.py`: Takes in d3d9 assembly and gives back the HLSL equivalent.
|
||||
- `swapper.py`: Searches a shader file for d3d9 assembly and calls the disassembler to replace it with HLSL.
|
||||
- `main.py`: Executes the swapper on every file in a path, writing the changes to new files.
|
||||
|
||||
## Known issues
|
||||
- Only vertex shaders with profile `vs_1_1` are supported
|
||||
- Only fragment shaders with profile `ps_2_0` are supported
|
||||
- Only a limited set of instructions (those used by FF and Unity 2.6) are supported
|
||||
- Properties that don't begin with an underscore do not get captured as locals
|
|
@ -0,0 +1,389 @@
|
|||
#!/usr/bin/env python
|
||||
# coding: utf-8
|
||||
# d3d9 to cg crude dissassembler
|
||||
# ycc 08/08/2022
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
legacy = False # True for 2.6
|
||||
|
||||
reserved = {
|
||||
"_Time",
|
||||
"_SinTime",
|
||||
"_CosTime",
|
||||
|
||||
"_ProjectionParams",
|
||||
|
||||
"_PPLAmbient",
|
||||
|
||||
"_ObjectSpaceCameraPos",
|
||||
"_ObjectSpaceLightPos0",
|
||||
"_ModelLightColor0",
|
||||
"_SpecularLightColor0",
|
||||
|
||||
"_Light2World0", "_World2Light0", "_Object2World", "_World2Object", "_Object2Light0",
|
||||
|
||||
"_LightDirectionBias",
|
||||
"_LightPositionRange",
|
||||
}
|
||||
|
||||
decls = {
|
||||
"dcl_position": "float4 {0} = vdat.vertex;",
|
||||
"dcl_normal": "float4 {0} = float4(vdat.normal, 0);",
|
||||
"dcl_texcoord0": "float4 {0} = vdat.texcoord;",
|
||||
"dcl_texcoord1": "float4 {0} = vdat.texcoord1;",
|
||||
"dcl_color": "float4 {0} = vdat.color;",
|
||||
"dcl_2d": "; // no operation",
|
||||
"dcl": "float4 {0[0]}{0[1]} = pdat.{0[0]}{0[1]};",
|
||||
"def": "const float4 {0} = float4({1}, {2}, {3}, {4});",
|
||||
}
|
||||
|
||||
ops = {
|
||||
"mov": "{0} = {1};",
|
||||
"mov_sat": "{0} = clamp({1}, 0.0, 1.0)",
|
||||
"add": "{0} = {1} + {2};",
|
||||
"mul": "{0} = {1} * {2};",
|
||||
"mad": "{0} = {1} * {2} + {3};",
|
||||
"dp4": "{0} = dot((float4){1}, (float4){2});",
|
||||
"dp3": "{0} = dot((float3){1}, (float3){2});",
|
||||
"min": "{0} = min({1}, {2});",
|
||||
"max": "{0} = max({1}, {2});",
|
||||
"rsq": "{0} = rsqrt({1});",
|
||||
"frc": "{0} = float4({1}.x - (float)floor({1}.x), {1}.y - (float)floor({1}.y), {1}.z - (float)floor({1}.z), {1}.w - (float)floor({1}.w));",
|
||||
"slt": "{0} = float4(({1}.x < {2}.x) ? 1.0f : 0.0f, ({1}.y < {2}.y) ? 1.0f : 0.0f, ({1}.z < {2}.z) ? 1.0f : 0.0f, ({1}.w < {2}.w) ? 1.0f : 0.0f);",
|
||||
"sge": "{0} = float4(({1}.x >= {2}.x) ? 1.0f : 0.0f, ({1}.y >= {2}.y) ? 1.0f : 0.0f, ({1}.z >= {2}.z) ? 1.0f : 0.0f, ({1}.w >= {2}.w) ? 1.0f : 0.0f);",
|
||||
"rcp": "{0} = ({1} == 0.0f) ? FLT_MAX : (({1} == 1.0f) ? {1} : (1 / {1}));",
|
||||
"texld": "{0} = {3}({2}, (float2){1});",
|
||||
}
|
||||
|
||||
struct_a2v = """struct a2v {
|
||||
\tfloat4 vertex : POSITION;
|
||||
\tfloat3 normal : NORMAL;
|
||||
\tfloat4 texcoord : TEXCOORD0;
|
||||
\tfloat4 texcoord1 : TEXCOORD1;
|
||||
\tfloat4 tangent : TANGENT;
|
||||
\tfloat4 color : COLOR;
|
||||
};
|
||||
"""
|
||||
|
||||
v2f_postype = "POSITION" if legacy else "SV_POSITION"
|
||||
struct_v2f = f"""struct v2f {{
|
||||
\tfloat4 pos : {v2f_postype};
|
||||
\tfloat4 t0 : TEXCOORD0;
|
||||
\tfloat4 t1 : TEXCOORD1;
|
||||
\tfloat4 t2 : TEXCOORD2;
|
||||
\tfloat4 t3 : TEXCOORD3;
|
||||
\tfloat fog : FOG;
|
||||
\tfloat4 d0 : COLOR0;
|
||||
\tfloat4 d1 : COLOR1;
|
||||
}};
|
||||
"""
|
||||
|
||||
struct_f2a = """struct f2a {
|
||||
\tfloat4 c0 : COLOR0;
|
||||
};
|
||||
"""
|
||||
|
||||
cg_header = """CGPROGRAM
|
||||
#include "UnityCG.cginc"
|
||||
#pragma exclude_renderers xbox360 ps3 gles
|
||||
"""
|
||||
|
||||
cg_footer = """ENDCG"""
|
||||
|
||||
vertex_func = """v2f vert(a2v vdat) {{
|
||||
\tfloat4 r0, r1, r2, r3, r4;
|
||||
\tfloat4 tmp;
|
||||
\tv2f o;
|
||||
|
||||
{0}
|
||||
|
||||
\treturn o;
|
||||
}}
|
||||
"""
|
||||
|
||||
fragment_func = """f2a frag(v2f pdat) {{
|
||||
\tfloat4 r0, r1, r2, r3, r4;
|
||||
\tfloat4 tmp;
|
||||
\tf2a o;
|
||||
|
||||
{0}
|
||||
|
||||
\treturn o;
|
||||
}}
|
||||
"""
|
||||
|
||||
def process_header(prog):
|
||||
keywords = []
|
||||
loctab = {}
|
||||
locdecl = []
|
||||
binds = []
|
||||
i = 0
|
||||
lighting = False
|
||||
textures = 0
|
||||
while i < len(prog):
|
||||
line = prog[i]
|
||||
if line.startswith("Keywords"):
|
||||
keywords = re.findall("\"[\w\d]+\"", line)
|
||||
del prog[i]
|
||||
i = i - 1
|
||||
elif line.startswith("Bind"):
|
||||
binds.append(line)
|
||||
del prog[i]
|
||||
i = i - 1
|
||||
elif line.startswith("Local") or line.startswith("Matrix"):
|
||||
dec = line.split(' ')
|
||||
key = int(dec[1][:-1])
|
||||
if dec[2][0] == '[':
|
||||
# singleton
|
||||
val = dec[2][1:-1]
|
||||
if val[0] == '_' and val not in reserved:
|
||||
loctype = "float4" if dec[0] == "Local" else "float4x4"
|
||||
locdecl.append(f"{loctype} {val};")
|
||||
elif dec[2][0] == '(':
|
||||
#components
|
||||
vals = dec[2][1:-1].split(',')
|
||||
for j, v in enumerate(vals):
|
||||
if v[0] == '[':
|
||||
vals[j] = v[1:-1]
|
||||
if vals[j][0] == '_' and vals[j] not in reserved:
|
||||
locdecl.append(f"float {vals[j]};")
|
||||
val = f"float4({vals[0]},{vals[1]},{vals[2]},{vals[3]})"
|
||||
|
||||
lightval = re.match("glstate_light(\d)_([a-zA-Z]+)", val)
|
||||
if lightval:
|
||||
val = f"glstate.light[{lightval[1]}].{lightval[2]}"
|
||||
lighting = True
|
||||
elif val == "_ObjectSpaceCameraPos" and not legacy:
|
||||
val = "mul(_World2Object, float4(_WorldSpaceCameraPos, 1.0f))"
|
||||
elif val == "_ObjectSpaceLightPos0" and not legacy:
|
||||
val = "mul(_World2Object, _WorldSpaceLightPos0)"
|
||||
lighting = True
|
||||
elif val == "glstate_lightmodel_ambient":
|
||||
val = "glstate.lightmodel.ambient"
|
||||
lighting = True
|
||||
elif val.startswith("glstate_matrix_texture"):
|
||||
val = f"glstate.matrix.texture[{val[-1]}]" if legacy else f"UNITY_MATRIX_TEXTURE{val[-1]}"
|
||||
elif val == "glstate_matrix_mvp":
|
||||
val = "glstate.matrix.mvp" if legacy else "UNITY_MATRIX_MVP"
|
||||
elif val == "glstate_matrix_modelview0":
|
||||
val = "glstate.matrix.modelview[0]" if legacy else "UNITY_MATRIX_MV"
|
||||
elif val == "glstate_matrix_transpose_modelview0":
|
||||
val = "glstate.matrix.transpose.modelview[0]" if legacy else "UNITY_MATRIX_T_MV"
|
||||
elif val == "glstate_matrix_invtrans_modelview0":
|
||||
val = "glstate.matrix.invtrans.modelview[0]" if legacy else "UNITY_MATRIX_IT_MV"
|
||||
elif val.startswith("glstate"):
|
||||
raise ValueError(f"Unrecognized glstate: {val}")
|
||||
|
||||
if dec[0] == "Local":
|
||||
loctab[f"c{key}"] = val
|
||||
elif dec[0] == "Matrix":
|
||||
for offset in range(0,4):
|
||||
loctab[f"c{key + offset}"] = f"{val}[{offset}]"
|
||||
|
||||
del prog[i]
|
||||
i = i - 1
|
||||
elif line.startswith("SetTexture"):
|
||||
dec = line.split(' ')
|
||||
if dec[2] == "{2D}":
|
||||
texture_type = "sampler2D"
|
||||
elif dec[2] == "{3D}":
|
||||
texture_type = "sampler3D"
|
||||
elif dec[2] == "{RECT}":
|
||||
texture_type = "samplerRECT"
|
||||
elif dec[2] == "{CUBE}":
|
||||
texture_type = "samplerCUBE"
|
||||
else:
|
||||
raise ValueError(f"Unknown texture type {dec[2]}")
|
||||
key = f"s{textures}"
|
||||
val = dec[1][1:-1]
|
||||
loctab[key] = val
|
||||
locdecl.append(f"{texture_type} {val};")
|
||||
textures = textures + 1
|
||||
|
||||
del prog[i]
|
||||
i = i - 1
|
||||
i = i + 1
|
||||
|
||||
# print(loctab)
|
||||
|
||||
return (keywords, loctab, locdecl, binds, lighting)
|
||||
|
||||
def resolve_args(args, loctab, consts):
|
||||
for a in range(0, len(args)):
|
||||
arg = args[a]
|
||||
|
||||
neg = ""
|
||||
if arg[0] == '-':
|
||||
arg = arg[1:]
|
||||
neg = "-"
|
||||
|
||||
# save swizzler!
|
||||
dot = arg.find(".")
|
||||
if dot > -1:
|
||||
swiz = arg[dot:]
|
||||
arg = arg[:dot]
|
||||
else:
|
||||
swiz = ""
|
||||
|
||||
if arg[0] == 'r':
|
||||
pass
|
||||
elif arg[0] == 'v':
|
||||
pass
|
||||
elif arg[0] == 't':
|
||||
pass
|
||||
elif arg[0] == 'c':
|
||||
if arg not in consts:
|
||||
arg = loctab[arg]
|
||||
elif arg[0] == 's':
|
||||
arg = loctab[arg]
|
||||
elif arg[0] == 'o':
|
||||
arg = f"o.{arg[1:].lower()}"
|
||||
elif re.match("[+-]?([0-9]*[.])?[0-9]+", arg):
|
||||
pass
|
||||
else:
|
||||
raise ValueError(f"Unknown arg {arg}")
|
||||
|
||||
args[a] = neg + arg + swiz
|
||||
|
||||
def get_cgtex_type(name, locdecl):
|
||||
for loc in locdecl:
|
||||
loc = loc.split(' ')
|
||||
if name == loc[1][:-1]:
|
||||
if loc[0] == 'sampler2D':
|
||||
return "tex2D"
|
||||
elif loc[0] == 'sampler3D':
|
||||
return "tex3D"
|
||||
elif loc[0] == 'samplerCUBE':
|
||||
return "texCUBE"
|
||||
elif loc[0] == 'samplerRECT':
|
||||
return "texRECT"
|
||||
else:
|
||||
raise ValueError(f"Unknown CG texture type {loc[0]}")
|
||||
raise ValueError(f"Could not find texture {name} in locals")
|
||||
|
||||
def decode(code, args, locdecl):
|
||||
if code in decls:
|
||||
return [decls[code].format(*args)]
|
||||
elif code in ops:
|
||||
target = args[0]
|
||||
if target == "o.fog":
|
||||
return [ops[code].format(*args)]
|
||||
|
||||
dot = re.search("\.[xyzw]+", target)
|
||||
if dot:
|
||||
swiz = target[dot.start()+1:]
|
||||
target = target[:dot.start()]
|
||||
else:
|
||||
swiz = "xyzw"
|
||||
|
||||
if code == "texld":
|
||||
lines = [ops[code].format("tmp", *args[1:], get_cgtex_type(args[2], locdecl))]
|
||||
else:
|
||||
lines = [ops[code].format("tmp", *args[1:])]
|
||||
|
||||
for c in swiz:
|
||||
lines.append(f"{target}.{c} = tmp.{c};")
|
||||
return lines
|
||||
else:
|
||||
raise ValueError(f"Unknown opcode {code}")
|
||||
|
||||
def process_asm(asm, loctab, locdecl):
|
||||
shadertype = ""
|
||||
if asm[0] == "\"vs_1_1":
|
||||
shadertype = "vertex"
|
||||
elif asm[0] == "\"ps_2_0":
|
||||
shadertype = "fragment"
|
||||
else:
|
||||
raise ValueError(f"Unsupported shader type: {asm[0][1:]}")
|
||||
|
||||
consts = set()
|
||||
translated = []
|
||||
i = 1
|
||||
while i < len(asm):
|
||||
instruction = asm[i]
|
||||
if instruction == "\"":
|
||||
break
|
||||
|
||||
space = instruction.find(" ")
|
||||
if space == -1:
|
||||
code = instruction
|
||||
args = []
|
||||
else:
|
||||
code = instruction[:space]
|
||||
args = instruction[space+1:].split(", ")
|
||||
|
||||
if code == "def":
|
||||
consts.add(args[0])
|
||||
|
||||
pp = code.find("_pp")
|
||||
if pp > -1:
|
||||
code = code[:pp]
|
||||
|
||||
resolve_args(args, loctab, consts)
|
||||
disasm = decode(code, args, locdecl)
|
||||
# print(f"{instruction} \t==>\t{disasm}")
|
||||
disasm.insert(0, f"// {instruction}")
|
||||
translated.extend(disasm)
|
||||
i = i + 1
|
||||
|
||||
return (shadertype, translated)
|
||||
|
||||
def disassemble(blocks):
|
||||
shaders = {}
|
||||
keywords = set()
|
||||
locdecl = set()
|
||||
binds = set()
|
||||
lighting = False
|
||||
for block in blocks:
|
||||
asm = block.split('\n')[1:-1]
|
||||
|
||||
(kw, ltab, ldecl, bds, light) = process_header(asm)
|
||||
keywords.update(kw)
|
||||
locdecl.update(ldecl)
|
||||
binds.update(bds)
|
||||
lighting |= light
|
||||
|
||||
(shadertype, disasm) = process_asm(asm, ltab, locdecl)
|
||||
shaders[shadertype] = disasm
|
||||
|
||||
text = ""
|
||||
if len(binds) > 0:
|
||||
text += "BindChannels {\n"
|
||||
for b in binds:
|
||||
text += f"\t{b}\n"
|
||||
text += "}\n"
|
||||
|
||||
if lighting:
|
||||
text += "Lighting On\n"
|
||||
|
||||
text += cg_header
|
||||
if len(keywords) > 0:
|
||||
text += "#pragma multi_compile " + " ".join(keywords)
|
||||
if "vertex" in shaders:
|
||||
text += "#pragma vertex vert\n"
|
||||
if "fragment" in shaders:
|
||||
text += "#pragma fragment frag\n"
|
||||
text += "\n"
|
||||
if "vertex" in shaders:
|
||||
text += struct_a2v + "\n"
|
||||
text += struct_v2f + "\n"
|
||||
if "fragment" in shaders:
|
||||
text += struct_f2a + "\n"
|
||||
text += "\n".join(locdecl) + "\n"
|
||||
if "vertex" in shaders:
|
||||
text += "\n" + vertex_func.format("\t" + "\n\t".join(shaders["vertex"]))
|
||||
if "fragment" in shaders:
|
||||
text += "\n" + fragment_func.format("\t" + "\n\t".join(shaders["fragment"]))
|
||||
text += cg_footer
|
||||
return text
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: disassembler.py <filename>")
|
||||
else:
|
||||
with open(sys.argv[1], "r") as fi:
|
||||
buf = fi.read()
|
||||
disasm = disassemble(buf.split('~'))
|
||||
print(disasm)
|
|
@ -0,0 +1,37 @@
|
|||
#!/usr/bin/env python
|
||||
# coding: utf-8
|
||||
|
||||
import os
|
||||
import sys
|
||||
from .swapper import process
|
||||
|
||||
def process_file(filename, suffix):
|
||||
dot = filename.rfind(".")
|
||||
if dot > -1:
|
||||
outfile_name = filename[:dot] + suffix + filename[dot:]
|
||||
else:
|
||||
outfile_name = filename + suffix
|
||||
return process(filename, outfile_name)
|
||||
|
||||
def process_batch(path, suffix="_hlsl"):
|
||||
files = os.listdir(path)
|
||||
for f in files:
|
||||
if os.path.isdir(f):
|
||||
process_batch(f"{path}/{f}")
|
||||
else:
|
||||
try:
|
||||
if process_file(f"{path}/{f}", suffix):
|
||||
print(f"Processed {f}")
|
||||
else:
|
||||
print(f"Skipping {f}")
|
||||
except ValueError as err:
|
||||
print(f"Failed to process {f}: {err}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: main.py <folder> [outfile-suffix]")
|
||||
elif len(sys.argv) == 2:
|
||||
process_batch(sys.argv[1])
|
||||
else:
|
||||
process_batch(*sys.argv[1:3])
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
#!/usr/bin/env python
|
||||
# coding: utf-8
|
||||
# parser for replacing d3d9 subprograms in shaderlab files with HLSL/CG
|
||||
# ycc 08/08/2022
|
||||
|
||||
import re
|
||||
import sys
|
||||
from .disassembler import disassemble
|
||||
|
||||
tabs = 3
|
||||
def indent(block):
|
||||
lines = block.split('\n')
|
||||
for i in range(0, len(lines)-1):
|
||||
lines[i] = tabs * "\t" + lines[i]
|
||||
return "\n".join(lines)
|
||||
|
||||
def find_closing_bracket(block, i):
|
||||
count = 0
|
||||
while i < len(block):
|
||||
if block[i] == '{':
|
||||
count = count + 1
|
||||
if block[i] == '}':
|
||||
count = count - 1
|
||||
if count == 0:
|
||||
return i
|
||||
i = i + 1
|
||||
raise ValueError(f"Block at {i} has no closing bracket")
|
||||
|
||||
def process_program(prog):
|
||||
# print("processing:\n" + prog)
|
||||
subprogs = []
|
||||
subprog_index = prog.find("SubProgram \"d3d9")
|
||||
while subprog_index > -1:
|
||||
subprog_end_index = find_closing_bracket(prog, subprog_index)
|
||||
subprog = prog[subprog_index:subprog_end_index+1]
|
||||
subprogs.append(subprog)
|
||||
prog = prog[subprog_end_index+1:]
|
||||
subprog_index = prog.find("SubProgram \"d3d9")
|
||||
if len(subprogs) < 1:
|
||||
raise ValueError(f"Program has no d3d9 subprograms")
|
||||
processed = disassemble(subprogs) + "\n"
|
||||
return indent(processed)
|
||||
|
||||
def process_shader(shader):
|
||||
buf = shader
|
||||
processed = ''
|
||||
program_index = buf.find("Program \"\"")
|
||||
while program_index > -1:
|
||||
processed = processed + buf[:program_index]
|
||||
buf = buf[program_index:]
|
||||
line = re.search("#LINE [0-9]+\n", buf)
|
||||
if not line:
|
||||
raise ValueError(f"Program at {program_index} has no #LINE marker")
|
||||
end_index = line.end() + 1
|
||||
program_section = buf[:end_index+1]
|
||||
processed = processed + process_program(program_section)
|
||||
buf = buf[end_index+1:]
|
||||
|
||||
program_index = buf.find("Program \"\"")
|
||||
processed = processed + buf
|
||||
return processed
|
||||
|
||||
def process(fn_in, fn_out):
|
||||
with open(fn_in, "r") as fi:
|
||||
buf = fi.read()
|
||||
processed = process_shader(buf)
|
||||
if buf != processed:
|
||||
with open(fn_out, "w") as fo:
|
||||
fo.write(processed)
|
||||
return True
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) < 3:
|
||||
print("Usage: swapper.py <file-in> <file-out>")
|
||||
else:
|
||||
process(*sys.argv[1:3])
|
|
@ -0,0 +1,2 @@
|
|||
.vscode
|
||||
xdt*.json
|
|
@ -0,0 +1,9 @@
|
|||
# json2xdb
|
||||
This script populates a functional, near-complete FusionFall XDB tabledata server.
|
||||
You need an existing MySQL server (an old version; 5.5.42 seems to work with the FusionFall client). This can be set up pretty easily using Docker.
|
||||
You also need a copy of xdt.json from the [OpenFusion tabledata repository](https://github.com/OpenFusionProject/tabledata).
|
||||
|
||||
It is interesting to note that the JSON tabledata file is really just a Unity ScriptableObject containing all the XDT/XDB state packaged into a FusionFall client build. The devs likely kept a central tabledata server around (XDB) and, whenever it was time for a client build, they fetched it into local binary files (XDT) before finally packing them into the XdtTableScript asset.
|
||||
|
||||
I would like to thank my girlfriend for showing me the wonders of `tqdm`. It really helped being able to see that things were happening.
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# Uses default credentials
|
||||
version: '3.1'
|
||||
|
||||
services:
|
||||
db:
|
||||
image: mysql:5.5.42
|
||||
command: --character-set-server utf8
|
||||
restart: always
|
||||
ports:
|
||||
- 3306:3306
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: mypassword
|
||||
MYSQL_DATABASE: XDB
|
|
@ -0,0 +1,76 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def to_db_table_name_mappings(table):\n",
|
||||
" mappings = {}\n",
|
||||
" for subtable_name in table:\n",
|
||||
" mappings[subtable_name] = \"\"\n",
|
||||
" return mappings"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def gen_mappings(xdt):\n",
|
||||
" mappings = {}\n",
|
||||
" for table_name in xdt:\n",
|
||||
" if \"table\" not in table_name.lower():\n",
|
||||
" continue\n",
|
||||
" table = xdt[table_name]\n",
|
||||
" mappings[table_name] = to_db_table_name_mappings(table)\n",
|
||||
" return mappings\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"with open('xdt.json', 'r') as f:\n",
|
||||
" xdt = json.load(f)\n",
|
||||
"mappings = gen_mappings(xdt)\n",
|
||||
"with open('mappings.json', 'w') as f:\n",
|
||||
" json.dump(mappings, f, indent=4)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.12"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
|
@ -0,0 +1,222 @@
|
|||
# %%
|
||||
import json
|
||||
import sys
|
||||
from tqdm import tqdm
|
||||
import mysql.connector
|
||||
|
||||
SPLIT_FIELDS = {
|
||||
"m_iMissionRewardItem": ("m_iMissionRewardItemID", "m_iMissionRewarItemType"),
|
||||
"m_iMissionRewardItem2": ("m_iMissionRewardItemID2", "m_iMissionRewardItemType2"),
|
||||
"m_iCSTItem": ("m_iCSTItemID", "m_iCSTItemNumNeeded"),
|
||||
"m_iCSUEnemy": ("m_iCSUEnemyID", "m_iCSUNumToKill"),
|
||||
"m_iCSUItem": ("m_iCSUItemID", "m_iCSUItemNumNeeded"),
|
||||
"m_iSTItem": ("m_iSTItemID", "m_iSTItemNumNeeded", "m_iSTItemDropRate"),
|
||||
"m_iSUItem_": ("m_iSUItem", "m_iSUInstancename"),
|
||||
"m_iFItem": ("m_iFItemID", "m_iFItemNumNeeded"),
|
||||
}
|
||||
|
||||
# %%
|
||||
def get_db_column_name(xdt_field_name):
|
||||
# special case 1
|
||||
if xdt_field_name == "m_iitemID":
|
||||
return "ItemID"
|
||||
|
||||
try:
|
||||
# find the first uppercase character and split the string there
|
||||
idx_of_first_uppercase = next(i for i, c in enumerate(xdt_field_name) if c.isupper())
|
||||
except StopIteration:
|
||||
# special case 2
|
||||
if xdt_field_name == "m_ibattery":
|
||||
idx_of_first_uppercase = 3
|
||||
else:
|
||||
print(f"Could not find uppercase character in {xdt_field_name}")
|
||||
sys.exit(1)
|
||||
prefix = xdt_field_name[:idx_of_first_uppercase]
|
||||
db_field_name = xdt_field_name[idx_of_first_uppercase:]
|
||||
return db_field_name
|
||||
|
||||
# %%
|
||||
def table_entry_to_tuple(table_entry):
|
||||
vals = []
|
||||
for field_name in table_entry:
|
||||
field = table_entry[field_name]
|
||||
vals.append(field)
|
||||
return tuple(vals)
|
||||
|
||||
def flatten_table_entry(table_entry):
|
||||
flattened_entry = {}
|
||||
for field_name in table_entry:
|
||||
field = table_entry[field_name]
|
||||
if type(field) == list:
|
||||
for i, item in enumerate(field):
|
||||
flattened_entry[f"{field_name}{i}"] = item
|
||||
else:
|
||||
flattened_entry[field_name] = field
|
||||
return flattened_entry
|
||||
|
||||
def handle_dict_table(table_entries, identifier_key, items_key):
|
||||
new_table_entries = []
|
||||
for table_entry in table_entries:
|
||||
identifier = table_entry[identifier_key]
|
||||
items = table_entry[items_key]
|
||||
for item in items:
|
||||
new_item = {}
|
||||
new_item[identifier_key] = identifier # needs to be first
|
||||
for field_name in item:
|
||||
new_item[field_name] = item[field_name]
|
||||
new_table_entries.append(new_item)
|
||||
return new_table_entries
|
||||
|
||||
def apply_schema(schema, entry):
|
||||
fixed_entry = {}
|
||||
padding = 0
|
||||
for field_name in schema:
|
||||
if field_name is None:
|
||||
fixed_entry[f"m_iPadding{padding}"] = 0
|
||||
padding += 1
|
||||
continue
|
||||
|
||||
if field_name in entry:
|
||||
fixed_entry[field_name] = entry[field_name]
|
||||
elif field_name in SPLIT_FIELDS:
|
||||
split_field_names = SPLIT_FIELDS[field_name]
|
||||
interleaved_arr_len = len(entry[split_field_names[0]])
|
||||
val = []
|
||||
for i in range(interleaved_arr_len):
|
||||
for split_field_name in split_field_names:
|
||||
val.append(entry[split_field_name][i])
|
||||
for l in range(len(val)):
|
||||
n = l % len(split_field_names)
|
||||
i = l // len(split_field_names)
|
||||
new_field_name = f"{split_field_names[n]}{i}"
|
||||
fixed_entry[new_field_name] = val[l]
|
||||
else:
|
||||
print("Missing field: {}".format(field_name))
|
||||
return fixed_entry
|
||||
|
||||
# %%
|
||||
def gen_column_sql(field_name, field_value):
|
||||
field_type = type(field_value)
|
||||
if field_type == int:
|
||||
return f"`{field_name}` INT,"
|
||||
elif field_type == float:
|
||||
return f"`{field_name}` FLOAT,"
|
||||
elif field_type == str:
|
||||
# TODO maybe ascii vs unicode?
|
||||
return f"`{field_name}` TEXT,"
|
||||
else:
|
||||
print(f"Unknown type {field_type} for field {field_name}, skipping")
|
||||
return ""
|
||||
|
||||
# %%
|
||||
def table_create(cursor, table_name, xdt_template_entry):
|
||||
sql = f"CREATE TABLE {table_name} ("
|
||||
sql += "id INT AUTO_INCREMENT PRIMARY KEY,"
|
||||
for field_name in xdt_template_entry:
|
||||
db_field_name = get_db_column_name(field_name)
|
||||
val = xdt_template_entry[field_name]
|
||||
sql += gen_column_sql(db_field_name, val)
|
||||
sql = sql[:-1] # remove trailing comma
|
||||
sql += ")"
|
||||
cursor.execute(sql)
|
||||
|
||||
# %%
|
||||
def table_populate(cursor, table_name, table_entries):
|
||||
# generate the SQL first
|
||||
sql = f"INSERT INTO {table_name} ("
|
||||
template_entry = table_entries[0]
|
||||
for field_name in template_entry:
|
||||
db_field_name = get_db_column_name(field_name)
|
||||
sql += f"`{db_field_name}`,"
|
||||
sql = sql[:-1] # remove trailing comma
|
||||
sql += ") VALUES ("
|
||||
for field_name in template_entry:
|
||||
sql += f"%s,"
|
||||
sql = sql[:-1] # remove trailing comma
|
||||
sql += ")"
|
||||
|
||||
vals = [table_entry_to_tuple(entry) for entry in table_entries]
|
||||
try:
|
||||
cursor.executemany(sql, vals)
|
||||
except Exception as e:
|
||||
print(sql)
|
||||
print(vals)
|
||||
raise e
|
||||
|
||||
# %%
|
||||
def process_xdt_table(cursor, root, table_name, mappings):
|
||||
table = root[table_name]
|
||||
for subtable_name in tqdm(table, desc=table_name, total=len(table)):
|
||||
if subtable_name not in mappings[table_name]:
|
||||
print(f"No mapping found for {table_name}.{subtable_name}")
|
||||
raise Exception()
|
||||
db_table_name = mappings[table_name][subtable_name]
|
||||
with open(f"schema/{db_table_name}.json", 'r') as f:
|
||||
schema = json.load(f)
|
||||
#print(f"{subtable_name} => {db_table_name}")
|
||||
|
||||
table_entries = table[subtable_name]
|
||||
if db_table_name == "CutSceneText":
|
||||
table_entries = handle_dict_table(table_entries, "m_iEvent", "m_TextElement")
|
||||
table_entries = [apply_schema(schema, entry) for entry in table_entries]
|
||||
table_entries = [flatten_table_entry(entry) for entry in table_entries]
|
||||
|
||||
# clear the table
|
||||
drop_sql = f"DROP TABLE IF EXISTS {db_table_name}"
|
||||
cursor.execute(drop_sql)
|
||||
|
||||
# create the table
|
||||
table_create(cursor, db_table_name, table_entries[0])
|
||||
table_populate(cursor, db_table_name, table_entries)
|
||||
|
||||
# %%
|
||||
def main(conn, xdt_path):
|
||||
with open("mappings.json", 'r') as f:
|
||||
mappings = json.load(f)
|
||||
with open(xdt_path, 'r') as f:
|
||||
root = json.load(f)
|
||||
cursor = conn.cursor()
|
||||
for table_name in root:
|
||||
if "Table" in table_name:
|
||||
process_xdt_table(cursor, root, table_name, mappings)
|
||||
finalize(cursor)
|
||||
conn.commit()
|
||||
|
||||
def connect_to_db():
|
||||
return mysql.connector.connect(
|
||||
host="localhost",
|
||||
user="root",
|
||||
password="mypassword",
|
||||
database="XDB"
|
||||
)
|
||||
|
||||
def prep_db():
|
||||
conn = connect_to_db()
|
||||
cursor = conn.cursor()
|
||||
# we have to upload a lot of data, so we need to raise the limit
|
||||
cursor.execute("SET GLOBAL max_allowed_packet=1073741824")
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
def finalize(cursor):
|
||||
# credentials used by the game
|
||||
cursor.execute("GRANT SELECT ON XDB.* TO 'cmog' IDENTIFIED BY 'scooby'")
|
||||
# change the root password to something more secure
|
||||
new_root_pw = input("Enter new root password: ")
|
||||
cursor.execute(f"SET PASSWORD = PASSWORD('{new_root_pw}')")
|
||||
|
||||
# %%
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) != 2:
|
||||
print("Usage: python3 json2xdb.py <path to xdt file>")
|
||||
sys.exit(1)
|
||||
xdt_path = sys.argv[1]
|
||||
prep_db()
|
||||
conn = connect_to_db()
|
||||
main(conn, xdt_path)
|
||||
conn.close()
|
||||
|
||||
# %%
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,232 @@
|
|||
{
|
||||
"m_pAnimationTable": {
|
||||
"m_pAvatarData": "M",
|
||||
"m_pNpcData": "Mob",
|
||||
"m_pNanoData": "Nano"
|
||||
},
|
||||
"m_pAvatarTable": {
|
||||
"m_pAvatarData": "AvatarTable",
|
||||
"m_pAvatarGrowData": "AvatarGrowTable"
|
||||
},
|
||||
"m_pChatTable": {
|
||||
"m_pFirstChatData": "1stChatTable",
|
||||
"m_pSecondChatData": "2ndChatTable",
|
||||
"m_pThirdChatData": "3rdChatTable",
|
||||
"m_pChatStringData": "ChatString",
|
||||
"m_pMenuChatData": "ChatTable",
|
||||
"m_pMenuChatClassData": "ClassTable",
|
||||
"m_pMenuChatEmoteData": "EmoteLink"
|
||||
},
|
||||
"m_pEmoteTable": {
|
||||
"m_pEmoteAnimationData": "EmoteTable",
|
||||
"m_pEmoteTextureData": "EmoteTexture"
|
||||
},
|
||||
"m_pGuideTable": {
|
||||
"m_pGuideData": "GuideTable",
|
||||
"m_pGuideStringData": "GuideStringTable"
|
||||
},
|
||||
"m_pInstanceTable": {
|
||||
"m_pInstanceData": "InstanceTable",
|
||||
"m_pWarpData": "WarpTable",
|
||||
"m_pWarpNameData": "NameString"
|
||||
},
|
||||
"m_pMessageTable": {
|
||||
"m_pMessageData": "SystemMessage"
|
||||
},
|
||||
"m_pMissionTable": {
|
||||
"m_pJournalData": "Journal_ID",
|
||||
"m_pMissionData": "MissionField",
|
||||
"m_pMissionStringData": "MissionStringTable",
|
||||
"m_pRewardData": "Reward"
|
||||
},
|
||||
"m_pNameTable": {
|
||||
"m_pFirstName": "FirstNameTable",
|
||||
"m_pMiddleName": "MiddleNameTable",
|
||||
"m_pLastName": "LastNameTable"
|
||||
},
|
||||
"m_pNanoTable": {
|
||||
"m_pNanoData": "NanoTable",
|
||||
"m_pNanoStringData": "NanoString",
|
||||
"m_pNanoMeshData": "NanoMesh",
|
||||
"m_pNanoIconData": "NanoIcon",
|
||||
"m_pNanoTuneData": "NanoTuneTable",
|
||||
"m_pNanoTuneStringData": "NanoTuneString",
|
||||
"m_pNanoTuneIconData": "NanoTuneIcon"
|
||||
},
|
||||
"m_pNpcTable": {
|
||||
"m_pNpcData": "NpcTable",
|
||||
"m_pNpcStringData": "NpcString",
|
||||
"m_pNpcBarkerData": "BarkerTable",
|
||||
"m_pNpcMeshData": "NpcMesh",
|
||||
"m_pNpcIconData": "NpcIcon",
|
||||
"m_pNpcGroupData": "NpcGroup",
|
||||
"m_pNpcServiceData": "ServiceString"
|
||||
},
|
||||
"m_pShinyTable": {
|
||||
"m_pShinyData": "ShinyTable",
|
||||
"m_pShinyStringData": "ShinyString",
|
||||
"m_pShinyMeshData": "ShinyMesh"
|
||||
},
|
||||
"m_pSkillTable": {
|
||||
"m_pSkillData": "SkillTable",
|
||||
"m_pSkillBuffData": "SkillBuffEffect",
|
||||
"m_pSkillIconData": "SkillIcon",
|
||||
"m_pSkillStringData": "SkillString"
|
||||
},
|
||||
"m_pConditionTable": {
|
||||
"m_pConditionData": "StatusTable"
|
||||
},
|
||||
"m_pTransportationTable": {
|
||||
"m_pTransportationMeshData": "TransportationMesh",
|
||||
"m_pTransportationData": "TransportationTable",
|
||||
"m_pTransportationWarpLocation": "WarpLocationTable",
|
||||
"m_pTransportationWarpString": "TransportationWarpString",
|
||||
"m_pBroomstickLocation": "WyvernLocationTable",
|
||||
"m_pBroomstickString": "TransportationWyvernString",
|
||||
"m_pTransIcon": "TransIcon"
|
||||
},
|
||||
"m_pVendorTable": {
|
||||
"m_pItemData": "VendorTable"
|
||||
},
|
||||
"m_pXComTable": {
|
||||
"m_pXComData": "XComTable"
|
||||
},
|
||||
"m_pBackItemTable": {
|
||||
"m_pItemData": "ItemBackTable",
|
||||
"m_pItemStringData": "ItemBackString",
|
||||
"m_pItemIconData": "ItemBackIcon",
|
||||
"m_pItemMeshData": "ItemBackMesh",
|
||||
"m_pItemSoundData": "ItemBackSound"
|
||||
},
|
||||
"m_pFaceItemTable": {
|
||||
"m_pItemData": "ItemFaceTable",
|
||||
"m_pItemStringData": "ItemFaceString",
|
||||
"m_pItemIconData": "ItemFaceIcon",
|
||||
"m_pItemMeshData": "ItemFaceMesh",
|
||||
"m_pItemSoundData": "ItemFaceSound"
|
||||
},
|
||||
"m_pGlassItemTable": {
|
||||
"m_pItemData": "ItemGlassTable",
|
||||
"m_pItemStringData": "ItemGlassString",
|
||||
"m_pItemIconData": "ItemGlassIcon",
|
||||
"m_pItemMeshData": "ItemGlassMesh",
|
||||
"m_pItemSoundData": "ItemGlassSound"
|
||||
},
|
||||
"m_pHatItemTable": {
|
||||
"m_pItemData": "ItemHatTable",
|
||||
"m_pItemStringData": "ItemHatString",
|
||||
"m_pItemIconData": "ItemHatIcon",
|
||||
"m_pItemMeshData": "ItemHatMesh",
|
||||
"m_pItemSoundData": "ItemHatSound"
|
||||
},
|
||||
"m_pHeadItemTable": {
|
||||
"m_pItemData": "ItemHeadTable",
|
||||
"m_pItemStringData": "ItemHeadString",
|
||||
"m_pItemIconData": "ItemHeadIcon",
|
||||
"m_pItemMeshData": "ItemHeadMesh",
|
||||
"m_pItemSoundData": "ItemHeadSound"
|
||||
},
|
||||
"m_pPantsItemTable": {
|
||||
"m_pItemData": "ItemPantsTable",
|
||||
"m_pItemStringData": "ItemPantsString",
|
||||
"m_pItemIconData": "ItemPantsIcon",
|
||||
"m_pItemMeshData": "ItemPantsMesh",
|
||||
"m_pItemSoundData": "ItemPantsSound"
|
||||
},
|
||||
"m_pShirtsItemTable": {
|
||||
"m_pItemData": "ItemShirtTable",
|
||||
"m_pItemStringData": "ItemShirtString",
|
||||
"m_pItemIconData": "ItemShirtIcon",
|
||||
"m_pItemMeshData": "ItemShirtMesh",
|
||||
"m_pItemSoundData": "ItemShirtSound"
|
||||
},
|
||||
"m_pShoesItemTable": {
|
||||
"m_pItemData": "ItemShoesTable",
|
||||
"m_pItemStringData": "ItemShoesString",
|
||||
"m_pItemIconData": "ItemShoesIcon",
|
||||
"m_pItemMeshData": "ItemShoesMesh",
|
||||
"m_pItemSoundData": "ItemShoesSound"
|
||||
},
|
||||
"m_pWeaponItemTable": {
|
||||
"m_pItemData": "ItemWpnTable",
|
||||
"m_pItemStringData": "ItemWpnString",
|
||||
"m_pItemIconData": "ItemWpnIcon",
|
||||
"m_pItemMeshData": "ItemWpnMesh",
|
||||
"m_pItemSoundData": "ItemWpnSound"
|
||||
},
|
||||
"m_pVehicleItemTable": {
|
||||
"m_pItemData": "ItemVehicleTable",
|
||||
"m_pItemStringData": "ItemVehicleString",
|
||||
"m_pItemIconData": "ItemVehicleIcon",
|
||||
"m_pItemMeshData": "ItemVehicleMesh",
|
||||
"m_pItemSoundData": "ItemVehicleSound"
|
||||
},
|
||||
"m_pGeneralItemTable": {
|
||||
"m_pItemData": "ItemGeneralTable",
|
||||
"m_pItemStringData": "ItemGeneralString",
|
||||
"m_pItemIconData": "ItemGeneralIcon"
|
||||
},
|
||||
"m_pChestItemTable": {
|
||||
"m_pItemData": "ItemChestTable",
|
||||
"m_pItemStringData": "ItemChestString",
|
||||
"m_pItemIconData": "ChestIconTable"
|
||||
},
|
||||
"m_pQuestItemTable": {
|
||||
"m_pItemData": "ItemQuestTable",
|
||||
"m_pItemStringData": "ItemQuestString",
|
||||
"m_pItemIconData": "ItemQuestIcon"
|
||||
},
|
||||
"m_pCreationItemTable": {
|
||||
"m_pCreationItemData": "ItemCreationTable"
|
||||
},
|
||||
"m_pFirstUseTable": {
|
||||
"m_pFirstUseData": "FirstUseTable",
|
||||
"m_pFirstUseString": "FirstUseString"
|
||||
},
|
||||
"m_pRulesTable": {
|
||||
"m_pRulesData": "RulesTable",
|
||||
"m_pRulesString": "RulesString"
|
||||
},
|
||||
"m_pHelpTable": {
|
||||
"m_pHelpData": "HelpTable",
|
||||
"m_pHelpPageData": "DescriptionTable",
|
||||
"m_pHelpPageDescData": "Description",
|
||||
"m_pHelpPageString": "DescriptionString",
|
||||
"m_pHelpString": "HelpString"
|
||||
},
|
||||
"m_pCutSceneTable": {
|
||||
"m_SceneData": "CutSceneText"
|
||||
},
|
||||
"m_pCombiningTable": {
|
||||
"m_pCombiningData": "CombiningTable"
|
||||
},
|
||||
"m_pFilterTable": {
|
||||
"m_pWhiteFilterData": "UnfilterTable",
|
||||
"m_pBlackFilterData": "FilterTable",
|
||||
"m_pNameFilterData": "NamefilterTable"
|
||||
},
|
||||
"m_pClassTable": {
|
||||
"m_pClassTypeData": "ClassType",
|
||||
"m_pClassWpnTypeData": "ClassWpnType",
|
||||
"m_pClassString": "ClassString",
|
||||
"m_pClassIconData": "ClassIcon"
|
||||
},
|
||||
"m_pEnchantTable": {
|
||||
"m_pEnchantData": "EnchantTable"
|
||||
},
|
||||
"m_pClassSkillTable": {
|
||||
"m_pClassSkillChargingElement": "ClassSkill_Charging",
|
||||
"m_pSkillManagerData": "ClassSkill_Manager",
|
||||
"m_pSkillData": "ClassSkill_Skill",
|
||||
"m_pSkillBuffElement": "ClassSkill_BuffEffect",
|
||||
"m_pSkillString": "ClassSkill_String",
|
||||
"m_pClassSkillCondition": "Condition_Character",
|
||||
"m_pSkillIconData": "ClassSkill_Icon",
|
||||
"m_pSkillSound": "ClassSkill_Sound"
|
||||
},
|
||||
"m_pSkillBookTable": {
|
||||
"m_pSkillBookElement": "ItemSkillBookTable",
|
||||
"m_pSkillBookString": "ItemSkillBookString",
|
||||
"m_pSkillBookIconData": "ItemSkillBookIcon"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,283 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 59,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import json\n",
|
||||
"import sys\n",
|
||||
"from tqdm import tqdm\n",
|
||||
"import mysql.connector"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 60,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def get_db_column_name(xdt_field_name):\n",
|
||||
" # special case 1\n",
|
||||
" if xdt_field_name == \"m_iitemID\":\n",
|
||||
" return \"ItemID\"\n",
|
||||
" \n",
|
||||
" try:\n",
|
||||
" # find the first uppercase character and split the string there\n",
|
||||
" idx_of_first_uppercase = next(i for i, c in enumerate(xdt_field_name) if c.isupper())\n",
|
||||
" except StopIteration:\n",
|
||||
" # special case 2\n",
|
||||
" if xdt_field_name == \"m_ibattery\":\n",
|
||||
" idx_of_first_uppercase = 3\n",
|
||||
" else:\n",
|
||||
" print(f\"Could not find uppercase character in {xdt_field_name}\")\n",
|
||||
" sys.exit(1)\n",
|
||||
" prefix = xdt_field_name[:idx_of_first_uppercase]\n",
|
||||
" db_field_name = xdt_field_name[idx_of_first_uppercase:]\n",
|
||||
" return db_field_name"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 61,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def table_entry_to_tuple(table_entry):\n",
|
||||
" vals = []\n",
|
||||
" for field_name in table_entry:\n",
|
||||
" field = table_entry[field_name]\n",
|
||||
" vals.append(field)\n",
|
||||
" return tuple(vals)\n",
|
||||
"\n",
|
||||
"def flatten_table_entry(table_entry):\n",
|
||||
" flattened_entry = {}\n",
|
||||
" for field_name in table_entry:\n",
|
||||
" field = table_entry[field_name]\n",
|
||||
" if type(field) == list:\n",
|
||||
" for i, item in enumerate(field):\n",
|
||||
" flattened_entry[f\"{field_name}{i}\"] = item\n",
|
||||
" else:\n",
|
||||
" flattened_entry[field_name] = field\n",
|
||||
" return flattened_entry\n",
|
||||
"\n",
|
||||
"def handle_dict_table(table_entries, identifier_key, items_key):\n",
|
||||
" new_table_entries = []\n",
|
||||
" for table_entry in table_entries:\n",
|
||||
" identifier = table_entry[identifier_key]\n",
|
||||
" items = table_entry[items_key]\n",
|
||||
" for item in items:\n",
|
||||
" new_item = {}\n",
|
||||
" new_item[identifier_key] = identifier # needs to be first\n",
|
||||
" for field_name in item:\n",
|
||||
" new_item[field_name] = item[field_name]\n",
|
||||
" new_table_entries.append(new_item)\n",
|
||||
" return new_table_entries\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 62,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def gen_column_sql(field_name, field_value):\n",
|
||||
" field_type = type(field_value)\n",
|
||||
" if field_type == int:\n",
|
||||
" return f\"`{field_name}` INT,\"\n",
|
||||
" elif field_type == float:\n",
|
||||
" return f\"`{field_name}` FLOAT,\"\n",
|
||||
" elif field_type == str:\n",
|
||||
" # TODO maybe ascii vs unicode?\n",
|
||||
" return f\"`{field_name}` TEXT,\"\n",
|
||||
" else:\n",
|
||||
" print(f\"Unknown type {field_type} for field {field_name}, skipping\")\n",
|
||||
" return \"\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 63,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def table_create(cursor, table_name, xdt_template_entry):\n",
|
||||
" sql = f\"CREATE TABLE {table_name} (\"\n",
|
||||
" sql += \"id INT AUTO_INCREMENT PRIMARY KEY,\"\n",
|
||||
" for field_name in xdt_template_entry:\n",
|
||||
" db_field_name = get_db_column_name(field_name)\n",
|
||||
" val = xdt_template_entry[field_name]\n",
|
||||
" sql += gen_column_sql(db_field_name, val)\n",
|
||||
" sql = sql[:-1] # remove trailing comma\n",
|
||||
" sql += \")\"\n",
|
||||
" cursor.execute(sql)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 64,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def table_populate(cursor, table_name, table_entries):\n",
|
||||
" # generate the SQL first\n",
|
||||
" sql = f\"INSERT INTO {table_name} (\"\n",
|
||||
" template_entry = table_entries[0]\n",
|
||||
" for field_name in template_entry:\n",
|
||||
" db_field_name = get_db_column_name(field_name)\n",
|
||||
" sql += f\"`{db_field_name}`,\"\n",
|
||||
" sql = sql[:-1] # remove trailing comma\n",
|
||||
" sql += \") VALUES (\"\n",
|
||||
" for field_name in template_entry:\n",
|
||||
" sql += f\"%s,\"\n",
|
||||
" sql = sql[:-1] # remove trailing comma\n",
|
||||
" sql += \")\"\n",
|
||||
" \n",
|
||||
" vals = [table_entry_to_tuple(entry) for entry in table_entries]\n",
|
||||
" try:\n",
|
||||
" cursor.executemany(sql, vals)\n",
|
||||
" except Exception as e:\n",
|
||||
" print(sql)\n",
|
||||
" print(vals)\n",
|
||||
" raise e"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 65,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def process_xdt_table(cursor, root, table_name, mappings):\n",
|
||||
" table = root[table_name]\n",
|
||||
" for (i, subtable_name) in tqdm(enumerate(table), desc=table_name, total=len(table)):\n",
|
||||
" db_table_name = mappings[table_name][i]\n",
|
||||
" #print(f\"{subtable_name} => {db_table_name}\")\n",
|
||||
" \n",
|
||||
" table_entries = table[subtable_name]\n",
|
||||
" if db_table_name == \"CutSceneText\":\n",
|
||||
" table_entries = handle_dict_table(table_entries, \"m_iEvent\", \"m_TextElement\")\n",
|
||||
" table_entries = [flatten_table_entry(entry) for entry in table_entries]\n",
|
||||
"\n",
|
||||
" # clear the table\n",
|
||||
" drop_sql = f\"DROP TABLE IF EXISTS {db_table_name}\"\n",
|
||||
" cursor.execute(drop_sql)\n",
|
||||
"\n",
|
||||
" # create the table\n",
|
||||
" table_create(cursor, db_table_name, table_entries[0])\n",
|
||||
" table_populate(cursor, db_table_name, table_entries)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 66,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def main(conn, xdt_path):\n",
|
||||
" with open(\"mappings.json\", 'r') as f:\n",
|
||||
" mappings = json.load(f)\n",
|
||||
" with open(xdt_path, 'r') as f:\n",
|
||||
" root = json.load(f)\n",
|
||||
" cursor = conn.cursor()\n",
|
||||
" for table_name in root:\n",
|
||||
" if \"Table\" in table_name:\n",
|
||||
" process_xdt_table(cursor, root, table_name, mappings)\n",
|
||||
" conn.commit()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 67,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"m_pAnimationTable: 100%|██████████| 3/3 [00:00<00:00, 9.30it/s]\n",
|
||||
"m_pAvatarTable: 100%|██████████| 2/2 [00:00<00:00, 5.76it/s]\n",
|
||||
"m_pChatTable: 100%|██████████| 7/7 [00:00<00:00, 9.55it/s]\n",
|
||||
"m_pEmoteTable: 100%|██████████| 2/2 [00:00<00:00, 12.84it/s]\n",
|
||||
"m_pGuideTable: 100%|██████████| 2/2 [00:00<00:00, 11.23it/s]\n",
|
||||
"m_pInstanceTable: 100%|██████████| 3/3 [00:00<00:00, 9.99it/s]\n",
|
||||
"m_pMessageTable: 100%|██████████| 1/1 [00:00<00:00, 8.64it/s]\n",
|
||||
"m_pMissionTable: 100%|██████████| 4/4 [00:01<00:00, 2.57it/s]\n",
|
||||
"m_pNameTable: 100%|██████████| 3/3 [00:00<00:00, 9.74it/s]\n",
|
||||
"m_pNanoTable: 100%|██████████| 7/7 [00:00<00:00, 9.92it/s]\n",
|
||||
"m_pNpcTable: 100%|██████████| 7/7 [00:01<00:00, 4.86it/s]\n",
|
||||
"m_pShinyTable: 100%|██████████| 3/3 [00:00<00:00, 9.07it/s]\n",
|
||||
"m_pSkillTable: 100%|██████████| 4/4 [00:00<00:00, 11.26it/s]\n",
|
||||
"m_pConditionTable: 100%|██████████| 1/1 [00:00<00:00, 11.58it/s]\n",
|
||||
"m_pTransportationTable: 100%|██████████| 7/7 [00:00<00:00, 10.35it/s]\n",
|
||||
"m_pVendorTable: 100%|██████████| 1/1 [00:00<00:00, 4.68it/s]\n",
|
||||
"m_pXComTable: 100%|██████████| 1/1 [00:00<00:00, 9.32it/s]\n",
|
||||
"m_pBackItemTable: 100%|██████████| 5/5 [00:00<00:00, 9.05it/s]\n",
|
||||
"m_pFaceItemTable: 100%|██████████| 5/5 [00:00<00:00, 9.85it/s]\n",
|
||||
"m_pGlassItemTable: 100%|██████████| 5/5 [00:00<00:00, 8.95it/s]\n",
|
||||
"m_pHatItemTable: 100%|██████████| 5/5 [00:00<00:00, 10.58it/s]\n",
|
||||
"m_pHeadItemTable: 100%|██████████| 5/5 [00:00<00:00, 9.31it/s]\n",
|
||||
"m_pPantsItemTable: 100%|██████████| 5/5 [00:00<00:00, 8.16it/s]\n",
|
||||
"m_pShirtsItemTable: 100%|██████████| 5/5 [00:00<00:00, 7.10it/s]\n",
|
||||
"m_pShoesItemTable: 100%|██████████| 5/5 [00:00<00:00, 6.49it/s]\n",
|
||||
"m_pWeaponItemTable: 100%|██████████| 5/5 [00:00<00:00, 6.26it/s]\n",
|
||||
"m_pVehicleItemTable: 100%|██████████| 5/5 [00:00<00:00, 9.41it/s]\n",
|
||||
"m_pGeneralItemTable: 100%|██████████| 3/3 [00:00<00:00, 11.56it/s]\n",
|
||||
"m_pChestItemTable: 100%|██████████| 3/3 [00:00<00:00, 6.83it/s]\n",
|
||||
"m_pQuestItemTable: 100%|██████████| 3/3 [00:00<00:00, 11.19it/s]\n",
|
||||
"m_pCreationItemTable: 100%|██████████| 1/1 [00:00<00:00, 12.50it/s]\n",
|
||||
"m_pFirstUseTable: 100%|██████████| 2/2 [00:00<00:00, 10.72it/s]\n",
|
||||
"m_pRulesTable: 100%|██████████| 2/2 [00:00<00:00, 8.38it/s]\n",
|
||||
"m_pHelpTable: 100%|██████████| 5/5 [00:00<00:00, 9.11it/s]\n",
|
||||
"m_pCutSceneTable: 100%|██████████| 1/1 [00:00<00:00, 11.51it/s]\n",
|
||||
"m_pCombiningTable: 100%|██████████| 1/1 [00:00<00:00, 13.88it/s]\n",
|
||||
"m_pFilterTable: 100%|██████████| 3/3 [00:00<00:00, 9.08it/s]\n",
|
||||
"m_pClassTable: 100%|██████████| 4/4 [00:00<00:00, 10.94it/s]\n",
|
||||
"m_pEnchantTable: 100%|██████████| 1/1 [00:00<00:00, 11.75it/s]\n",
|
||||
"m_pClassSkillTable: 100%|██████████| 8/8 [00:00<00:00, 9.37it/s]\n",
|
||||
"m_pSkillBookTable: 100%|██████████| 3/3 [00:00<00:00, 10.67it/s]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"xdt_path = \"tdata/xdt.json\"\n",
|
||||
"conn = mysql.connector.connect(\n",
|
||||
" host=\"localhost\",\n",
|
||||
" user=\"root\",\n",
|
||||
" password=\"mypassword\",\n",
|
||||
" database=\"tabledata\"\n",
|
||||
")\n",
|
||||
"main(conn, xdt_path)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".venv",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.10.12"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
[
|
||||
"m_iItemStringIndex",
|
||||
"m_iItemConditionNum",
|
||||
"m_iItemConditionNum2",
|
||||
"m_iNextItem"
|
||||
]
|
|
@ -0,0 +1,6 @@
|
|||
[
|
||||
"m_iItemStringIndex",
|
||||
"m_iItemConditionNum",
|
||||
"m_iItemConditionNum2",
|
||||
"m_iNextItem"
|
||||
]
|
|
@ -0,0 +1,6 @@
|
|||
[
|
||||
"m_iItemStringIndex",
|
||||
"m_iItemConditionNum",
|
||||
"m_iItemConditionNum2",
|
||||
"m_iNextItem"
|
||||
]
|
|
@ -0,0 +1,17 @@
|
|||
[
|
||||
"m_iLevel",
|
||||
"m_iHpUp",
|
||||
"m_iMaxHP",
|
||||
"m_iAccuracy",
|
||||
"m_iDodge",
|
||||
"m_iPower",
|
||||
"m_iProtection",
|
||||
"m_iReqBlob_NanoCreate",
|
||||
"m_iReqBlob_NanoTune",
|
||||
"m_iFMLimit",
|
||||
"m_iMobFM",
|
||||
"m_iNanoQuestTaskID",
|
||||
"m_iNanoID",
|
||||
"m_iBonusFM",
|
||||
"m_iDeathFM"
|
||||
]
|
|
@ -0,0 +1,22 @@
|
|||
[
|
||||
"m_iPower",
|
||||
"m_iAccuracy",
|
||||
"m_iProtection",
|
||||
"m_iDodge",
|
||||
"m_iRunSpeed",
|
||||
"m_iSwimSpeed",
|
||||
"m_iJumpHeight",
|
||||
"m_iJumpDistance",
|
||||
"m_iViewAngle",
|
||||
"m_iViewDistance",
|
||||
"m_iAtkRange",
|
||||
"m_iAtkAngle",
|
||||
"m_iEffectArea",
|
||||
"m_iTargetMode",
|
||||
"m_iTargetNumber",
|
||||
"m_iInitialTime",
|
||||
"m_iDeliverTime",
|
||||
"m_iDelayTime",
|
||||
"m_iDurationTime",
|
||||
"m_iBonusUp"
|
||||
]
|
|
@ -0,0 +1,7 @@
|
|||
[
|
||||
"m_strName",
|
||||
"m_strComment",
|
||||
"m_strComment1",
|
||||
"m_strComment2",
|
||||
"m_iExtraNumber"
|
||||
]
|
|
@ -0,0 +1,8 @@
|
|||
[
|
||||
"m_pstrMMeshModelString",
|
||||
"m_pstrMTextureString",
|
||||
"m_pstrMTextureString2",
|
||||
"m_pstrFMeshModelString",
|
||||
"m_pstrFTextureString",
|
||||
"m_pstrFTextureString2"
|
||||
]
|
|
@ -0,0 +1,12 @@
|
|||
[
|
||||
"m_iChatNum1",
|
||||
"m_iChatNum2",
|
||||
"m_iChatNum3",
|
||||
"m_iChatNum4",
|
||||
"m_iChatNum5",
|
||||
"m_iChatNum6",
|
||||
"m_iChatNum7",
|
||||
"m_iChatNum8",
|
||||
"m_iChatNum9",
|
||||
"m_iChatNum10"
|
||||
]
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
"m_iIconType",
|
||||
"m_iIconNumber"
|
||||
]
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
"m_iIconType",
|
||||
"m_iIconNumber"
|
||||
]
|
|
@ -0,0 +1,5 @@
|
|||
[
|
||||
"m_iBuffNumber",
|
||||
"m_iBuffEffect",
|
||||
"m_iBuffEffectInstant"
|
||||
]
|
|
@ -0,0 +1,10 @@
|
|||
[
|
||||
"m_iMax",
|
||||
"m_iStandard",
|
||||
"m_fTickplus",
|
||||
"m_fTickminus",
|
||||
"m_iAttackplus",
|
||||
"m_iDefensplus",
|
||||
"m_iDeadline",
|
||||
"m_iDeaddown"
|
||||
]
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
"m_iIconType",
|
||||
"m_iIconNumber"
|
||||
]
|
|
@ -0,0 +1,10 @@
|
|||
[
|
||||
"m_iPriority",
|
||||
"m_iSkillbutton",
|
||||
"m_iSkillNumber",
|
||||
"m_iConditionChar",
|
||||
"m_iConditionSkill",
|
||||
"m_iKeyMintime",
|
||||
"m_iKeyMaxtime",
|
||||
"m_iMotionSkipTime"
|
||||
]
|
|
@ -0,0 +1,41 @@
|
|||
[
|
||||
"m_iSkillNumber",
|
||||
"m_iSkillType",
|
||||
"m_iEffectTarget",
|
||||
"m_iEffectType",
|
||||
"m_iTargetType",
|
||||
"m_iValueA_Type",
|
||||
"m_iValueA",
|
||||
"m_iValueB_Type",
|
||||
"m_iValueB",
|
||||
"m_iValueC_Type",
|
||||
"m_iValueC",
|
||||
"m_iEffectRange",
|
||||
"m_iEffectAngle",
|
||||
"m_iEffectArea",
|
||||
"m_iCoolTime",
|
||||
"m_iTargetNumber",
|
||||
"m_iBatteryDrainType",
|
||||
"m_iBatteryDrainUse",
|
||||
"m_iInitialTime",
|
||||
"m_iDeleverTime",
|
||||
"m_iDelayTime",
|
||||
"m_iDurationTime",
|
||||
"m_iDBType",
|
||||
"m_iIcon",
|
||||
"m_iEffect",
|
||||
"m_iTargetEffect",
|
||||
"m_iBuffEffect",
|
||||
"m_iSound",
|
||||
"m_iCoolType",
|
||||
"m_iClassType",
|
||||
"m_iClassNum",
|
||||
"m_iWpnType",
|
||||
"m_iDisCharging",
|
||||
"m_iPlusCharging",
|
||||
"m_iMoveType",
|
||||
"m_iMoveSpeed",
|
||||
"m_iJumpPower",
|
||||
"m_iSkillLevel",
|
||||
"m_iAnimationTime"
|
||||
]
|
|
@ -0,0 +1,5 @@
|
|||
[
|
||||
"m_pstrSoundString1",
|
||||
"m_pstrSoundString2",
|
||||
"m_pstrSoundString3"
|
||||
]
|
|
@ -0,0 +1,8 @@
|
|||
[
|
||||
"m_SkillName",
|
||||
"m_ClassName",
|
||||
"m_WpnName",
|
||||
"m_skillAccount1",
|
||||
"m_skillAccount2",
|
||||
"m_animationName"
|
||||
]
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
"m_strName",
|
||||
"m_strComment"
|
||||
]
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
"m_iChatString",
|
||||
"m_iLinkChatNum"
|
||||
]
|
|
@ -0,0 +1,13 @@
|
|||
[
|
||||
"m_iClassNum",
|
||||
"m_iClassName",
|
||||
"m_iWpnType1",
|
||||
"m_iWpnType2",
|
||||
"m_iBasicWpn",
|
||||
"m_iBonusHP",
|
||||
"m_iBonusPow",
|
||||
"m_iBonusAcc",
|
||||
"m_iBonusPro",
|
||||
"m_iBonusDod",
|
||||
"m_iIcon"
|
||||
]
|
|
@ -0,0 +1,10 @@
|
|||
[
|
||||
"m_iWpnType",
|
||||
"m_iRateOfFire",
|
||||
"m_iOverheatMax",
|
||||
"m_iOverheatUse",
|
||||
"m_iUnuseCool",
|
||||
"m_iUseCool",
|
||||
"m_iCoolTime",
|
||||
"m_iOverheatEffect"
|
||||
]
|
|
@ -0,0 +1,10 @@
|
|||
[
|
||||
"m_iLevelGap",
|
||||
"m_fSameGrade",
|
||||
"m_fOneGrade",
|
||||
"m_fTwoGrade",
|
||||
"m_fThreeGrade",
|
||||
"m_fLevelGapStandard",
|
||||
"m_iLookConstant",
|
||||
"m_iStatConstant"
|
||||
]
|
|
@ -0,0 +1,6 @@
|
|||
[
|
||||
"m_iIndex",
|
||||
"m_iBattleCondition",
|
||||
"m_iMoveCondition",
|
||||
"m_iJumpCondition"
|
||||
]
|
|
@ -0,0 +1,5 @@
|
|||
[
|
||||
"m_iEvent",
|
||||
"m_iLine",
|
||||
"m_strText"
|
||||
]
|
|
@ -0,0 +1,6 @@
|
|||
[
|
||||
"m_iType",
|
||||
"m_iSize",
|
||||
"m_iColor",
|
||||
"m_iString"
|
||||
]
|
|
@ -0,0 +1,7 @@
|
|||
[
|
||||
"m_strName",
|
||||
"m_strComment",
|
||||
"m_strComment1",
|
||||
"m_strComment2",
|
||||
"m_iExtraNumber"
|
||||
]
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
"m_iStartContent",
|
||||
"m_iEndContent"
|
||||
]
|
|
@ -0,0 +1,3 @@
|
|||
[
|
||||
"m_iLinkEmoteNum"
|
||||
]
|
|
@ -0,0 +1,8 @@
|
|||
[
|
||||
"m_iEmoteNumber",
|
||||
"m_iUser",
|
||||
"m_iAvatarAnimation",
|
||||
"m_iNanoAnimation",
|
||||
"m_iTexture",
|
||||
"m_iDuration"
|
||||
]
|
|
@ -0,0 +1,8 @@
|
|||
[
|
||||
"m_pstrMMeshModelString",
|
||||
"m_pstrMTextureString",
|
||||
"m_pstrMTextureString2",
|
||||
"m_pstrFMeshModelString",
|
||||
"m_pstrFTextureString",
|
||||
"m_pstrFTextureString2"
|
||||
]
|
|
@ -0,0 +1,16 @@
|
|||
[
|
||||
"m_iEnchantGrade",
|
||||
"m_iCost",
|
||||
"m_iClass",
|
||||
"m_iWpnMatter",
|
||||
"m_iCostumeMatter",
|
||||
"m_iProbability",
|
||||
"m_iOffenceUp",
|
||||
"m_iDefenceUp",
|
||||
"m_iFailType",
|
||||
"m_iNoDropProb",
|
||||
"m_iOneDropProb",
|
||||
"m_iTwoDropProb",
|
||||
"m_iThreeDropProb",
|
||||
"m_iFourDropProb"
|
||||
]
|
|
@ -0,0 +1,3 @@
|
|||
[
|
||||
"m_strText"
|
||||
]
|
|
@ -0,0 +1,3 @@
|
|||
[
|
||||
"m_pstrNameString"
|
||||
]
|
|
@ -0,0 +1,7 @@
|
|||
[
|
||||
"m_strName",
|
||||
"m_strComment",
|
||||
"m_strComment1",
|
||||
"m_strComment2",
|
||||
"m_iExtraNumber"
|
||||
]
|
|
@ -0,0 +1,7 @@
|
|||
[
|
||||
"m_iString",
|
||||
"m_iCompDuration",
|
||||
"m_iIconDuration",
|
||||
"m_iHelpSub",
|
||||
"m_iHelpMain"
|
||||
]
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
"m_iNum",
|
||||
"m_pszString"
|
||||
]
|
|
@ -0,0 +1,8 @@
|
|||
[
|
||||
"m_iNameIndex",
|
||||
"m_iQuest",
|
||||
"m_iSelect",
|
||||
"m_iLoginNomail",
|
||||
"m_iLoginMail",
|
||||
"m_iLevelUp"
|
||||
]
|
|
@ -0,0 +1,7 @@
|
|||
[
|
||||
"m_strName",
|
||||
"m_strComment",
|
||||
"m_strComment1",
|
||||
"m_strComment2",
|
||||
"m_iExtraNumber"
|
||||
]
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
"m_iTitleStartString",
|
||||
"m_iSubEndString"
|
||||
]
|
|
@ -0,0 +1,26 @@
|
|||
[
|
||||
null,
|
||||
"m_iZoneX",
|
||||
"m_iZoneY",
|
||||
null,
|
||||
"m_iInstanceNameID",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"m_iIsEP",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"m_ScoreMax",
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
"m_SortIndex"
|
||||
]
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
"m_iIconType",
|
||||
"m_iIconNumber"
|
||||
]
|
|
@ -0,0 +1,8 @@
|
|||
[
|
||||
"m_pstrMMeshModelString",
|
||||
"m_pstrMTextureString",
|
||||
"m_pstrMTextureString2",
|
||||
"m_pstrFMeshModelString",
|
||||
"m_pstrFTextureString",
|
||||
"m_pstrFTextureString2"
|
||||
]
|
|
@ -0,0 +1,5 @@
|
|||
[
|
||||
"m_pstrSoundString1",
|
||||
"m_pstrSoundString2",
|
||||
"m_pstrSoundString3"
|
||||
]
|
|
@ -0,0 +1,7 @@
|
|||
[
|
||||
"m_strName",
|
||||
"m_strComment",
|
||||
"m_strComment1",
|
||||
"m_strComment2",
|
||||
"m_iExtraNumber"
|
||||
]
|
|
@ -0,0 +1,50 @@
|
|||
[
|
||||
"m_iItemNumber",
|
||||
"m_iItemName",
|
||||
"m_iComment",
|
||||
"m_iTradeAble",
|
||||
"m_iItemPrice",
|
||||
"m_iItemSellPrice",
|
||||
"m_iSellAble",
|
||||
"m_iStackNumber",
|
||||
"m_iEquipLoc",
|
||||
"m_iEquipType",
|
||||
"m_ibattery",
|
||||
"m_iBatteryDrain",
|
||||
"m_iMinReqLev",
|
||||
"m_iReqSex",
|
||||
"m_iMentor",
|
||||
"m_iAtkRange",
|
||||
"m_iAtkAngle",
|
||||
"m_iEffectArea",
|
||||
"m_iTargetMode",
|
||||
"m_iTargetNumber",
|
||||
"m_iInitalTime",
|
||||
"m_iDeliverTime",
|
||||
"m_iDelayTime",
|
||||
"m_iDurationTime",
|
||||
"m_iUp_power",
|
||||
"m_iUp_accuracy",
|
||||
"m_iUp_protection",
|
||||
"m_iUp_dodge",
|
||||
"m_iUp_runSpeed",
|
||||
"m_iUp_swimSpeed",
|
||||
"m_iUp_jumpHeight",
|
||||
"m_iUp_jumpDistance",
|
||||
"m_iUp_atkRate",
|
||||
"m_iUp_effectArea",
|
||||
"m_iUp_addFusionMatter",
|
||||
"m_iUp_addCandy",
|
||||
"m_iUp_addItemfind",
|
||||
"m_iMesh",
|
||||
"m_iIcon",
|
||||
"m_iEffect1",
|
||||
"m_iSound1",
|
||||
"m_iRarity",
|
||||
"m_iPointRat",
|
||||
"m_iGroupRat",
|
||||
"m_iDefenseRat",
|
||||
"m_iEffect2",
|
||||
"m_iSound2",
|
||||
"m_iCashAble"
|
||||
]
|
|
@ -0,0 +1,7 @@
|
|||
[
|
||||
"m_strName",
|
||||
"m_strComment",
|
||||
"m_strComment1",
|
||||
"m_strComment2",
|
||||
"m_iExtraNumber"
|
||||
]
|
|
@ -0,0 +1,12 @@
|
|||
[
|
||||
"m_iItemNumber",
|
||||
"m_iItemName",
|
||||
"m_iChestDesc",
|
||||
"m_iTradeAble",
|
||||
"m_iItemPrice",
|
||||
"m_iItemSellPrice",
|
||||
"m_iSellAble",
|
||||
"m_iStackNumber",
|
||||
"m_iIcon",
|
||||
"m_iChestCheck"
|
||||
]
|
|
@ -0,0 +1,13 @@
|
|||
[
|
||||
"m_iShirtM",
|
||||
"m_iPantsM",
|
||||
"m_iShoesM",
|
||||
"m_iHairM",
|
||||
"m_iFaceM",
|
||||
"m_iShirtF",
|
||||
"m_iPantsF",
|
||||
"m_iShoesF",
|
||||
"m_iHairF",
|
||||
"m_iFaceF",
|
||||
"m_iWeapon"
|
||||
]
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
"m_iIconType",
|
||||
"m_iIconNumber"
|
||||
]
|
|
@ -0,0 +1,8 @@
|
|||
[
|
||||
"m_pstrMMeshModelString",
|
||||
"m_pstrMTextureString",
|
||||
"m_pstrMTextureString2",
|
||||
"m_pstrFMeshModelString",
|
||||
"m_pstrFTextureString",
|
||||
"m_pstrFTextureString2"
|
||||
]
|
|
@ -0,0 +1,5 @@
|
|||
[
|
||||
"m_pstrSoundString1",
|
||||
"m_pstrSoundString2",
|
||||
"m_pstrSoundString3"
|
||||
]
|
|
@ -0,0 +1,7 @@
|
|||
[
|
||||
"m_strName",
|
||||
"m_strComment",
|
||||
"m_strComment1",
|
||||
"m_strComment2",
|
||||
"m_iExtraNumber"
|
||||
]
|
|
@ -0,0 +1,50 @@
|
|||
[
|
||||
"m_iItemNumber",
|
||||
"m_iItemName",
|
||||
"m_iComment",
|
||||
"m_iTradeAble",
|
||||
"m_iItemPrice",
|
||||
"m_iItemSellPrice",
|
||||
"m_iSellAble",
|
||||
"m_iStackNumber",
|
||||
"m_iEquipLoc",
|
||||
"m_iEquipType",
|
||||
"m_ibattery",
|
||||
"m_iBatteryDrain",
|
||||
"m_iMinReqLev",
|
||||
"m_iReqSex",
|
||||
"m_iMentor",
|
||||
"m_iAtkRange",
|
||||
"m_iAtkAngle",
|
||||
"m_iEffectArea",
|
||||
"m_iTargetMode",
|
||||
"m_iTargetNumber",
|
||||
"m_iInitalTime",
|
||||
"m_iDeliverTime",
|
||||
"m_iDelayTime",
|
||||
"m_iDurationTime",
|
||||
"m_iUp_power",
|
||||
"m_iUp_accuracy",
|
||||
"m_iUp_protection",
|
||||
"m_iUp_dodge",
|
||||
"m_iUp_runSpeed",
|
||||
"m_iUp_swimSpeed",
|
||||
"m_iUp_jumpHeight",
|
||||
"m_iUp_jumpDistance",
|
||||
"m_iUp_atkRate",
|
||||
"m_iUp_effectArea",
|
||||
"m_iUp_addFusionMatter",
|
||||
"m_iUp_addCandy",
|
||||
"m_iUp_addItemfind",
|
||||
"m_iMesh",
|
||||
"m_iIcon",
|
||||
"m_iEffect1",
|
||||
"m_iSound1",
|
||||
"m_iRarity",
|
||||
"m_iPointRat",
|
||||
"m_iGroupRat",
|
||||
"m_iDefenseRat",
|
||||
"m_iEffect2",
|
||||
"m_iSound2",
|
||||
"m_iCashAble"
|
||||
]
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
"m_iIconType",
|
||||
"m_iIconNumber"
|
||||
]
|
|
@ -0,0 +1,7 @@
|
|||
[
|
||||
"m_strName",
|
||||
"m_strComment",
|
||||
"m_strComment1",
|
||||
"m_strComment2",
|
||||
"m_iExtraNumber"
|
||||
]
|
|
@ -0,0 +1,16 @@
|
|||
[
|
||||
"m_iItemNumber",
|
||||
"m_iItemName",
|
||||
"m_iComment",
|
||||
"m_iTradeAble",
|
||||
"m_iItemPrice",
|
||||
"m_iItemSellPrice",
|
||||
"m_iSellAble",
|
||||
"m_iStackNumber",
|
||||
"m_iBatteryRecharge",
|
||||
"m_iItemType",
|
||||
"m_iStimPackAttri",
|
||||
"m_iLinkSkill",
|
||||
"m_iIcon",
|
||||
"m_iCash"
|
||||
]
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
"m_iIconType",
|
||||
"m_iIconNumber"
|
||||
]
|
|
@ -0,0 +1,8 @@
|
|||
[
|
||||
"m_pstrMMeshModelString",
|
||||
"m_pstrMTextureString",
|
||||
"m_pstrMTextureString2",
|
||||
"m_pstrFMeshModelString",
|
||||
"m_pstrFTextureString",
|
||||
"m_pstrFTextureString2"
|
||||
]
|
|
@ -0,0 +1,5 @@
|
|||
[
|
||||
"m_pstrSoundString1",
|
||||
"m_pstrSoundString2",
|
||||
"m_pstrSoundString3"
|
||||
]
|
|
@ -0,0 +1,7 @@
|
|||
[
|
||||
"m_strName",
|
||||
"m_strComment",
|
||||
"m_strComment1",
|
||||
"m_strComment2",
|
||||
"m_iExtraNumber"
|
||||
]
|
|
@ -0,0 +1,50 @@
|
|||
[
|
||||
"m_iItemNumber",
|
||||
"m_iItemName",
|
||||
"m_iComment",
|
||||
"m_iTradeAble",
|
||||
"m_iItemPrice",
|
||||
"m_iItemSellPrice",
|
||||
"m_iSellAble",
|
||||
"m_iStackNumber",
|
||||
"m_iEquipLoc",
|
||||
"m_iEquipType",
|
||||
"m_ibattery",
|
||||
"m_iBatteryDrain",
|
||||
"m_iMinReqLev",
|
||||
"m_iReqSex",
|
||||
"m_iMentor",
|
||||
"m_iAtkRange",
|
||||
"m_iAtkAngle",
|
||||
"m_iEffectArea",
|
||||
"m_iTargetMode",
|
||||
"m_iTargetNumber",
|
||||
"m_iInitalTime",
|
||||
"m_iDeliverTime",
|
||||
"m_iDelayTime",
|
||||
"m_iDurationTime",
|
||||
"m_iUp_power",
|
||||
"m_iUp_accuracy",
|
||||
"m_iUp_protection",
|
||||
"m_iUp_dodge",
|
||||
"m_iUp_runSpeed",
|
||||
"m_iUp_swimSpeed",
|
||||
"m_iUp_jumpHeight",
|
||||
"m_iUp_jumpDistance",
|
||||
"m_iUp_atkRate",
|
||||
"m_iUp_effectArea",
|
||||
"m_iUp_addFusionMatter",
|
||||
"m_iUp_addCandy",
|
||||
"m_iUp_addItemfind",
|
||||
"m_iMesh",
|
||||
"m_iIcon",
|
||||
"m_iEffect1",
|
||||
"m_iSound1",
|
||||
"m_iRarity",
|
||||
"m_iPointRat",
|
||||
"m_iGroupRat",
|
||||
"m_iDefenseRat",
|
||||
"m_iEffect2",
|
||||
"m_iSound2",
|
||||
"m_iCashAble"
|
||||
]
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
"m_iIconType",
|
||||
"m_iIconNumber"
|
||||
]
|
|
@ -0,0 +1,8 @@
|
|||
[
|
||||
"m_pstrMMeshModelString",
|
||||
"m_pstrMTextureString",
|
||||
"m_pstrMTextureString2",
|
||||
"m_pstrFMeshModelString",
|
||||
"m_pstrFTextureString",
|
||||
"m_pstrFTextureString2"
|
||||
]
|
|
@ -0,0 +1,5 @@
|
|||
[
|
||||
"m_pstrSoundString1",
|
||||
"m_pstrSoundString2",
|
||||
"m_pstrSoundString3"
|
||||
]
|
|
@ -0,0 +1,7 @@
|
|||
[
|
||||
"m_strName",
|
||||
"m_strComment",
|
||||
"m_strComment1",
|
||||
"m_strComment2",
|
||||
"m_iExtraNumber"
|
||||
]
|
|
@ -0,0 +1,50 @@
|
|||
[
|
||||
"m_iItemNumber",
|
||||
"m_iItemName",
|
||||
"m_iComment",
|
||||
"m_iTradeAble",
|
||||
"m_iItemPrice",
|
||||
"m_iItemSellPrice",
|
||||
"m_iSellAble",
|
||||
"m_iStackNumber",
|
||||
"m_iEquipLoc",
|
||||
"m_iEquipType",
|
||||
"m_ibattery",
|
||||
"m_iBatteryDrain",
|
||||
"m_iMinReqLev",
|
||||
"m_iReqSex",
|
||||
"m_iMentor",
|
||||
"m_iAtkRange",
|
||||
"m_iAtkAngle",
|
||||
"m_iEffectArea",
|
||||
"m_iTargetMode",
|
||||
"m_iTargetNumber",
|
||||
"m_iInitalTime",
|
||||
"m_iDeliverTime",
|
||||
"m_iDelayTime",
|
||||
"m_iDurationTime",
|
||||
"m_iUp_power",
|
||||
"m_iUp_accuracy",
|
||||
"m_iUp_protection",
|
||||
"m_iUp_dodge",
|
||||
"m_iUp_runSpeed",
|
||||
"m_iUp_swimSpeed",
|
||||
"m_iUp_jumpHeight",
|
||||
"m_iUp_jumpDistance",
|
||||
"m_iUp_atkRate",
|
||||
"m_iUp_effectArea",
|
||||
"m_iUp_addFusionMatter",
|
||||
"m_iUp_addCandy",
|
||||
"m_iUp_addItemfind",
|
||||
"m_iMesh",
|
||||
"m_iIcon",
|
||||
"m_iEffect1",
|
||||
"m_iSound1",
|
||||
"m_iRarity",
|
||||
"m_iPointRat",
|
||||
"m_iGroupRat",
|
||||
"m_iDefenseRat",
|
||||
"m_iEffect2",
|
||||
"m_iSound2",
|
||||
"m_iCashAble"
|
||||
]
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
"m_iIconType",
|
||||
"m_iIconNumber"
|
||||
]
|
|
@ -0,0 +1,8 @@
|
|||
[
|
||||
"m_pstrMMeshModelString",
|
||||
"m_pstrMTextureString",
|
||||
"m_pstrMTextureString2",
|
||||
"m_pstrFMeshModelString",
|
||||
"m_pstrFTextureString",
|
||||
"m_pstrFTextureString2"
|
||||
]
|
|
@ -0,0 +1,5 @@
|
|||
[
|
||||
"m_pstrSoundString1",
|
||||
"m_pstrSoundString2",
|
||||
"m_pstrSoundString3"
|
||||
]
|
|
@ -0,0 +1,7 @@
|
|||
[
|
||||
"m_strName",
|
||||
"m_strComment",
|
||||
"m_strComment1",
|
||||
"m_strComment2",
|
||||
"m_iExtraNumber"
|
||||
]
|
|
@ -0,0 +1,50 @@
|
|||
[
|
||||
"m_iItemNumber",
|
||||
"m_iItemName",
|
||||
"m_iComment",
|
||||
"m_iTradeAble",
|
||||
"m_iItemPrice",
|
||||
"m_iItemSellPrice",
|
||||
"m_iSellAble",
|
||||
"m_iStackNumber",
|
||||
"m_iEquipLoc",
|
||||
"m_iEquipType",
|
||||
"m_ibattery",
|
||||
"m_iBatteryDrain",
|
||||
"m_iMinReqLev",
|
||||
"m_iReqSex",
|
||||
"m_iMentor",
|
||||
"m_iAtkRange",
|
||||
"m_iAtkAngle",
|
||||
"m_iEffectArea",
|
||||
"m_iTargetMode",
|
||||
"m_iTargetNumber",
|
||||
"m_iInitalTime",
|
||||
"m_iDeliverTime",
|
||||
"m_iDelayTime",
|
||||
"m_iDurationTime",
|
||||
"m_iUp_power",
|
||||
"m_iUp_accuracy",
|
||||
"m_iUp_protection",
|
||||
"m_iUp_dodge",
|
||||
"m_iUp_runSpeed",
|
||||
"m_iUp_swimSpeed",
|
||||
"m_iUp_jumpHeight",
|
||||
"m_iUp_jumpDistance",
|
||||
"m_iUp_atkRate",
|
||||
"m_iUp_effectArea",
|
||||
"m_iUp_addFusionMatter",
|
||||
"m_iUp_addCandy",
|
||||
"m_iUp_addItemfind",
|
||||
"m_iMesh",
|
||||
"m_iIcon",
|
||||
"m_iEffect1",
|
||||
"m_iSound1",
|
||||
"m_iRarity",
|
||||
"m_iPointRat",
|
||||
"m_iGroupRat",
|
||||
"m_iDefenseRat",
|
||||
"m_iEffect2",
|
||||
"m_iSound2",
|
||||
"m_iCashAble"
|
||||
]
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
"m_iIconType",
|
||||
"m_iIconNumber"
|
||||
]
|
|
@ -0,0 +1,8 @@
|
|||
[
|
||||
"m_pstrMMeshModelString",
|
||||
"m_pstrMTextureString",
|
||||
"m_pstrMTextureString2",
|
||||
"m_pstrFMeshModelString",
|
||||
"m_pstrFTextureString",
|
||||
"m_pstrFTextureString2"
|
||||
]
|
|
@ -0,0 +1,5 @@
|
|||
[
|
||||
"m_pstrSoundString1",
|
||||
"m_pstrSoundString2",
|
||||
"m_pstrSoundString3"
|
||||
]
|
|
@ -0,0 +1,7 @@
|
|||
[
|
||||
"m_strName",
|
||||
"m_strComment",
|
||||
"m_strComment1",
|
||||
"m_strComment2",
|
||||
"m_iExtraNumber"
|
||||
]
|
|
@ -0,0 +1,50 @@
|
|||
[
|
||||
"m_iItemNumber",
|
||||
"m_iItemName",
|
||||
"m_iComment",
|
||||
"m_iTradeAble",
|
||||
"m_iItemPrice",
|
||||
"m_iItemSellPrice",
|
||||
"m_iSellAble",
|
||||
"m_iStackNumber",
|
||||
"m_iEquipLoc",
|
||||
"m_iEquipType",
|
||||
"m_ibattery",
|
||||
"m_iBatteryDrain",
|
||||
"m_iMinReqLev",
|
||||
"m_iReqSex",
|
||||
"m_iMentor",
|
||||
"m_iAtkRange",
|
||||
"m_iAtkAngle",
|
||||
"m_iEffectArea",
|
||||
"m_iTargetMode",
|
||||
"m_iTargetNumber",
|
||||
"m_iInitalTime",
|
||||
"m_iDeliverTime",
|
||||
"m_iDelayTime",
|
||||
"m_iDurationTime",
|
||||
"m_iUp_power",
|
||||
"m_iUp_accuracy",
|
||||
"m_iUp_protection",
|
||||
"m_iUp_dodge",
|
||||
"m_iUp_runSpeed",
|
||||
"m_iUp_swimSpeed",
|
||||
"m_iUp_jumpHeight",
|
||||
"m_iUp_jumpDistance",
|
||||
"m_iUp_atkRate",
|
||||
"m_iUp_effectArea",
|
||||
"m_iUp_addFusionMatter",
|
||||
"m_iUp_addCandy",
|
||||
"m_iUp_addItemfind",
|
||||
"m_iMesh",
|
||||
"m_iIcon",
|
||||
"m_iEffect1",
|
||||
"m_iSound1",
|
||||
"m_iRarity",
|
||||
"m_iPointRat",
|
||||
"m_iGroupRat",
|
||||
"m_iDefenseRat",
|
||||
"m_iEffect2",
|
||||
"m_iSound2",
|
||||
"m_iCashAble"
|
||||
]
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
"m_iIconType",
|
||||
"m_iIconNumber"
|
||||
]
|
|
@ -0,0 +1,7 @@
|
|||
[
|
||||
"m_strName",
|
||||
"m_strComment",
|
||||
"m_strComment1",
|
||||
"m_strComment2",
|
||||
"m_iExtraNumber"
|
||||
]
|
|
@ -0,0 +1,8 @@
|
|||
[
|
||||
"m_iItemNumber",
|
||||
"m_iItemName",
|
||||
"m_iComment",
|
||||
"m_iQuestStart",
|
||||
"m_iDelete",
|
||||
"m_iIcon"
|
||||
]
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
"m_iIconType",
|
||||
"m_iIconNumber"
|
||||
]
|
|
@ -0,0 +1,8 @@
|
|||
[
|
||||
"m_pstrMMeshModelString",
|
||||
"m_pstrMTextureString",
|
||||
"m_pstrMTextureString2",
|
||||
"m_pstrFMeshModelString",
|
||||
"m_pstrFTextureString",
|
||||
"m_pstrFTextureString2"
|
||||
]
|
|
@ -0,0 +1,5 @@
|
|||
[
|
||||
"m_pstrSoundString1",
|
||||
"m_pstrSoundString2",
|
||||
"m_pstrSoundString3"
|
||||
]
|
|
@ -0,0 +1,7 @@
|
|||
[
|
||||
"m_strName",
|
||||
"m_strComment",
|
||||
"m_strComment1",
|
||||
"m_strComment2",
|
||||
"m_iExtraNumber"
|
||||
]
|
|
@ -0,0 +1,50 @@
|
|||
[
|
||||
"m_iItemNumber",
|
||||
"m_iItemName",
|
||||
"m_iComment",
|
||||
"m_iTradeAble",
|
||||
"m_iItemPrice",
|
||||
"m_iItemSellPrice",
|
||||
"m_iSellAble",
|
||||
"m_iStackNumber",
|
||||
"m_iEquipLoc",
|
||||
"m_iEquipType",
|
||||
"m_ibattery",
|
||||
"m_iBatteryDrain",
|
||||
"m_iMinReqLev",
|
||||
"m_iReqSex",
|
||||
"m_iMentor",
|
||||
"m_iAtkRange",
|
||||
"m_iAtkAngle",
|
||||
"m_iEffectArea",
|
||||
"m_iTargetMode",
|
||||
"m_iTargetNumber",
|
||||
"m_iInitalTime",
|
||||
"m_iDeliverTime",
|
||||
"m_iDelayTime",
|
||||
"m_iDurationTime",
|
||||
"m_iUp_power",
|
||||
"m_iUp_accuracy",
|
||||
"m_iUp_protection",
|
||||
"m_iUp_dodge",
|
||||
"m_iUp_runSpeed",
|
||||
"m_iUp_swimSpeed",
|
||||
"m_iUp_jumpHeight",
|
||||
"m_iUp_jumpDistance",
|
||||
"m_iUp_atkRate",
|
||||
"m_iUp_effectArea",
|
||||
"m_iUp_addFusionMatter",
|
||||
"m_iUp_addCandy",
|
||||
"m_iUp_addItemfind",
|
||||
"m_iMesh",
|
||||
"m_iIcon",
|
||||
"m_iEffect1",
|
||||
"m_iSound1",
|
||||
"m_iRarity",
|
||||
"m_iPointRat",
|
||||
"m_iGroupRat",
|
||||
"m_iDefenseRat",
|
||||
"m_iEffect2",
|
||||
"m_iSound2",
|
||||
"m_iCashAble"
|
||||
]
|
|
@ -0,0 +1,4 @@
|
|||
[
|
||||
"m_iIconType",
|
||||
"m_iIconNumber"
|
||||
]
|
|
@ -0,0 +1,8 @@
|
|||
[
|
||||
"m_pstrMMeshModelString",
|
||||
"m_pstrMTextureString",
|
||||
"m_pstrMTextureString2",
|
||||
"m_pstrFMeshModelString",
|
||||
"m_pstrFTextureString",
|
||||
"m_pstrFTextureString2"
|
||||
]
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue