SERVER: Use generated hash table for model path conversion

This commit is contained in:
cypress 2024-01-06 17:33:52 -05:00
parent 471b08afe5
commit 5e799823af
15 changed files with 400 additions and 385 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
build/* build/*
source/server/hash_table.qc
bin/fteqcc.log bin/fteqcc.log

View file

@ -21,6 +21,8 @@ There are no prerequisites or dependancies needed to build QuakeC other than a w
Before you can build the NZ:P QuakeC, you must either [download](https://github.com/nzp-team/quakec/archive/refs/heads/main.zip) this repository (easy) or [clone it](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) (for developers). Before you can build the NZ:P QuakeC, you must either [download](https://github.com/nzp-team/quakec/archive/refs/heads/main.zip) this repository (easy) or [clone it](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository) (for developers).
[Python](https://www.python.org/) 3.7 or above is required to execute additional required components for hash table generation. You can install the [required modules](https://raw.githubusercontent.com/nzp-team/QCHashTableGenerator/main/requirements.txt) with `pip -r requirements.txt` pointing to the provided file.
To build, simply navigate to the `tools` directory and run the `qc-compiler-*` script for your platform. If unfamiliar with executing shell (`.sh`) scripts on Linux systems, give this [itsFOSS article](https://itsfoss.com/run-shell-script-linux/) a read. To build, simply navigate to the `tools` directory and run the `qc-compiler-*` script for your platform. If unfamiliar with executing shell (`.sh`) scripts on Linux systems, give this [itsFOSS article](https://itsfoss.com/run-shell-script-linux/) a read.
After having done this, a `build` directory will have been created, and inside of it will be more directories named after every platform. Copy the contents of the platform directories into your `nzp` game directory. (Example: For PSP, copy `progs.dat` and `progs.lno` from `standard/handheld` to `PSP/GAME/nzportable/nzp`). After having done this, a `build` directory will have been created, and inside of it will be more directories named after every platform. Copy the contents of the platform directories into your `nzp` game directory. (Example: For PSP, copy `progs.dat` and `progs.lno` from `standard/handheld` to `PSP/GAME/nzportable/nzp`).

176
bin/qc_hash_generator.py Normal file
View file

@ -0,0 +1,176 @@
"""
Nazi Zombies: Portable QuakeC CRC generator
Takes input .CSV files and outputs an FTEQCC-compilable
QuakeC struct with its contents, always assumes the first
entry should be IBM 3740 CRC16 hashed, adding its length
as an entry as well, for collision detection.
"""
import argparse
import pandas
import sys
import os
from fastcrc import crc16
from colorama import Fore, Style
from dataclasses import dataclass
args = {}
struct_fields = []
original_lengths = []
original_names = []
COL_BLUE = Fore.BLUE
COL_RED = Fore.RED
COL_YEL = Fore.YELLOW
COL_GREEN = Fore.GREEN
COL_NONE = Style.RESET_ALL
ITYPE_FLOAT = 0
ITYPE_STRING = 1
ITYPE_CRC = 2
@dataclass
class StructField:
'''
Class for fields that are added to the QuakeC struct.
'''
name: str
item_type: int = ITYPE_FLOAT
def write_qc_file(csv_data):
'''
Writes the data obtained into an FTEQCC-compilable
struct.
'''
with open(args['output_file'], 'w') as output:
# Define the struct.
output.write('var struct {\n')
# Write out all of it's types..
for fields in struct_fields:
if fields.item_type == ITYPE_STRING:
output.write('string ')
else:
output.write('float ')
output.write(f'{fields.name};\n')
# Close the struct.
output.write('}')
# Now, the name of it
struct_name = args['struct_name']
output.write(f'{struct_name}[]=')
output.write('{\n')
# We can begin writing the actual data..
value_counter = 0
for value in csv_data.values:
output.write('{')
entry_counter = 0
for entry in value:
if struct_fields[entry_counter].item_type != ITYPE_STRING:
output.write(f'{str(entry)},')
else:
output.write(f'\"{entry}\",')
entry_counter += 1
# Write the length of the first entry
output.write(str(original_lengths[value_counter]))
# Close entry, add comma if not the last..
output.write('}')
if value_counter + 1 < len(csv_data.values):
output.write(',')
# Leave comment referring to the unhashed-value
output.write(f' // {original_names[value_counter]}')
output.write('\n')
value_counter += 1
# End struct!
output.write('};\n')
def create_qc_structfields(csv_data):
'''
Parses the .CSV data to create new StructField
entries given the .CSV specific requirements.
'''
global struct_fields
column_count = 0
for column in csv_data.columns:
# Assume first entry is what we always want
# to hash, append _crc to it, too.
if column_count == 0:
item_type = ITYPE_CRC
item_name = column + '_crc'
else:
item_type = ITYPE_STRING
item_name = column
struct_fields.append(StructField(item_name, item_type))
column_count += 1
# Always append a field that will store the
# length of the unhashed-CRC.
struct_fields.append(StructField('crc_strlen', ITYPE_FLOAT))
def generate_qc_file(csv_data):
'''
Calls for population of StructFields and prompts
for writing the .QC file output.
'''
create_qc_structfields(csv_data)
write_qc_file(csv_data)
def read_csv_data():
'''
Parses the input_file .CSV into a Pandas dictionary,
performs the hashing on the first indexes, and sorts
in ascending order.
'''
global original_lengths, original_names
csv_data = pandas.read_csv(args['input_file'])
# Grab every value and turn the first entry into a hash.
for value in csv_data.values:
original_lengths.append(len(value[0]))
original_names.append(value[0])
value[0] = int(crc16.ibm_3740(str.encode(value[0])))
# Now order everything by ascending order
csv_data = csv_data.sort_values(csv_data.columns[0])
original_lengths = [original_lengths[i] for i in csv_data.index]
original_names = [original_names[i] for i in csv_data.index]
return csv_data
def fetch_cli_arguments():
'''
Initiates ArgParser with all potential command line arguments.
'''
global args
parser = argparse.ArgumentParser(description='IBM 3740 CRC16 hash generator in FTE QuakeC-readable data structure.')
parser.add_argument('-i', '--input-file',
help='.CSV input file to parse.', required=True)
parser.add_argument('-o', '--output-file',
help='File name for generated .QC file.', default='hashes.qc')
parser.add_argument('-n', '--struct-name',
help='Name of the struct generated.', default='asset_conversion_table')
args = vars(parser.parse_args())
def main():
fetch_cli_arguments()
if not os.path.isfile(args['input_file']):
print(f'{COL_RED}Error{COL_NONE}: Input .CSV file does not exist. Exiting.')
sys.exit()
csv_data = read_csv_data()
generate_qc_file(csv_data)
if __name__ == '__main__':
main()

View file

@ -5,6 +5,7 @@
../source/shared/weapon_defines.qc ../source/shared/weapon_defines.qc
../source/server/defs/custom.qc ../source/server/defs/custom.qc
../source/server/clientfuncs.qc ../source/server/clientfuncs.qc
../source/server/hash_table.qc
../source/server/dummies.qc ../source/server/dummies.qc
../source/server/rounds.qc ../source/server/rounds.qc

View file

@ -7,6 +7,7 @@
../source/shared/weapon_defines.qc ../source/shared/weapon_defines.qc
../source/server/defs/custom.qc ../source/server/defs/custom.qc
../source/server/clientfuncs.qc ../source/server/clientfuncs.qc
../source/server/hash_table.qc
../source/server/non_fte_specifics.qc ../source/server/non_fte_specifics.qc

View file

@ -24,7 +24,6 @@
Boston, MA 02111-1307, USA Boston, MA 02111-1307, USA
*/ */
string(string asset) convert_old_asset_path;
void() NotifyGameEnd = void() NotifyGameEnd =
{ {
@ -676,7 +675,7 @@ void(entity ent) Ent_FakeRemove =
void(string modelname) Precache_Set = // Precache model, and set myself to it void(string modelname) Precache_Set = // Precache model, and set myself to it
{ {
modelname = convert_old_asset_path(modelname); modelname = Compat_ConvertOldAssetPath(modelname);
precache_model(modelname); precache_model(modelname);
setmodel(self, modelname); setmodel(self, modelname);
}; };

View file

@ -244,6 +244,8 @@ void Set_W_Frame (float startframe, float endframe, float duration, float funcca
.void() animend; .void() animend;
.void(optional float t) animend2; .void(optional float t) animend2;
string(string path) Compat_ConvertOldAssetPath;
//Null functions //Null functions
void() SUB_Null = {}; void() SUB_Null = {};
void() SUB_Null2 = {}; void() SUB_Null2 = {};

View file

@ -348,7 +348,7 @@ void() place_model =
self.classname = "place_model"; self.classname = "place_model";
// Grab an updated model path. // Grab an updated model path.
self.model = convert_old_asset_path(self.model); self.model = Compat_ConvertOldAssetPath(self.model);
// Convert the VEC_HULL bounds to match mdlsz. // Convert the VEC_HULL bounds to match mdlsz.
self.mdlsz = '64 64 88'; self.mdlsz = '64 64 88';

View file

@ -407,9 +407,9 @@ void() perk_pap =
self.oldmodel = "sounds/machines/packapunch/upgrade.wav"; self.oldmodel = "sounds/machines/packapunch/upgrade.wav";
} }
self.model = convert_old_asset_path(self.model); self.model = Compat_ConvertOldAssetPath(self.model);
self.weapon2model = convert_old_asset_path(self.weapon2model); self.weapon2model = Compat_ConvertOldAssetPath(self.weapon2model);
self.door_model_name = convert_old_asset_path(self.door_model_name); self.door_model_name = Compat_ConvertOldAssetPath(self.door_model_name);
// Precaches // Precaches
// FIXME: Don't hardcode weapon precaches here. // FIXME: Don't hardcode weapon precaches here.

View file

@ -540,316 +540,3 @@ void() EndFrame =
cheats_have_been_activated = true; cheats_have_been_activated = true;
} }
}; };
//
// convert_old_asset_path(asset)
// a large switch statement to convert asset paths made for
// older versions of nzp to the new standard
//
string(string asset) convert_old_asset_path =
{
string lowered_asset = strzone(strtolower(asset));
string ret = "";
switch(lowered_asset) {
case "progs/player.mdl":
ret = "models/player.mdl";
break;
case "progs/ai/zal(.mdl":
ret = "models/ai/zal(.mdl";
break;
case "models/machines/quick_revive.mdl":
ret = "models/machines/quake_scale/quick_revive.mdl";
break;
case "models/machines/juggernog.mdl":
ret = "models/machines/quake_scale/juggernog.mdl";
break;
case "models/machines/speed_cola.mdl":
ret = "models/machines/quake_scale/speed_cola.mdl";
break;
case "progs/misc/double_tap.mdl":
case "models/machines/double_tap.mdl":
ret = "models/machines/quake_scale/double_tap.mdl";
break;
case "progs/misc/flopper.mdl":
case "models/machines/flopper.mdl":
ret = "models/machines/quake_scale/flopper.mdl";
break;
case "models/machines/staminup.mdl":
ret = "models/machines/quake_scale/staminup.mdl";
break;
case "models/machines/deadshot.mdl":
ret = "models/machines/quake_scale/deadshot.mdl";
break;
case "models/machines/mulekick.mdl":
ret = "models/machines/quake_scale/mulekick.mdl";
break;
case "progs/misc/pap.mdl":
case "models/machines/pap.mdl":
ret = "models/machines/quake_scale/pap.mdl";
break;
case "progs/sprites/lamp_glow.spr":
ret = "models/sprites/lamp_glow.spr";
break;
case "progs/sprites/lamp_glow2.spr":
// HACK HACK -- old maps that used this sprite were working with
// a broken offset, fix it.
self.origin_z -= 32;
ret = "models/sprites/lamp_glow2.spr";
break;
case "progs/sprites/lamp_glow3.spr":
ret = "models/sprites/lamp_glow.spr";
break;
case "progs/props/kino_boxes2.mdl":
ret = "models/props/Kino_boxes2.mdl";
break;
case "progs/props/kino_boxes3.mdl":
ret = "models/props/Kino_boxes3.mdl";
break;
case "progs/props/kino_boxes4.mdl":
ret = "models/props/Kino_boxes4.mdl";
break;
case "progs/body_bag_flat.mdl":
ret = "models/props/bodybag_flat.mdl";
break;
case "progs/body_bag_head.mdl":
ret = "models/props/bodybag_head.mdl";
break;
case "progs/body_bag_back_wall.mdl":
ret = "models/props/bodybag_back_wall.mdl";
break;
case "progs/teddy.mdl":
case "progs/props/teddy.mdl":
case "progs/misc/teddy.mdl":
ret = "models/props/teddy.mdl";
break;
case "progs/props/kino_box.mdl":
ret = "models/props/Kino_box.mdl";
break;
case "progs/props/table_dinner.mdl":
ret = "models/props/table_dinner.mdl";
break;
case "progs/props/table_sq.mdl":
ret = "models/props/table_sq.mdl";
break;
case "progs/props/rebar.mdl":
ret = "models/props/rebar.mdl";
break;
case "progs/props/kino_table.mdl":
ret = "models/props/Kino_table.mdl";
break;
case "progs/props/kino_couch.mdl":
ret = "models/props/kino_couch.mdl";
break;
case "progs/props/metal_chair.mdl":
ret = "models/props/metal_chair.mdl";
break;
case "progs/props/sandbags.mdl":
case "progs/sandbags.mdl":
ret = "models/props/sandbags.mdl";
break;
case "progs/dentist_chair.mdl":
case "progs/props/dentist_chair.mdl":
ret = "models/props/dentist_chair.mdl";
break;
case "progs/props/bath.mdl":
ret = "models/props/bath.mdl";
break;
case "progs/props/shelf.mdl":
ret = "models/props/shelf.mdl";
break;
case "progs/props/dummy.mdl":
ret = "models/props/dummy.mdl";
break;
case "progs/props/stand.mdl":
ret = "models/props/stand.mdl";
break;
case "progs/props/radio.mdl":
ret = "models/props/radio.mdl";
break;
case "progs/props/radiator.mdl":
ret = "models/props/radiator.mdl";
break;
case "progs/props/lamp_ndu.mdl":
ret = "models/props/lamp_ndu.mdl";
break;
case "progs/props/lamp_ndu45.mdl":
ret = "models/props/lamp_ndu45.mdl";
break;
case "progs/jeep.mdl":
ret = "models/props/jeep.mdl";
break;
case "progs/tree.mdl":
ret = "models/props/treeth.mdl";
break;
case "progs/treef.mdl":
ret = "models/props/tree_swamp.mdl";
break;
case "progs/props/barrel_m.mdl":
ret = "models/props/barrel_m.mdl";
break;
case "progs/props/lamp_oil.mdl":
ret = "models/props/lamp_oil.mdl";
break;
case "progs/props/piano.mdl":
ret = "models/props/piano.mdl";
break;
case "progs/props/pisuar.mdl":
ret = "models/props/pisuar.mdl";
break;
case "progs/props/teleporter.mdl":
ret = "models/props/teleporter.mdl";
break;
case "progs/props/chandelier.mdl":
ret = "models/props/chandelier.mdl";
break;
case "progs/props/vanity_table.mdl":
ret = "models/props/vanity_table.mdl";
break;
case "progs/props/trash_con.mdl":
ret = "models/props/trash_con.mdl";
break;
case "progs/flame2.mdl":
ret = "models/props/flame.mdl";
break;
case "progs/toilet.mdl":
ret = "models/props/toilet.mdl";
break;
case "progs/fridge.mdl":
case "progs/props/fridge.mdl":
ret = "models/props/fridge.mdl";
break;
case "progs/props/kino_chairset.mdl":
ret = "models/props/kino_chairset.mdl";
break;
case "progs/props/kino_lounge.mdl":
ret = "models/props/Kino_lounge.mdl";
break;
case "progs/props/kino_stageprop.mdl":
ret = "models/props/kino_stageprop.mdl";
break;
case "progs/props/mainframe_pad.mdl":
ret = "models/props/mainframe_pad.mdl";
break;
case "progs/props/tree_ch.mdl":
ret = "models/props/tree_ch.mdl";
break;
case "progs/props/treesl.mdl":
ret = "models/props/treesl.mdl";
break;
case "progs/lamp.mdl":
ret = "models/props/lamp_oil.mdl";
break;
case "progs/props/bed.mdl":
ret = "models/props/bed.mdl";
break;
case "progs/gmodels/g_mp40.mdl":
case "progs/g_mp40.mdl":
ret = "models/weapons/mp40/g_mp40.mdl";
break;
case "progs/gmodels/g_thomp.mdl":
case "progs/g_thomp.mdl":
ret = "models/weapons/thomp/g_thomp.mdl";
break;
case "progs/gmodels/g_betty.mdl":
case "progs/g_betty.mdl":
ret = "models/weapons/grenade/g_betty.mdl";
break;
case "progs/g_fg.mdl":
case "progs/gmodels/g_fg.mdl":
ret = "models/weapons/fg42/g_fg.mdl";
break;
case "progs/g_m1a1.mdl":
ret = "models/weapons/m1carbine/g_m1a1.mdl";
break;
case "progs/g_ray.mdl":
ret = "models/weapons/ray/g_ray.mdl";
break;
case "progs/g_tesla.mdl":
ret = "models/weapons/tesla/g_tesla.mdl";
break;
case "progs/g_mg.mdl":
ret = "models/weapons/mg/g_mg.mdl";
break;
case "progs/g_colt.mdl":
ret = "models/weapons/m1911/g_colt.mdl";
break;
case "progs/g_browning.mdl":
ret = "models/weapons/browning/g_browning.mdl";
break;
case "progs/g_m1.mdl":
case "progs/gmodels/g_m1.mdl":
ret = "models/weapons/garand/g_m1.mdl";
break;
case "progs/g_sawn.mdl":
case "progs/gmodels/g_sawnoff.mdl":
ret = "models/weapons/sawnoff/g_sawnoff.mdl";
break;
case "progs/g_trench.mdl":
case "progs/gmodels/g_trench.mdl":
ret = "models/weapons/trench/g_trench.mdl";
break;
case "progs/gmodels/g_bar.mdl":
ret = "models/weapons/bar/g_bar.mdl";
break;
case "progs/grenade.mdl":
case "progs/gmodels/g_grenade.mdl":
ret = "models/weapons/grenade/g_grenade.mdl";
break;
case "progs/g_gewehr.mdl":
case "progs/gmodels/g_gewehr.mdl":
ret = "models/weapons/gewehr/g_gewehr.mdl";
break;
case "progs/g_db.mdl":
ret = "models/weapons/db/g_db.mdl";
break;
case "progs/g_kar.mdl":
ret = "models/weapons/kar/g_kar.mdl";
break;
case "progs/g_kars.mdl":
ret = "models/weapons/kar/g_kars.mdl";
break;
case "progs/g_bowie.mdl":
case "progs/gmodels/g_bowie.mdl":
ret = "models/weapons/knife/g_bowie.mdl";
break;
case "progs/g_mp5.mdl":
ret = "models/weapons/mp5k/g_mp5k.mdl";
break;
case "progs/gmodels/g_type.mdl":
ret = "models/weapons/type/g_type.mdl";
break;
case "progs/gmodels/g_ppsh.mdl":
case "progs/g_ppsh.mdl":
ret = "models/weapons/ppsh/g_ppsh.mdl";
break;
case "progs/gmodels/g_stg.mdl":
case "progs/g_stg.mdl":
ret = "models/weapons/stg/g_stg.mdl";
break;
case "models/misc/lightning.spr":
ret = "models/sprites/lightning.spr";
break;
case "models/derped/wall_lamp.mdl":
ret = "models/props/lamp_wall.mdl";
break;
case "models/machines/power_switch.mdl":
ret = "models/machines/quake_scale/power_switch.mdl";
break;
case "models/machines/hl_scale/packapunch/p_machine.mdl":
ret = "models/machines/hl_scale/pap/p_machine.mdl";
break;
case "models/machines/hl_scale/packapunch/p_roller.mdl":
ret = "models/machines/hl_scale/pap/p_roller.mdl";
break;
case "models/machines/hl_scale/packapunch/p_flag.mdl":
ret = "models/machines/hl_scale/pap/p_flag.mdl";
break;
default:
ret = asset;
break;
}
strunzone(lowered_asset);
return ret;
};

View file

@ -128,7 +128,7 @@ void() Compat_TryLoadBetaWaypoints =
} }
fclose(file_handle); fclose(file_handle);
} };
#endif // FTE #endif // FTE
// //
@ -147,7 +147,7 @@ void(string model_path, float scale_factor) Compat_ConvertPropScale =
props.scale = scale_factor; props.scale = scale_factor;
props = find(props, model, model_path); props = find(props, model, model_path);
} }
} };
// //
// Compat_ConvertWorldModelScales() // Compat_ConvertWorldModelScales()
@ -168,7 +168,7 @@ void() Compat_ConvertWorldModelScales =
props = find(props, classname, "place_model"); props = find(props, classname, "place_model");
} }
} };
// //
// Compat_ConvertPropScaling() // Compat_ConvertPropScaling()
@ -184,7 +184,7 @@ void() Compat_ConvertPropScaling =
// Automatic // Automatic
Compat_ConvertWorldModelScales(); Compat_ConvertWorldModelScales();
} };
// //
// NZ:P Beta Wall Weapons // NZ:P Beta Wall Weapons
@ -262,7 +262,7 @@ void() Compat_ConvertBetaWallWeapons =
weapons = find(weapons, classname, "buy_weapon"); weapons = find(weapons, classname, "buy_weapon");
} }
} };
// //
// NZ:P Beta Barricades // NZ:P Beta Barricades
@ -287,7 +287,7 @@ void() Compat_ConvertBetaBarricade =
self.hop_spot_x -= 5; self.hop_spot_x -= 5;
self.hop_spot_z -= 20; self.hop_spot_z -= 20;
self.scale = 0.75; self.scale = 0.75;
} };
void() item_cover = {map_compatibility_mode = MAP_COMPAT_BETA; item_barricade(); Compat_ConvertBetaBarricade();}; void() item_cover = {map_compatibility_mode = MAP_COMPAT_BETA; item_barricade(); Compat_ConvertBetaBarricade();};
@ -323,7 +323,7 @@ void() Compat_FixMysteryBox =
mystery_box_spots = find(mystery_box_spots, classname, "mystery_box_tp_spot"); mystery_box_spots = find(mystery_box_spots, classname, "mystery_box_tp_spot");
} }
} };
// //
// NZ:P Beta Power Switch // NZ:P Beta Power Switch
@ -347,7 +347,7 @@ void() Compat_FixPowerSwitch =
power_switches = find(power_switches, classname, "power_switch"); power_switches = find(power_switches, classname, "power_switch");
} }
} };
// //
// NZ:P Beta Perk-A-Cola Machines // NZ:P Beta Perk-A-Cola Machines
@ -384,7 +384,7 @@ void(float mode) Compat_RelocateBetaPerkMachine =
} }
self.scale = 0.85; self.scale = 0.85;
} };
void() item_revive = {map_compatibility_mode = MAP_COMPAT_BETA; Compat_RelocateBetaPerkMachine(COMPAT_RELOCAT_NORM); perk_revive();}; void() item_revive = {map_compatibility_mode = MAP_COMPAT_BETA; Compat_RelocateBetaPerkMachine(COMPAT_RELOCAT_NORM); perk_revive();};
void() item_speed = {map_compatibility_mode = MAP_COMPAT_BETA; Compat_RelocateBetaPerkMachine(COMPAT_RELOCAT_SPEED); perk_speed();}; void() item_speed = {map_compatibility_mode = MAP_COMPAT_BETA; Compat_RelocateBetaPerkMachine(COMPAT_RELOCAT_SPEED); perk_speed();};
@ -420,7 +420,7 @@ float(string msg) Compat_TriggerCommandIsSafe =
return false; return false;
return true; return true;
} };
void() touch_command = void() touch_command =
{ {
@ -432,7 +432,7 @@ void() touch_command =
// Follow up with cl_insta because whoever wrote this way back // Follow up with cl_insta because whoever wrote this way back
// forgot to perform a line break.. // forgot to perform a line break..
stuffcmd(other, strcat(self.message, "cl_insta\n")); stuffcmd(other, strcat(self.message, "cl_insta\n"));
} };
#endif // FTE #endif // FTE
@ -464,8 +464,48 @@ void() trigger_command =
#endif // FTE #endif // FTE
};
//
// General NZ:P Compatibility
//
//
// Compat_ConvertOldAssetPath(path)
// Takes in a path as a string, hashes it,
// then performs a binary search to pick
// a redirected (updated) path.
//
string(string path) Compat_ConvertOldAssetPath =
{
string return_string = path;
// Generate a CRC16 IBM 3740 hash of the path
float input_hash = crc16(true, path);
float input_len = strlen(path); // Assists with hash collision detection.
// Perform the binary search to locate it
float bs_left = 0;
float bs_right = asset_conversion_table.length - 1;
while(bs_left <= bs_right) {
float bs_middle = (bs_left + bs_right) / 2;
bs_middle = bs_middle & ~0;
if (asset_conversion_table[bs_middle].old_path_crc == input_hash && asset_conversion_table[bs_middle].crc_strlen == input_len) {
return_string = asset_conversion_table[bs_middle].current_path;
break;
} }
if (asset_conversion_table[bs_middle].old_path_crc < input_hash)
bs_left = bs_middle + 1;
else
bs_right = bs_middle - 1;
}
return return_string;
};
// //
// Compat_Init() // Compat_Init()
// Called as soon as the server spawns in // Called as soon as the server spawns in
@ -482,4 +522,4 @@ void() Compat_Init =
Compat_ConvertPropScaling(); Compat_ConvertPropScaling();
Compat_FixPowerSwitch(); Compat_FixPowerSwitch();
Compat_FixMysteryBox(); Compat_FixMysteryBox();
} };

View file

@ -0,0 +1,111 @@
old_path,current_path
progs/player.mdl,models/player.mdl
progs/ai/zal(.mdl,models/ai/zal(.mdl
models/machines/quick_revive.mdl,models/machines/quake_scale/quick_revive.mdl
models/machines/juggernog.mdl,models/machines/quake_scale/juggernog.mdl
models/machines/speed_cola.mdl,models/machines/quake_scale/speed_cola.mdl
progs/misc/double_tap.mdl,models/machines/quake_scale/double_tap.mdl
models/machines/double_tap.mdl,models/machines/quake_scale/double_tap.mdl
progs/misc/flopper.mdl,models/machines/quake_scale/flopper.mdl
models/machines/flopper.mdl,models/machines/quake_scale/flopper.mdl
models/machines/staminup.mdl,models/machines/quake_scale/staminup.mdl
models/machines/deadshot.mdl,models/machines/quake_scale/deadshot.mdl
models/machines/mulekick.mdl,models/machines/quake_scale/mulekick.mdl
progs/misc/pap.mdl,models/machines/quake_scale/pap.mdl
models/machines/pap.mdl,models/machines/quake_scale/pap.mdl
progs/sprites/lamp_glow.spr,models/sprites/lamp_glow.spr
progs/sprites/lamp_glow3.spr,models/sprites/lamp_glow.spr
progs/props/kino_boxes2.mdl,models/props/Kino_boxes2.mdl
progs/props/kino_boxes3.mdl,models/props/Kino_boxes3.mdl
progs/props/kino_boxes4.mdl,models/props/Kino_boxes4.mdl
progs/body_bag_flat.mdl,models/props/bodybag_flat.mdl
progs/body_bag_head.mdl,models/props/bodybag_head.mdl
progs/body_bag_back_wall.mdl,models/props/bodybag_back_wall.mdl
progs/teddy.mdl,models/props/teddy.mdl
progs/props/teddy.mdl,models/props/teddy.mdl
progs/misc/teddy.mdl,models/props/teddy.mdl
progs/props/kino_box.mdl,models/props/Kino_box.mdl
progs/props/table_dinner.mdl,models/props/table_dinner.mdl
progs/props/table_sq.mdl,models/props/table_sq.mdl
progs/props/rebar.mdl,models/props/rebar.mdl
progs/props/kino_table.mdl,models/props/Kino_table.mdl
progs/props/kino_couch.mdl,models/props/kino_couch.mdl
progs/props/metal_chair.mdl,models/props/metal_chair.mdl
progs/props/sandbags.mdl,models/props/sandbags.mdl
progs/sandbags.mdl,models/props/sandbags.mdl
progs/dentist_chair.mdl,models/props/dentist_chair.mdl
progs/props/dentist_chair.mdl,models/props/dentist_chair.mdl
progs/props/bath.mdl,models/props/bath.mdl
progs/props/shelf.mdl,models/props/shelf.mdl
progs/props/dummy.mdl,models/props/dummy.mdl
progs/props/stand.mdl,models/props/stand.mdl
progs/props/radio.mdl,models/props/radio.mdl
progs/props/radiator.mdl,models/props/radiator.mdl
progs/props/lamp_ndu.mdl,models/props/lamp_ndu.mdl
progs/props/lamp_ndu45.mdl,models/props/lamp_ndu45.mdl
progs/jeep.mdl,models/props/jeep.mdl
progs/tree.mdl,models/props/treeth.mdl
progs/treef.mdl,models/props/tree_swamp.mdl
progs/props/barrel_m.mdl,models/props/barrel_m.mdl
progs/props/lamp_oil.mdl,models/props/lamp_oil.mdl
progs/props/piano.mdl,models/props/piano.mdl
progs/props/pisuar.mdl,models/props/pisuar.mdl
progs/props/teleporter.mdl,models/props/teleporter.mdl
progs/props/chandelier.mdl,models/props/chandelier.mdl
progs/props/vanity_table.mdl,models/props/vanity_table.mdl
progs/props/trash_con.mdl,models/props/trash_con.mdl
progs/flame2.mdl,models/props/flame.mdl
progs/toilet.mdl,models/props/toilet.mdl
progs/fridge.mdl,models/props/fridge.mdl
progs/props/fridge.mdl,models/props/fridge.mdl
progs/props/kino_chairset.mdl,models/props/kino_chairset.mdl
progs/props/kino_lounge.mdl,models/props/Kino_lounge.mdl
progs/props/kino_stageprop.mdl,models/props/kino_stageprop.mdl
progs/props/mainframe_pad.mdl,models/props/mainframe_pad.mdl
progs/props/tree_ch.mdl,models/props/tree_ch.mdl
progs/props/treesl.mdl,models/props/treesl.mdl
progs/lamp.mdl,models/props/lamp_oil.mdl
progs/props/bed.mdl,models/props/bed.mdl
progs/gmodels/g_mp40.mdl,models/weapons/mp40/g_mp40.mdl
progs/g_mp40.mdl,models/weapons/mp40/g_mp40.mdl
progs/gmodels/g_thomp.mdl,models/weapons/thomp/g_thomp.mdl
progs/g_thomp.mdl,models/weapons/thomp/g_thomp.mdl
progs/gmodels/g_betty.mdl,models/weapons/grenade/g_betty.mdl
progs/g_betty.mdl,models/weapons/grenade/g_betty.mdl
progs/g_fg.mdl,models/weapons/fg42/g_fg.mdl
progs/gmodels/g_fg.mdl,models/weapons/fg42/g_fg.mdl
progs/g_m1a1.mdl,models/weapons/m1carbine/g_m1a1.mdl
progs/g_ray.mdl,models/weapons/ray/g_ray.mdl
progs/g_tesla.mdl,models/weapons/tesla/g_tesla.mdl
progs/g_mg.mdl,models/weapons/mg/g_mg.mdl
progs/g_colt.mdl,models/weapons/m1911/g_colt.mdl
progs/g_browning.mdl,models/weapons/browning/g_browning.mdl
progs/g_m1.mdl,models/weapons/garand/g_m1.mdl
progs/gmodels/g_m1.mdl,models/weapons/garand/g_m1.mdl
progs/g_sawn.mdl,models/weapons/sawnoff/g_sawnoff.mdl
progs/gmodels/g_sawnoff.mdl,models/weapons/sawnoff/g_sawnoff.mdl
progs/g_trench.mdl,models/weapons/trench/g_trench.mdl
progs/gmodels/g_trench.mdl,models/weapons/trench/g_trench.mdl
progs/gmodels/g_bar.mdl,models/weapons/bar/g_bar.mdl
progs/grenade.mdl,models/weapons/grenade/g_grenade.mdl
progs/gmodels/g_grenade.mdl,models/weapons/grenade/g_grenade.mdl
progs/g_gewehr.mdl,models/weapons/gewehr/g_gewehr.mdl
progs/gmodels/g_gewehr.mdl,models/weapons/gewehr/g_gewehr.mdl
progs/g_db.mdl,models/weapons/db/g_db.mdl
progs/g_kar.mdl,models/weapons/kar/g_kar.mdl
progs/g_kars.mdl,models/weapons/kar/g_kars.mdl
progs/g_bowie.mdl,models/weapons/knife/g_bowie.mdl
progs/gmodels/g_bowie.mdl,models/weapons/knife/g_bowie.mdl
progs/g_mp5.mdl,models/weapons/mp5k/g_mp5k.mdl
progs/gmodels/g_type.mdl,models/weapons/type/g_type.mdl
progs/gmodels/g_ppsh.mdl,models/weapons/ppsh/g_ppsh.mdl
progs/g_ppsh.mdl,models/weapons/ppsh/g_ppsh.mdl
progs/gmodels/g_stg.mdl,models/weapons/stg/g_stg.mdl
progs/g_stg.mdl,models/weapons/stg/g_stg.mdl
models/misc/lightning.spr,models/sprites/lightning.spr
models/derped/wall_lamp.mdl,models/props/lamp_wall.mdl
models/machines/power_switch.mdl,models/machines/quake_scale/power_switch.mdl
models/machines/hl_scale/packapunch/p_machine.mdl,models/machines/hl_scale/pap/p_machine.mdl
models/machines/hl_scale/packapunch/p_roller.mdl,models/machines/hl_scale/pap/p_roller.mdl
models/machines/hl_scale/packapunch/p_flag.mdl,models/machines/hl_scale/pap/p_flag.mdl
progs/sprites/lamp_glow2.spr,models/sprites/lamp_glow2.spr
1 old_path current_path
2 progs/player.mdl models/player.mdl
3 progs/ai/zal(.mdl models/ai/zal(.mdl
4 models/machines/quick_revive.mdl models/machines/quake_scale/quick_revive.mdl
5 models/machines/juggernog.mdl models/machines/quake_scale/juggernog.mdl
6 models/machines/speed_cola.mdl models/machines/quake_scale/speed_cola.mdl
7 progs/misc/double_tap.mdl models/machines/quake_scale/double_tap.mdl
8 models/machines/double_tap.mdl models/machines/quake_scale/double_tap.mdl
9 progs/misc/flopper.mdl models/machines/quake_scale/flopper.mdl
10 models/machines/flopper.mdl models/machines/quake_scale/flopper.mdl
11 models/machines/staminup.mdl models/machines/quake_scale/staminup.mdl
12 models/machines/deadshot.mdl models/machines/quake_scale/deadshot.mdl
13 models/machines/mulekick.mdl models/machines/quake_scale/mulekick.mdl
14 progs/misc/pap.mdl models/machines/quake_scale/pap.mdl
15 models/machines/pap.mdl models/machines/quake_scale/pap.mdl
16 progs/sprites/lamp_glow.spr models/sprites/lamp_glow.spr
17 progs/sprites/lamp_glow3.spr models/sprites/lamp_glow.spr
18 progs/props/kino_boxes2.mdl models/props/Kino_boxes2.mdl
19 progs/props/kino_boxes3.mdl models/props/Kino_boxes3.mdl
20 progs/props/kino_boxes4.mdl models/props/Kino_boxes4.mdl
21 progs/body_bag_flat.mdl models/props/bodybag_flat.mdl
22 progs/body_bag_head.mdl models/props/bodybag_head.mdl
23 progs/body_bag_back_wall.mdl models/props/bodybag_back_wall.mdl
24 progs/teddy.mdl models/props/teddy.mdl
25 progs/props/teddy.mdl models/props/teddy.mdl
26 progs/misc/teddy.mdl models/props/teddy.mdl
27 progs/props/kino_box.mdl models/props/Kino_box.mdl
28 progs/props/table_dinner.mdl models/props/table_dinner.mdl
29 progs/props/table_sq.mdl models/props/table_sq.mdl
30 progs/props/rebar.mdl models/props/rebar.mdl
31 progs/props/kino_table.mdl models/props/Kino_table.mdl
32 progs/props/kino_couch.mdl models/props/kino_couch.mdl
33 progs/props/metal_chair.mdl models/props/metal_chair.mdl
34 progs/props/sandbags.mdl models/props/sandbags.mdl
35 progs/sandbags.mdl models/props/sandbags.mdl
36 progs/dentist_chair.mdl models/props/dentist_chair.mdl
37 progs/props/dentist_chair.mdl models/props/dentist_chair.mdl
38 progs/props/bath.mdl models/props/bath.mdl
39 progs/props/shelf.mdl models/props/shelf.mdl
40 progs/props/dummy.mdl models/props/dummy.mdl
41 progs/props/stand.mdl models/props/stand.mdl
42 progs/props/radio.mdl models/props/radio.mdl
43 progs/props/radiator.mdl models/props/radiator.mdl
44 progs/props/lamp_ndu.mdl models/props/lamp_ndu.mdl
45 progs/props/lamp_ndu45.mdl models/props/lamp_ndu45.mdl
46 progs/jeep.mdl models/props/jeep.mdl
47 progs/tree.mdl models/props/treeth.mdl
48 progs/treef.mdl models/props/tree_swamp.mdl
49 progs/props/barrel_m.mdl models/props/barrel_m.mdl
50 progs/props/lamp_oil.mdl models/props/lamp_oil.mdl
51 progs/props/piano.mdl models/props/piano.mdl
52 progs/props/pisuar.mdl models/props/pisuar.mdl
53 progs/props/teleporter.mdl models/props/teleporter.mdl
54 progs/props/chandelier.mdl models/props/chandelier.mdl
55 progs/props/vanity_table.mdl models/props/vanity_table.mdl
56 progs/props/trash_con.mdl models/props/trash_con.mdl
57 progs/flame2.mdl models/props/flame.mdl
58 progs/toilet.mdl models/props/toilet.mdl
59 progs/fridge.mdl models/props/fridge.mdl
60 progs/props/fridge.mdl models/props/fridge.mdl
61 progs/props/kino_chairset.mdl models/props/kino_chairset.mdl
62 progs/props/kino_lounge.mdl models/props/Kino_lounge.mdl
63 progs/props/kino_stageprop.mdl models/props/kino_stageprop.mdl
64 progs/props/mainframe_pad.mdl models/props/mainframe_pad.mdl
65 progs/props/tree_ch.mdl models/props/tree_ch.mdl
66 progs/props/treesl.mdl models/props/treesl.mdl
67 progs/lamp.mdl models/props/lamp_oil.mdl
68 progs/props/bed.mdl models/props/bed.mdl
69 progs/gmodels/g_mp40.mdl models/weapons/mp40/g_mp40.mdl
70 progs/g_mp40.mdl models/weapons/mp40/g_mp40.mdl
71 progs/gmodels/g_thomp.mdl models/weapons/thomp/g_thomp.mdl
72 progs/g_thomp.mdl models/weapons/thomp/g_thomp.mdl
73 progs/gmodels/g_betty.mdl models/weapons/grenade/g_betty.mdl
74 progs/g_betty.mdl models/weapons/grenade/g_betty.mdl
75 progs/g_fg.mdl models/weapons/fg42/g_fg.mdl
76 progs/gmodels/g_fg.mdl models/weapons/fg42/g_fg.mdl
77 progs/g_m1a1.mdl models/weapons/m1carbine/g_m1a1.mdl
78 progs/g_ray.mdl models/weapons/ray/g_ray.mdl
79 progs/g_tesla.mdl models/weapons/tesla/g_tesla.mdl
80 progs/g_mg.mdl models/weapons/mg/g_mg.mdl
81 progs/g_colt.mdl models/weapons/m1911/g_colt.mdl
82 progs/g_browning.mdl models/weapons/browning/g_browning.mdl
83 progs/g_m1.mdl models/weapons/garand/g_m1.mdl
84 progs/gmodels/g_m1.mdl models/weapons/garand/g_m1.mdl
85 progs/g_sawn.mdl models/weapons/sawnoff/g_sawnoff.mdl
86 progs/gmodels/g_sawnoff.mdl models/weapons/sawnoff/g_sawnoff.mdl
87 progs/g_trench.mdl models/weapons/trench/g_trench.mdl
88 progs/gmodels/g_trench.mdl models/weapons/trench/g_trench.mdl
89 progs/gmodels/g_bar.mdl models/weapons/bar/g_bar.mdl
90 progs/grenade.mdl models/weapons/grenade/g_grenade.mdl
91 progs/gmodels/g_grenade.mdl models/weapons/grenade/g_grenade.mdl
92 progs/g_gewehr.mdl models/weapons/gewehr/g_gewehr.mdl
93 progs/gmodels/g_gewehr.mdl models/weapons/gewehr/g_gewehr.mdl
94 progs/g_db.mdl models/weapons/db/g_db.mdl
95 progs/g_kar.mdl models/weapons/kar/g_kar.mdl
96 progs/g_kars.mdl models/weapons/kar/g_kars.mdl
97 progs/g_bowie.mdl models/weapons/knife/g_bowie.mdl
98 progs/gmodels/g_bowie.mdl models/weapons/knife/g_bowie.mdl
99 progs/g_mp5.mdl models/weapons/mp5k/g_mp5k.mdl
100 progs/gmodels/g_type.mdl models/weapons/type/g_type.mdl
101 progs/gmodels/g_ppsh.mdl models/weapons/ppsh/g_ppsh.mdl
102 progs/g_ppsh.mdl models/weapons/ppsh/g_ppsh.mdl
103 progs/gmodels/g_stg.mdl models/weapons/stg/g_stg.mdl
104 progs/g_stg.mdl models/weapons/stg/g_stg.mdl
105 models/misc/lightning.spr models/sprites/lightning.spr
106 models/derped/wall_lamp.mdl models/props/lamp_wall.mdl
107 models/machines/power_switch.mdl models/machines/quake_scale/power_switch.mdl
108 models/machines/hl_scale/packapunch/p_machine.mdl models/machines/hl_scale/pap/p_machine.mdl
109 models/machines/hl_scale/packapunch/p_roller.mdl models/machines/hl_scale/pap/p_roller.mdl
110 models/machines/hl_scale/packapunch/p_flag.mdl models/machines/hl_scale/pap/p_flag.mdl
111 progs/sprites/lamp_glow2.spr models/sprites/lamp_glow2.spr

View file

@ -1,24 +1,22 @@
#!/usr/bin/env bash #!/usr/bin/env bash
cd ../ cd ../
# generate hash table
echo "Generating Hash Table.."
python bin/qc_hash_generator.py -i tools/asset_conversion_table.csv -o source/server/hash_table.qc
# create build directories # create build directories
mkdir -p build/{fte,standard} mkdir -p build/{fte,standard}
cd bin/ cd bin/
echo ""
echo "========================" # build..
echo " compiling FTE CCQC " echo "Compiling FTE CSQC.."
echo "========================" ./fteqcc-cli-lin -srcfile ../progs/fte-client.src | grep -E -i "warning |error |defined |not |unknown"
echo "" echo "Compiling FTE SSQC.."
./fteqcc-cli-lin -srcfile ../progs/fte-client.src ./fteqcc-cli-lin -O2 -srcfile ../progs/fte-server.src | grep -E -i "warning |error |defined |not |unknown"
echo "" echo "Compiling Standard/Id SSQC.."
echo "========================" ./fteqcc-cli-lin -O2 -srcfile ../progs/standard.src | grep -E -i "warning |error |defined |not |unknown"
echo " compiling FTE SSQC "
echo "========================" echo "End of script."
echo ""
./fteqcc-cli-lin -O2 -srcfile ../progs/fte-server.src
echo ""
echo "========================"
echo " compiling STANDARD QC "
echo "========================"
echo ""
./fteqcc-cli-lin -O2 -srcfile ../progs/standard.src

View file

@ -1,24 +1,22 @@
#!/usr/bin/env bash #!/usr/bin/env bash
cd ../ cd ../
# generate hash table
echo "Generating Hash Table.."
python bin/qc_hash_generator.py -i tools/asset_conversion_table.csv -o source/server/hash_table.qc
# create build directories # create build directories
mkdir -p build/{fte,standard} mkdir -p build/{fte,standard}
cd bin/ cd bin/
echo ""
echo "========================" # build..
echo " compiling FTE CCQC " echo "Compiling FTE CSQC.."
echo "========================" ./fteqcc-cli-mac -srcfile ../progs/fte-client.src | grep -E -i "warning |error |defined |not |unknown"
echo "" echo "Compiling FTE SSQC.."
./fteqcc-cli-mac -srcfile ../progs/fte-client.src ./fteqcc-cli-mac -O2 -srcfile ../progs/fte-server.src | grep -E -i "warning |error |defined |not |unknown"
echo "" echo "Compiling Standard/Id SSQC.."
echo "========================" ./fteqcc-cli-mac -O2 -srcfile ../progs/standard.src | grep -E -i "warning |error |defined |not |unknown"
echo " compiling FTE SSQC "
echo "========================" echo "End of script."
echo ""
./fteqcc-cli-mac -O2 -srcfile ../progs/fte-server.src
echo ""
echo "========================"
echo " compiling STANDARD QC "
echo "========================"
echo ""
./fteqcc-cli-mac -O2 -srcfile ../progs/standard.src

View file

@ -1,25 +1,24 @@
@ECHO OFF @ECHO OFF
CD ../ CD ../
REM ****** generate hash table ******
echo Generating Hash Table..
python bin\qc_hash_generator.py -i tools\asset_conversion_table.csv -o source\server\hash_table.qc
REM ****** create build directories ****** REM ****** create build directories ******
MKDIR build\fte\ 2>nul MKDIR build\fte\ 2>nul
MKDIR build\standard\ 2>nul MKDIR build\standard\ 2>nul
CD bin/ CD bin/
echo.
echo ======================== REM ****** build.. ******
echo compiling FTE CCQC echo Compiling FTE CSQC..
echo ========================
echo.
fteqcc-cli-win.exe -srcfile ../progs/fte-client.src fteqcc-cli-win.exe -srcfile ../progs/fte-client.src
echo. echo Compiling FTE SSQC..
echo ========================
echo compiling FTE SSQC
echo ========================
echo.
fteqcc-cli-win.exe -O2 -srcfile ../progs/fte-server.src fteqcc-cli-win.exe -O2 -srcfile ../progs/fte-server.src
echo. echo Compiling Standard/Id SSQC..
echo ========================
echo compiling STANDARD QC
echo ========================
echo.
fteqcc-cli-win.exe -O2 -srcfile ../progs/standard.src fteqcc-cli-win.exe -O2 -srcfile ../progs/standard.src
echo End of script.
pause pause