mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 01:58:19 +00:00
larger restructure to improve security
This commit is contained in:
parent
1ea859c431
commit
4739966e14
|
@ -81,4 +81,3 @@ const array:int image = images.*
|
||||||
const array:int sprite = sprites.*.*
|
const array:int sprite = sprites.*.*
|
||||||
const array:int anim = animations.*
|
const array:int anim = animations.*
|
||||||
const array:int powerup = powerups.*
|
const array:int powerup = powerups.*
|
||||||
const array:int gametype = playerstats.*
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
const array:int sound = sounds.*
|
const array:int sound = sounds.*
|
||||||
const array:int weapon = weapons.*
|
const array:int weapon = weapons.*
|
||||||
const array:int powerup = powerups.*
|
const array:int powerup = powerups.*
|
||||||
const array:int gametype = playerstats.*
|
|
||||||
|
|
||||||
struct weapon {
|
struct weapon {
|
||||||
int firedelay = firedelay@1
|
int firedelay = firedelay@1
|
||||||
|
|
34
default.bam
34
default.bam
|
@ -5,6 +5,11 @@ if family == "windows" then
|
||||||
dc_compiler = "scripts\\compiler.py"
|
dc_compiler = "scripts\\compiler.py"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
netobj_compiler = "python scripts/netobj.py"
|
||||||
|
if family == "windows" then
|
||||||
|
netobj_compiler = "scripts\\netobj.py"
|
||||||
|
end
|
||||||
|
|
||||||
dat2c_compiler = "python scripts/dat2c.py"
|
dat2c_compiler = "python scripts/dat2c.py"
|
||||||
if family == "windows" then
|
if family == "windows" then
|
||||||
dat2c_compiler = "scripts\\dat2c.py"
|
dat2c_compiler = "scripts\\dat2c.py"
|
||||||
|
@ -56,6 +61,15 @@ function dc_cdata(output, data, script)
|
||||||
return os.execute(dc_compiler .. " " .. data .. " " .. script .. " -c " .. output)
|
return os.execute(dc_compiler .. " " .. data .. " " .. script .. " -c " .. output)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function netobj_source(output, proto)
|
||||||
|
print("netobj source " .. PathFilename(output) .. " = " .. PathFilename(proto))
|
||||||
|
return os.execute(netobj_compiler .. " source " .. proto .. " " .. output)
|
||||||
|
end
|
||||||
|
|
||||||
|
function netobj_header(output, proto)
|
||||||
|
print("netobj header " .. PathFilename(output) .. " = " .. PathFilename(proto))
|
||||||
|
return os.execute(netobj_compiler .. " header " .. proto .. " " .. output)
|
||||||
|
end
|
||||||
|
|
||||||
function CHash(output, ...)
|
function CHash(output, ...)
|
||||||
local inputs = {}
|
local inputs = {}
|
||||||
|
@ -91,6 +105,17 @@ function Dat2c(datafile, sourcefile, arrayname)
|
||||||
return sourcefile
|
return sourcefile
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function NetObjCompile(protofile, sourcefile, headerfile)
|
||||||
|
protofile = Path(protofile)
|
||||||
|
sourcefile = Path(sourcefile)
|
||||||
|
headerfile = Path(headerfile)
|
||||||
|
bam_add_job("netobj_source", sourcefile, protofile)
|
||||||
|
bam_add_job("netobj_header", headerfile, protofile)
|
||||||
|
bam_add_dependency(sourcefile, protofile)
|
||||||
|
bam_add_dependency(headerfile, protofile)
|
||||||
|
return {source = sourcefile, header=headerfile}
|
||||||
|
end
|
||||||
|
|
||||||
function DataCompile(datafile, scriptfile, headerfile, sourcefile, outputdatafile)
|
function DataCompile(datafile, scriptfile, headerfile, sourcefile, outputdatafile)
|
||||||
datafile = Path(datafile)
|
datafile = Path(datafile)
|
||||||
scriptfile = Path(scriptfile)
|
scriptfile = Path(scriptfile)
|
||||||
|
@ -138,10 +163,15 @@ networkdata = DataCompile(
|
||||||
"src/game/generated/g_protocol_ids.h",
|
"src/game/generated/g_protocol_ids.h",
|
||||||
"src/game/generated/g_protocol_ids.cpp")
|
"src/game/generated/g_protocol_ids.cpp")
|
||||||
|
|
||||||
|
netobj = NetObjCompile(
|
||||||
|
"src/game/g_protocol.def",
|
||||||
|
"src/game/generated/g_protocol.cpp",
|
||||||
|
"src/game/generated/g_protocol.h")
|
||||||
|
|
||||||
nethash = CHash(
|
nethash = CHash(
|
||||||
"src/game/generated/nethash.c",
|
"src/game/generated/nethash.c",
|
||||||
"src/engine/e_protocol.h",
|
"src/engine/e_protocol.h",
|
||||||
"src/game/g_protocol.h",
|
"src/game/generated/g_protocol.h",
|
||||||
"src/game/g_tuning.h",
|
"src/game/g_tuning.h",
|
||||||
"src/game/g_game.cpp", networkdata.header)
|
"src/game/g_game.cpp", networkdata.header)
|
||||||
|
|
||||||
|
@ -260,7 +290,7 @@ function build(settings)
|
||||||
server = Compile(server_settings, Collect("src/engine/server/*.c"))
|
server = Compile(server_settings, Collect("src/engine/server/*.c"))
|
||||||
|
|
||||||
masterserver = Compile(settings, Collect("src/mastersrv/*.cpp"))
|
masterserver = Compile(settings, Collect("src/mastersrv/*.cpp"))
|
||||||
game_shared = Compile(settings, Collect("src/game/*.cpp"), nethash)
|
game_shared = Compile(settings, Collect("src/game/*.cpp"), nethash, netobj.source)
|
||||||
game_client = Compile(settings, Collect("src/game/client/*.cpp"), clientdata.source, clientdata.cdata)
|
game_client = Compile(settings, Collect("src/game/client/*.cpp"), clientdata.source, clientdata.cdata)
|
||||||
game_server = Compile(settings, Collect("src/game/server/*.cpp"), serverdata.source, serverdata.cdata)
|
game_server = Compile(settings, Collect("src/game/server/*.cpp"), serverdata.source, serverdata.cdata)
|
||||||
game_editor = Compile(settings, Collect("src/game/editor/*.cpp"))
|
game_editor = Compile(settings, Collect("src/game/editor/*.cpp"))
|
||||||
|
|
|
@ -487,8 +487,8 @@ class translator:
|
||||||
for s in self.structs:
|
for s in self.structs:
|
||||||
s.emit_header_code(out)
|
s.emit_header_code(out)
|
||||||
print >>out, ""
|
print >>out, ""
|
||||||
print >>out, "data_container *load_data_from_file(const char *filename);"
|
print >>out, "struct data_container *load_data_from_file(const char *filename);"
|
||||||
print >>out, "data_container *load_data_from_memory(unsigned char *filename);"
|
print >>out, "struct data_container *load_data_from_memory(unsigned char *filename);"
|
||||||
print >>out, ""
|
print >>out, ""
|
||||||
|
|
||||||
|
|
||||||
|
|
270
scripts/netobj.py
Normal file
270
scripts/netobj.py
Normal file
|
@ -0,0 +1,270 @@
|
||||||
|
import sys, os
|
||||||
|
|
||||||
|
line_count = 0
|
||||||
|
|
||||||
|
class variable:
|
||||||
|
name = "unknown"
|
||||||
|
def __init__(self, args, name):
|
||||||
|
global line_count
|
||||||
|
self.name = name
|
||||||
|
self.line = line_count
|
||||||
|
def emit_declaration(self):
|
||||||
|
return ["\tint %s;" % self.name]
|
||||||
|
def linedef(self):
|
||||||
|
return "#line %d" % self.line
|
||||||
|
def emit_secure(self):
|
||||||
|
return []
|
||||||
|
|
||||||
|
class var_any(variable):
|
||||||
|
def __init__(self, args, name):
|
||||||
|
variable.__init__(self, args, name)
|
||||||
|
|
||||||
|
class var_range(variable):
|
||||||
|
def __init__(self, args, name):
|
||||||
|
variable.__init__(self, args, name)
|
||||||
|
self.min = args[0]
|
||||||
|
self.max = args[1]
|
||||||
|
def emit_secure(self):
|
||||||
|
return [self.linedef(), "obj->%s = netobj_clamp_int(obj->%s, %s, %s);" % (self.name, self.name, self.min, self.max)]
|
||||||
|
|
||||||
|
class var_clientid(variable):
|
||||||
|
def __init__(self, args, name):
|
||||||
|
variable.__init__(self, args, name)
|
||||||
|
def emit_secure(self):
|
||||||
|
return [self.linedef(), "obj->%s = netobj_clamp_int(obj->%s, -1, MAX_CLIENTS);" % (self.name, self.name)]
|
||||||
|
|
||||||
|
class var_string(variable):
|
||||||
|
def __init__(self, args, name):
|
||||||
|
variable.__init__(self, args, name)
|
||||||
|
|
||||||
|
class object:
|
||||||
|
def __init__(self, line):
|
||||||
|
fields = line.split()
|
||||||
|
self.name = fields[1]
|
||||||
|
self.extends = None
|
||||||
|
if len(fields) == 4 and fields[2] == "extends":
|
||||||
|
self.extends = fields[3]
|
||||||
|
self.enum_name = "NETOBJTYPE_%s" % self.name.upper()
|
||||||
|
self.struct_name = "NETOBJ_%s" % self.name.upper()
|
||||||
|
self.members = []
|
||||||
|
|
||||||
|
def parse(self, lines):
|
||||||
|
global line_count
|
||||||
|
for index in xrange(0, len(lines)):
|
||||||
|
line_count += 1
|
||||||
|
line = lines[index]
|
||||||
|
if not len(line):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if line == "end":
|
||||||
|
return lines[index+1:]
|
||||||
|
else:
|
||||||
|
# check for argument
|
||||||
|
fields = line.split(")", 1)
|
||||||
|
if len(fields) == 2:
|
||||||
|
names = [line.strip() for line in fields[1].split(",")]
|
||||||
|
l = fields[0].split("(", 1)
|
||||||
|
type = l[0]
|
||||||
|
args = [line.strip() for line in l[1].split(",")]
|
||||||
|
else:
|
||||||
|
l = fields[0].split(None, 1)
|
||||||
|
type = l[0]
|
||||||
|
args = []
|
||||||
|
names = [line.strip() for line in l[1].split(",")]
|
||||||
|
|
||||||
|
for name in names:
|
||||||
|
create_string = 'var_%s(%s, "%s")' % (type, args, name)
|
||||||
|
new_member = eval(create_string)
|
||||||
|
self.members += [new_member]
|
||||||
|
|
||||||
|
raise BaseException("Parse error")
|
||||||
|
|
||||||
|
def emit_declaration(self):
|
||||||
|
lines = []
|
||||||
|
if self.extends:
|
||||||
|
lines += ["struct %s : public NETOBJ_%s\n {" % (self.struct_name, self.extends.upper())]
|
||||||
|
else:
|
||||||
|
lines += ["struct %s\n {" % self.struct_name]
|
||||||
|
for m in self.members:
|
||||||
|
lines += m.emit_declaration()
|
||||||
|
lines += ["};"]
|
||||||
|
return lines
|
||||||
|
|
||||||
|
def emit_secure(self):
|
||||||
|
lines = []
|
||||||
|
for m in self.members:
|
||||||
|
lines += m.emit_secure()
|
||||||
|
return lines
|
||||||
|
|
||||||
|
class event(object):
|
||||||
|
def __init__(self, line):
|
||||||
|
object.__init__(self, line)
|
||||||
|
self.enum_name = "NETEVENTTYPE_%s" % self.name.upper()
|
||||||
|
self.struct_name = "NETEVENT_%s" % self.name.upper()
|
||||||
|
|
||||||
|
class raw_reader:
|
||||||
|
def __init__(self):
|
||||||
|
self.raw_lines = []
|
||||||
|
def parse(self, lines):
|
||||||
|
global line_count
|
||||||
|
for index in xrange(0, len(lines)):
|
||||||
|
line_count += 1
|
||||||
|
line = lines[index]
|
||||||
|
if not len(line):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if line == "end":
|
||||||
|
return lines[index+1:]
|
||||||
|
else:
|
||||||
|
self.raw_lines += [line]
|
||||||
|
|
||||||
|
raise BaseException("Parse error")
|
||||||
|
|
||||||
|
class proto:
|
||||||
|
def __init__(self):
|
||||||
|
self.objects = []
|
||||||
|
self.source_raw = []
|
||||||
|
self.header_raw = []
|
||||||
|
|
||||||
|
|
||||||
|
def load(filename):
|
||||||
|
# read the file
|
||||||
|
global line_count
|
||||||
|
line_count = 0
|
||||||
|
lines = [line.strip() for line in file(filename).readlines()]
|
||||||
|
|
||||||
|
p = proto()
|
||||||
|
|
||||||
|
while len(lines):
|
||||||
|
line_count += 1
|
||||||
|
line = lines[0]
|
||||||
|
line = line.split("//", 2)[0] # strip comment
|
||||||
|
|
||||||
|
if not len(line):
|
||||||
|
del lines[0]
|
||||||
|
continue
|
||||||
|
|
||||||
|
fields = line.split(None, 1)
|
||||||
|
|
||||||
|
del lines[0]
|
||||||
|
|
||||||
|
if fields[0] == "object" or fields[0] == "msg":
|
||||||
|
new_obj = object(line)
|
||||||
|
lines = new_obj.parse(lines)
|
||||||
|
p.objects += [new_obj]
|
||||||
|
elif fields[0] == "event":
|
||||||
|
new_obj = event(line)
|
||||||
|
lines = new_obj.parse(lines)
|
||||||
|
p.objects += [new_obj]
|
||||||
|
elif fields[0] == "raw_source":
|
||||||
|
raw = raw_reader()
|
||||||
|
lines = raw.parse(lines)
|
||||||
|
p.source_raw += raw.raw_lines
|
||||||
|
elif fields[0] == "raw_header":
|
||||||
|
raw = raw_reader()
|
||||||
|
lines = raw.parse(lines)
|
||||||
|
p.header_raw += raw.raw_lines
|
||||||
|
else:
|
||||||
|
print "error, strange line:", line
|
||||||
|
|
||||||
|
return p
|
||||||
|
|
||||||
|
def emit_header_file(f, p):
|
||||||
|
for l in p.header_raw:
|
||||||
|
print >>f, l
|
||||||
|
|
||||||
|
if 1: # emit the enum table
|
||||||
|
print >>f, "enum {"
|
||||||
|
print >>f, "\tNETOBJTYPE_INVALID=0,"
|
||||||
|
for obj in p.objects:
|
||||||
|
print >>f, "\t%s," % obj.enum_name
|
||||||
|
print >>f, "\tNUM_NETOBJTYPES"
|
||||||
|
print >>f, "};"
|
||||||
|
print >>f, ""
|
||||||
|
|
||||||
|
print >>f, "int netobj_secure(int type, void *data, int size);"
|
||||||
|
print >>f, "const char *netobj_get_name(int type);"
|
||||||
|
print >>f, ""
|
||||||
|
|
||||||
|
for obj in p.objects:
|
||||||
|
for l in obj.emit_declaration():
|
||||||
|
print >>f, l
|
||||||
|
print >>f, ""
|
||||||
|
|
||||||
|
def emit_source_file(f, p, protofilename):
|
||||||
|
|
||||||
|
|
||||||
|
print >>f, "#line 1 \"%s\"" % os.path.abspath(protofilename)
|
||||||
|
|
||||||
|
for l in p.source_raw:
|
||||||
|
print >>f, l
|
||||||
|
|
||||||
|
print >>f, "static int netobj_clamp_int(int v, int min, int max)"
|
||||||
|
print >>f, "{"
|
||||||
|
print >>f, "if(v<min) return min;"
|
||||||
|
print >>f, "if(v>max) return max;"
|
||||||
|
print >>f, "return v;"
|
||||||
|
print >>f, "}"
|
||||||
|
print >>f, ""
|
||||||
|
|
||||||
|
if 1: # names
|
||||||
|
print >>f, "static const char *object_names[] = {"
|
||||||
|
print >>f, "\t" + '"invalid",'
|
||||||
|
for obj in p.objects:
|
||||||
|
print >>f, '\t"%s",' % obj.name
|
||||||
|
print >>f, '\t""'
|
||||||
|
print >>f, "};"
|
||||||
|
print >>f, ""
|
||||||
|
|
||||||
|
if 1: # secure functions
|
||||||
|
print >>f, "static int secure_object_invalid(void *data, int size) { return 0; }"
|
||||||
|
for obj in p.objects:
|
||||||
|
print >>f, "static int secure_%s(void *data, int size)" % obj.name
|
||||||
|
print >>f, "{"
|
||||||
|
print >>f, "\t%s *obj = (%s *)data;" % (obj.struct_name, obj.struct_name)
|
||||||
|
print >>f, "\t(void)obj;" # to get rid of "unused variable" warning
|
||||||
|
print >>f, "\tif(size != sizeof(%s)) return -1;" % obj.struct_name
|
||||||
|
if obj.extends:
|
||||||
|
print >>f, "\tif(secure_%s(data, sizeof(NETOBJ_%s)) != 0) return -1;" % (obj.extends, obj.extends.upper())
|
||||||
|
|
||||||
|
for l in obj.emit_secure():
|
||||||
|
print >>f, "\t" + l
|
||||||
|
print >>f, "\treturn 0;";
|
||||||
|
print >>f, "}"
|
||||||
|
print >>f, ""
|
||||||
|
|
||||||
|
if 1: # secure function table
|
||||||
|
print >>f, "typedef static int(*SECUREFUNC)(void *data, int size);"
|
||||||
|
print >>f, "static SECUREFUNC secure_funcs[] = {"
|
||||||
|
print >>f, "\t" + 'secure_object_invalid,'
|
||||||
|
for obj in p.objects:
|
||||||
|
print >>f, "\tsecure_%s," % obj.name
|
||||||
|
print >>f, "\t" + '0x0'
|
||||||
|
print >>f, "};"
|
||||||
|
print >>f, ""
|
||||||
|
|
||||||
|
if 1:
|
||||||
|
print >>f, "int netobj_secure(int type, void *data, int size)"
|
||||||
|
print >>f, "{"
|
||||||
|
print >>f, "\tif(type < 0 || type >= NUM_NETOBJTYPES) return -1;"
|
||||||
|
print >>f, "\treturn secure_funcs[type](data, size);"
|
||||||
|
print >>f, "};"
|
||||||
|
print >>f, ""
|
||||||
|
|
||||||
|
if 1:
|
||||||
|
print >>f, "const char *netobj_get_name(int type)"
|
||||||
|
print >>f, "{"
|
||||||
|
print >>f, "\tif(type < 0 || type >= NUM_NETOBJTYPES) return \"(invalid)\";"
|
||||||
|
print >>f, "\treturn object_names[type];"
|
||||||
|
print >>f, "};"
|
||||||
|
print >>f, ""
|
||||||
|
|
||||||
|
if sys.argv[1] == "header":
|
||||||
|
p = load(sys.argv[2])
|
||||||
|
emit_header_file(file(sys.argv[3], "w"), p)
|
||||||
|
elif sys.argv[1] == "source":
|
||||||
|
p = load(sys.argv[2])
|
||||||
|
emit_source_file(file(sys.argv[3], "w"), p, sys.argv[2])
|
||||||
|
else:
|
||||||
|
print "invalid command"
|
||||||
|
sys.exit(-1)
|
|
@ -211,30 +211,48 @@ enum
|
||||||
NUM_SNAPSHOT_TYPES=2
|
NUM_SNAPSHOT_TYPES=2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* the game snapshots are modifiable by the game */
|
||||||
SNAPSTORAGE snapshot_storage;
|
SNAPSTORAGE snapshot_storage;
|
||||||
static SNAPSTORAGE_HOLDER *snapshots[NUM_SNAPSHOT_TYPES];
|
static SNAPSTORAGE_HOLDER *snapshots[NUM_SNAPSHOT_TYPES];
|
||||||
|
|
||||||
static int recived_snapshots;
|
static int recived_snapshots;
|
||||||
static char snapshot_incomming_data[MAX_SNAPSHOT_SIZE];
|
static char snapshot_incomming_data[MAX_SNAPSHOT_SIZE];
|
||||||
|
|
||||||
/* --- */
|
/* --- */
|
||||||
|
|
||||||
const void *snap_get_item(int snapid, int index, SNAP_ITEM *item)
|
void *snap_get_item(int snapid, int index, SNAP_ITEM *item)
|
||||||
{
|
{
|
||||||
SNAPSHOT_ITEM *i;
|
SNAPSHOT_ITEM *i;
|
||||||
dbg_assert(snapid >= 0 && snapid < NUM_SNAPSHOT_TYPES, "invalid snapid");
|
dbg_assert(snapid >= 0 && snapid < NUM_SNAPSHOT_TYPES, "invalid snapid");
|
||||||
i = snapshot_get_item(snapshots[snapid]->snap, index);
|
i = snapshot_get_item(snapshots[snapid]->alt_snap, index);
|
||||||
|
item->datasize = snapshot_get_item_datasize(snapshots[snapid]->alt_snap, index);
|
||||||
item->type = snapitem_type(i);
|
item->type = snapitem_type(i);
|
||||||
item->id = snapitem_id(i);
|
item->id = snapitem_id(i);
|
||||||
return (void *)snapitem_data(i);
|
return (void *)snapitem_data(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
const void *snap_find_item(int snapid, int type, int id)
|
void snap_invalidate_item(int snapid, int index)
|
||||||
|
{
|
||||||
|
SNAPSHOT_ITEM *i;
|
||||||
|
dbg_assert(snapid >= 0 && snapid < NUM_SNAPSHOT_TYPES, "invalid snapid");
|
||||||
|
i = snapshot_get_item(snapshots[snapid]->alt_snap, index);
|
||||||
|
if(i)
|
||||||
|
{
|
||||||
|
if((char *)i < (char *)snapshots[snapid]->alt_snap || (char *)i > (char *)snapshots[snapid]->alt_snap + snapshots[snapid]->snap_size)
|
||||||
|
dbg_msg("ASDFASDFASdf", "ASDFASDFASDF");
|
||||||
|
if((char *)i >= (char *)snapshots[snapid]->snap && (char *)i < (char *)snapshots[snapid]->snap + snapshots[snapid]->snap_size)
|
||||||
|
dbg_msg("ASDFASDFASdf", "ASDFASDFASDF");
|
||||||
|
i->type_and_id = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *snap_find_item(int snapid, int type, int id)
|
||||||
{
|
{
|
||||||
/* TODO: linear search. should be fixed. */
|
/* TODO: linear search. should be fixed. */
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < snapshots[snapid]->snap->num_items; i++)
|
for(i = 0; i < snapshots[snapid]->snap->num_items; i++)
|
||||||
{
|
{
|
||||||
SNAPSHOT_ITEM *itm = snapshot_get_item(snapshots[snapid]->snap, i);
|
SNAPSHOT_ITEM *itm = snapshot_get_item(snapshots[snapid]->alt_snap, i);
|
||||||
if(snapitem_type(itm) == type && snapitem_id(itm) == id)
|
if(snapitem_type(itm) == type && snapitem_id(itm) == id)
|
||||||
return (void *)snapitem_data(itm);
|
return (void *)snapitem_data(itm);
|
||||||
}
|
}
|
||||||
|
@ -762,6 +780,11 @@ static void client_process_packet(NETPACKET *packet)
|
||||||
int total_size = msg_unpack_int();
|
int total_size = msg_unpack_int();
|
||||||
int size = msg_unpack_int();
|
int size = msg_unpack_int();
|
||||||
const unsigned char *data = msg_unpack_raw(size);
|
const unsigned char *data = msg_unpack_raw(size);
|
||||||
|
|
||||||
|
/* check fior errors */
|
||||||
|
if(msg_unpack_error() || size <= 0 || total_size <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
io_write(mapdownload_file, data, size);
|
io_write(mapdownload_file, data, size);
|
||||||
|
|
||||||
mapdownload_totalsize = total_size;
|
mapdownload_totalsize = total_size;
|
||||||
|
@ -882,6 +905,7 @@ static void client_process_packet(NETPACKET *packet)
|
||||||
|
|
||||||
complete_size = (num_parts-1) * MAX_SNAPSHOT_PACKSIZE + part_size;
|
complete_size = (num_parts-1) * MAX_SNAPSHOT_PACKSIZE + part_size;
|
||||||
|
|
||||||
|
/* reset snapshoting */
|
||||||
snapshot_part = 0;
|
snapshot_part = 0;
|
||||||
|
|
||||||
/* find snapshot that we should use as delta */
|
/* find snapshot that we should use as delta */
|
||||||
|
@ -891,7 +915,7 @@ static void client_process_packet(NETPACKET *packet)
|
||||||
/* find delta */
|
/* find delta */
|
||||||
if(delta_tick >= 0)
|
if(delta_tick >= 0)
|
||||||
{
|
{
|
||||||
int deltashot_size = snapstorage_get(&snapshot_storage, delta_tick, 0, &deltashot);
|
int deltashot_size = snapstorage_get(&snapshot_storage, delta_tick, 0, &deltashot, 0);
|
||||||
|
|
||||||
if(deltashot_size < 0)
|
if(deltashot_size < 0)
|
||||||
{
|
{
|
||||||
|
@ -913,16 +937,27 @@ static void client_process_packet(NETPACKET *packet)
|
||||||
|
|
||||||
if(complete_size)
|
if(complete_size)
|
||||||
{
|
{
|
||||||
|
int intsize;
|
||||||
int compsize = zerobit_decompress(snapshot_incomming_data, complete_size, tmpbuffer);
|
int compsize = zerobit_decompress(snapshot_incomming_data, complete_size, tmpbuffer);
|
||||||
int intsize = intpack_decompress(tmpbuffer, compsize, tmpbuffer2);
|
|
||||||
|
if(compsize < 0) /* failure during decompression, bail */
|
||||||
|
return;
|
||||||
|
|
||||||
|
intsize = intpack_decompress(tmpbuffer, compsize, tmpbuffer2);
|
||||||
|
|
||||||
|
if(intsize < 0) /* failure during decompression, bail */
|
||||||
|
return;
|
||||||
|
|
||||||
deltadata = tmpbuffer2;
|
deltadata = tmpbuffer2;
|
||||||
deltasize = intsize;
|
deltasize = intsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*dbg_msg("UNPACK", "%d unpacked with %d", game_tick, delta_tick); */
|
/* unpack delta */
|
||||||
|
|
||||||
purgetick = delta_tick;
|
purgetick = delta_tick;
|
||||||
snapsize = snapshot_unpack_delta(deltashot, (SNAPSHOT*)tmpbuffer3, deltadata, deltasize);
|
snapsize = snapshot_unpack_delta(deltashot, (SNAPSHOT*)tmpbuffer3, deltadata, deltasize);
|
||||||
|
if(snapsize < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
if(msg != NETMSG_SNAPEMPTY && snapshot_crc((SNAPSHOT*)tmpbuffer3) != crc)
|
if(msg != NETMSG_SNAPEMPTY && snapshot_crc((SNAPSHOT*)tmpbuffer3) != crc)
|
||||||
{
|
{
|
||||||
if(config.debug)
|
if(config.debug)
|
||||||
|
@ -950,10 +985,9 @@ static void client_process_packet(NETPACKET *packet)
|
||||||
if(snapshots[SNAP_CURRENT] && snapshots[SNAP_CURRENT]->tick < purgetick)
|
if(snapshots[SNAP_CURRENT] && snapshots[SNAP_CURRENT]->tick < purgetick)
|
||||||
purgetick = snapshots[SNAP_PREV]->tick;
|
purgetick = snapshots[SNAP_PREV]->tick;
|
||||||
snapstorage_purge_until(&snapshot_storage, purgetick);
|
snapstorage_purge_until(&snapshot_storage, purgetick);
|
||||||
/*client_snapshot_purge_until(game_tick-50); */
|
|
||||||
|
|
||||||
/* add new */
|
/* add new */
|
||||||
snapstorage_add(&snapshot_storage, game_tick, time_get(), snapsize, (SNAPSHOT*)tmpbuffer3);
|
snapstorage_add(&snapshot_storage, game_tick, time_get(), snapsize, (SNAPSHOT*)tmpbuffer3, 1);
|
||||||
|
|
||||||
/* apply snapshot, cycle pointers */
|
/* apply snapshot, cycle pointers */
|
||||||
recived_snapshots++;
|
recived_snapshots++;
|
||||||
|
|
|
@ -126,8 +126,7 @@ long zerobit_decompress(const void *src_, int size, void *dst_)
|
||||||
unsigned char *dst = (unsigned char *)dst_;
|
unsigned char *dst = (unsigned char *)dst_;
|
||||||
unsigned char *end = src + size;
|
unsigned char *end = src + size;
|
||||||
|
|
||||||
|
while(src < end)
|
||||||
while(src != end)
|
|
||||||
{
|
{
|
||||||
unsigned char bit = 0x80;
|
unsigned char bit = 0x80;
|
||||||
unsigned char mask = *src++;
|
unsigned char mask = *src++;
|
||||||
|
@ -140,6 +139,9 @@ long zerobit_decompress(const void *src_, int size, void *dst_)
|
||||||
else
|
else
|
||||||
*dst++ = 0;
|
*dst++ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(src > end)
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (long)(dst-(unsigned char *)dst_);
|
return (long)(dst-(unsigned char *)dst_);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <engine/e_system.h>
|
#include <engine/e_system.h>
|
||||||
#include <engine/e_server_interface.h>
|
#include <engine/e_server_interface.h>
|
||||||
|
@ -25,6 +26,15 @@ const char *engine_savepath(const char *filename, char *buffer, int max)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int engine_stress(float probability)
|
||||||
|
{
|
||||||
|
if(!config.dbg_stress)
|
||||||
|
return 0;
|
||||||
|
if(rand()/(float)RAND_MAX < probability)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void engine_init(const char *appname)
|
void engine_init(const char *appname)
|
||||||
{
|
{
|
||||||
dbg_msg("engine", "running on %s-%s-%s", CONF_FAMILY_STRING, CONF_PLATFORM_STRING, CONF_ARCH_STRING);
|
dbg_msg("engine", "running on %s-%s-%s", CONF_FAMILY_STRING, CONF_PLATFORM_STRING, CONF_ARCH_STRING);
|
||||||
|
|
|
@ -4,6 +4,7 @@ const char *engine_savepath(const char *filename, char *buffer, int max);
|
||||||
void engine_init(const char *appname);
|
void engine_init(const char *appname);
|
||||||
void engine_parse_arguments(int argc, char **argv);
|
void engine_parse_arguments(int argc, char **argv);
|
||||||
void engine_writeconfig();
|
void engine_writeconfig();
|
||||||
|
int engine_stress(float probability);
|
||||||
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
|
|
@ -34,6 +34,7 @@ typedef struct
|
||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
int id;
|
int id;
|
||||||
|
int datasize;
|
||||||
} SNAP_ITEM;
|
} SNAP_ITEM;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -234,7 +235,7 @@ int snap_num_items(int snapid);
|
||||||
Returns:
|
Returns:
|
||||||
Returns a pointer to the item if it exists, otherwise NULL.
|
Returns a pointer to the item if it exists, otherwise NULL.
|
||||||
*/
|
*/
|
||||||
const void *snap_get_item(int snapid, int index, SNAP_ITEM *item);
|
void *snap_get_item(int snapid, int index, SNAP_ITEM *item);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Function: snap_find_item
|
Function: snap_find_item
|
||||||
|
@ -250,7 +251,19 @@ const void *snap_get_item(int snapid, int index, SNAP_ITEM *item);
|
||||||
Returns:
|
Returns:
|
||||||
Returns a pointer to the item if it exists, otherwise NULL.
|
Returns a pointer to the item if it exists, otherwise NULL.
|
||||||
*/
|
*/
|
||||||
const void *snap_find_item(int snapid, int type, int id);
|
void *snap_find_item(int snapid, int type, int id);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: snap_invalidate_item
|
||||||
|
Marks an item as invalid byt setting type and id to 0xffffffff.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
snapid - Snapshot ID to the data to fetch.
|
||||||
|
* SNAP_PREV for previous snapshot.
|
||||||
|
* SNAP_CUR for current snapshot.
|
||||||
|
index - Index of the item.
|
||||||
|
*/
|
||||||
|
void snap_invalidate_item(int snapid, int index);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Function: snap_input
|
Function: snap_input
|
||||||
|
|
|
@ -54,7 +54,6 @@ typedef struct
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
} NETPACKETDATA;
|
} NETPACKETDATA;
|
||||||
|
|
||||||
|
|
||||||
static void send_packet(NETSOCKET socket, NETADDR4 *addr, NETPACKETDATA *packet)
|
static void send_packet(NETSOCKET socket, NETADDR4 *addr, NETPACKETDATA *packet)
|
||||||
{
|
{
|
||||||
unsigned char buffer[NETWORK_MAX_PACKET_SIZE];
|
unsigned char buffer[NETWORK_MAX_PACKET_SIZE];
|
||||||
|
@ -356,7 +355,18 @@ static int conn_feed(NETCONNECTION *conn, NETPACKETDATA *p, NETADDR4 *addr)
|
||||||
conn->remote_closed = 1;
|
conn->remote_closed = 1;
|
||||||
|
|
||||||
if(p->data_size)
|
if(p->data_size)
|
||||||
conn_set_error(conn, (char *)p->data);
|
{
|
||||||
|
/* make sure to sanitize the error string form the other party*/
|
||||||
|
char str[128];
|
||||||
|
if(p->data_size < 128)
|
||||||
|
str_copy(str, (char *)p->data, p->data_size);
|
||||||
|
else
|
||||||
|
str_copy(str, (char *)p->data, 128);
|
||||||
|
str_sanitize_strong(str);
|
||||||
|
|
||||||
|
/* set the error string */
|
||||||
|
conn_set_error(conn, str);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
conn_set_error(conn, "no reason given");
|
conn_set_error(conn, "no reason given");
|
||||||
if(config.debug)
|
if(config.debug)
|
||||||
|
@ -739,7 +749,7 @@ int netserver_recv(NETSERVER *s, NETPACKET *packet)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* errornous packet, drop it */
|
/* errornous packet, drop it */
|
||||||
dbg_msg("server", "crazy packet");
|
/* dbg_msg("server", "crazy packet"); */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read header */
|
/* read header */
|
||||||
|
@ -751,7 +761,11 @@ int netserver_recv(NETSERVER *s, NETPACKET *packet)
|
||||||
|
|
||||||
int netserver_send(NETSERVER *s, NETPACKET *packet)
|
int netserver_send(NETSERVER *s, NETPACKET *packet)
|
||||||
{
|
{
|
||||||
dbg_assert(packet->data_size < NETWORK_MAX_PAYLOAD, "packet payload too big");
|
if(packet->data_size >= NETWORK_MAX_PAYLOAD)
|
||||||
|
{
|
||||||
|
dbg_msg("netserver", "packet payload too big. %d. dropping packet", packet->data_size);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if(packet->flags&PACKETFLAG_CONNLESS)
|
if(packet->flags&PACKETFLAG_CONNLESS)
|
||||||
{
|
{
|
||||||
|
@ -898,7 +912,11 @@ int netclient_recv(NETCLIENT *c, NETPACKET *packet)
|
||||||
|
|
||||||
int netclient_send(NETCLIENT *c, NETPACKET *packet)
|
int netclient_send(NETCLIENT *c, NETPACKET *packet)
|
||||||
{
|
{
|
||||||
dbg_assert(packet->data_size < NETWORK_MAX_PAYLOAD, "packet payload too big");
|
if(packet->data_size >= NETWORK_MAX_PAYLOAD)
|
||||||
|
{
|
||||||
|
dbg_msg("netclient", "packet payload too big. %d. dropping packet", packet->data_size);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if(packet->flags&PACKETFLAG_CONNLESS)
|
if(packet->flags&PACKETFLAG_CONNLESS)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,12 +1,39 @@
|
||||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "e_system.h"
|
#include "e_system.h"
|
||||||
#include "e_packer.h"
|
#include "e_packer.h"
|
||||||
#include "e_compression.h"
|
#include "e_compression.h"
|
||||||
|
#include "e_engine.h"
|
||||||
|
|
||||||
/* useful for debugging */
|
/* useful for debugging */
|
||||||
#define packing_error(p) p->error = 1
|
#if 0
|
||||||
/* #define packing_error(p) p->error = 1; dbg_break() */
|
#define packing_error(p) p->error = 1; dbg_break()
|
||||||
|
#else
|
||||||
|
#define packing_error(p) p->error = 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int stress_get_int()
|
||||||
|
{
|
||||||
|
static const int nasty[] = {-1, 0, 1, 66000, -66000, (-1<<31), 0x7fffffff};
|
||||||
|
if(rand()&1)
|
||||||
|
return rand();
|
||||||
|
return nasty[rand()%6];
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *stress_get_string(int *size)
|
||||||
|
{
|
||||||
|
static char noise[1024];
|
||||||
|
int i;
|
||||||
|
int s;
|
||||||
|
s = (rand()%1024)-1;
|
||||||
|
for(i = 0; i < s; i++)
|
||||||
|
noise[i] = (rand()%254)+1;
|
||||||
|
noise[s] = 0;
|
||||||
|
if(size)
|
||||||
|
*size = s;
|
||||||
|
return noise;
|
||||||
|
}
|
||||||
|
|
||||||
void packer_reset(PACKER *p)
|
void packer_reset(PACKER *p)
|
||||||
{
|
{
|
||||||
|
@ -20,6 +47,9 @@ void packer_add_int(PACKER *p, int i)
|
||||||
if(p->error)
|
if(p->error)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/*if(engine_stress(0.05f))
|
||||||
|
i = stress_get_int();*/
|
||||||
|
|
||||||
/* make sure that we have space enough */
|
/* make sure that we have space enough */
|
||||||
if(p->end - p->current < 6)
|
if(p->end - p->current < 6)
|
||||||
{
|
{
|
||||||
|
@ -35,6 +65,15 @@ void packer_add_string(PACKER *p, const char *str, int limit)
|
||||||
if(p->error)
|
if(p->error)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* STRESS: do this better */
|
||||||
|
/*
|
||||||
|
if(engine_stress(0.1f))
|
||||||
|
{
|
||||||
|
str = stress_get_string(0);
|
||||||
|
limit = 0;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/* */
|
||||||
if(limit > 0)
|
if(limit > 0)
|
||||||
{
|
{
|
||||||
while(*str && limit != 0)
|
while(*str && limit != 0)
|
||||||
|
@ -105,8 +144,14 @@ void unpacker_reset(UNPACKER *p, const unsigned char *data, int size)
|
||||||
int unpacker_get_int(UNPACKER *p)
|
int unpacker_get_int(UNPACKER *p)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
if(p->error || p->current >= p->end)
|
if(p->error)
|
||||||
return 0;
|
return 0;
|
||||||
|
if(p->current >= p->end)
|
||||||
|
{
|
||||||
|
packing_error(p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
p->current = vint_unpack(p->current, &i);
|
p->current = vint_unpack(p->current, &i);
|
||||||
if(p->current > p->end)
|
if(p->current > p->end)
|
||||||
{
|
{
|
||||||
|
@ -118,11 +163,11 @@ int unpacker_get_int(UNPACKER *p)
|
||||||
|
|
||||||
const char *unpacker_get_string(UNPACKER *p)
|
const char *unpacker_get_string(UNPACKER *p)
|
||||||
{
|
{
|
||||||
const char *ptr;
|
char *ptr;
|
||||||
if(p->error || p->current >= p->end)
|
if(p->error || p->current >= p->end)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
ptr = (const char *)p->current;
|
ptr = (char *)p->current;
|
||||||
while(*p->current) /* skip the string */
|
while(*p->current) /* skip the string */
|
||||||
{
|
{
|
||||||
p->current++;
|
p->current++;
|
||||||
|
@ -133,17 +178,26 @@ const char *unpacker_get_string(UNPACKER *p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p->current++;
|
p->current++;
|
||||||
|
|
||||||
|
/* sanitize all strings */
|
||||||
|
str_sanitize(ptr);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned char *unpacker_get_raw(UNPACKER *p, int size)
|
const unsigned char *unpacker_get_raw(UNPACKER *p, int size)
|
||||||
{
|
{
|
||||||
const unsigned char *ptr = p->current;
|
const unsigned char *ptr = p->current;
|
||||||
p->current += size;
|
if(p->error)
|
||||||
if(p->current > p->end)
|
return 0;
|
||||||
|
|
||||||
|
/* check for nasty sizes */
|
||||||
|
if(size < 0 || p->current+size > p->end)
|
||||||
{
|
{
|
||||||
packing_error(p);
|
packing_error(p);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* "unpack" the data */
|
||||||
|
p->current += size;
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "e_snapshot.h"
|
#include "e_snapshot.h"
|
||||||
|
#include "e_engine.h"
|
||||||
#include "e_compression.h"
|
#include "e_compression.h"
|
||||||
#include "e_common_interface.h"
|
#include "e_common_interface.h"
|
||||||
|
|
||||||
|
@ -317,6 +318,8 @@ int snapshot_unpack_delta(SNAPSHOT *from, SNAPSHOT *to, void *srcdata, int data_
|
||||||
SNAPBUILD builder;
|
SNAPBUILD builder;
|
||||||
SNAPSHOT_DELTA *delta = (SNAPSHOT_DELTA *)srcdata;
|
SNAPSHOT_DELTA *delta = (SNAPSHOT_DELTA *)srcdata;
|
||||||
int *data = (int *)delta->data;
|
int *data = (int *)delta->data;
|
||||||
|
int *end = (int *)(((char *)srcdata + data_size));
|
||||||
|
|
||||||
SNAPSHOT_ITEM *fromitem;
|
SNAPSHOT_ITEM *fromitem;
|
||||||
int i, d, keep, itemsize;
|
int i, d, keep, itemsize;
|
||||||
int *deleted;
|
int *deleted;
|
||||||
|
@ -329,6 +332,8 @@ int snapshot_unpack_delta(SNAPSHOT *from, SNAPSHOT *to, void *srcdata, int data_
|
||||||
/* unpack deleted stuff */
|
/* unpack deleted stuff */
|
||||||
deleted = data;
|
deleted = data;
|
||||||
data += delta->num_deleted_items;
|
data += delta->num_deleted_items;
|
||||||
|
if(data > end)
|
||||||
|
return -1;
|
||||||
|
|
||||||
/* copy all non deleted stuff */
|
/* copy all non deleted stuff */
|
||||||
for(i = 0; i < from->num_items; i++)
|
for(i = 0; i < from->num_items; i++)
|
||||||
|
@ -358,11 +363,17 @@ int snapshot_unpack_delta(SNAPSHOT *from, SNAPSHOT *to, void *srcdata, int data_
|
||||||
/* unpack updated stuff */
|
/* unpack updated stuff */
|
||||||
for(i = 0; i < delta->num_update_items; i++)
|
for(i = 0; i < delta->num_update_items; i++)
|
||||||
{
|
{
|
||||||
|
if(data+3 > end)
|
||||||
|
return -1;
|
||||||
|
|
||||||
itemsize = *data++;
|
itemsize = *data++;
|
||||||
type = *data++;
|
type = *data++;
|
||||||
id = *data++;
|
id = *data++;
|
||||||
snapshot_current = type;
|
snapshot_current = type;
|
||||||
|
|
||||||
|
if(data+itemsize/4 > end)
|
||||||
|
return -1;
|
||||||
|
|
||||||
key = (type<<16)|id;
|
key = (type<<16)|id;
|
||||||
|
|
||||||
/* create the item if needed */
|
/* create the item if needed */
|
||||||
|
@ -442,10 +453,16 @@ void snapstorage_purge_until(SNAPSTORAGE *ss, int tick)
|
||||||
ss->last = 0;
|
ss->last = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void snapstorage_add(SNAPSTORAGE *ss, int tick, int64 tagtime, int data_size, void *data)
|
void snapstorage_add(SNAPSTORAGE *ss, int tick, int64 tagtime, int data_size, void *data, int create_alt)
|
||||||
{
|
{
|
||||||
/* allocate memory for holder + snapshot_data */
|
/* allocate memory for holder + snapshot_data */
|
||||||
SNAPSTORAGE_HOLDER *h = (SNAPSTORAGE_HOLDER *)mem_alloc(sizeof(SNAPSTORAGE_HOLDER)+data_size, 1);
|
SNAPSTORAGE_HOLDER *h;
|
||||||
|
int total_size = sizeof(SNAPSTORAGE_HOLDER)+data_size;
|
||||||
|
|
||||||
|
if(create_alt)
|
||||||
|
total_size += data_size;
|
||||||
|
|
||||||
|
h = (SNAPSTORAGE_HOLDER *)mem_alloc(total_size, 1);
|
||||||
|
|
||||||
/* set data */
|
/* set data */
|
||||||
h->tick = tick;
|
h->tick = tick;
|
||||||
|
@ -454,6 +471,15 @@ void snapstorage_add(SNAPSTORAGE *ss, int tick, int64 tagtime, int data_size, vo
|
||||||
h->snap = (SNAPSHOT*)(h+1);
|
h->snap = (SNAPSHOT*)(h+1);
|
||||||
mem_copy(h->snap, data, data_size);
|
mem_copy(h->snap, data, data_size);
|
||||||
|
|
||||||
|
if(create_alt) /* create alternative if wanted */
|
||||||
|
{
|
||||||
|
h->alt_snap = (SNAPSHOT*)(((char *)h->snap) + data_size);
|
||||||
|
mem_copy(h->alt_snap, data, data_size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
h->alt_snap = 0;
|
||||||
|
|
||||||
|
|
||||||
/* link */
|
/* link */
|
||||||
h->next = 0;
|
h->next = 0;
|
||||||
h->prev = ss->last;
|
h->prev = ss->last;
|
||||||
|
@ -464,7 +490,7 @@ void snapstorage_add(SNAPSTORAGE *ss, int tick, int64 tagtime, int data_size, vo
|
||||||
ss->last = h;
|
ss->last = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snapstorage_get(SNAPSTORAGE *ss, int tick, int64 *tagtime, SNAPSHOT **data)
|
int snapstorage_get(SNAPSTORAGE *ss, int tick, int64 *tagtime, SNAPSHOT **data, SNAPSHOT **alt_data)
|
||||||
{
|
{
|
||||||
SNAPSTORAGE_HOLDER *h = ss->first;
|
SNAPSTORAGE_HOLDER *h = ss->first;
|
||||||
|
|
||||||
|
@ -476,6 +502,8 @@ int snapstorage_get(SNAPSTORAGE *ss, int tick, int64 *tagtime, SNAPSHOT **data)
|
||||||
*tagtime = h->tagtime;
|
*tagtime = h->tagtime;
|
||||||
if(data)
|
if(data)
|
||||||
*data = h->snap;
|
*data = h->snap;
|
||||||
|
if(alt_data)
|
||||||
|
*alt_data = h->alt_snap;
|
||||||
return h->snap_size;
|
return h->snap_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -524,6 +552,14 @@ int snapbuild_finish(SNAPBUILD *sb, void *snapdata)
|
||||||
void *snapbuild_new_item(SNAPBUILD *sb, int type, int id, int size)
|
void *snapbuild_new_item(SNAPBUILD *sb, int type, int id, int size)
|
||||||
{
|
{
|
||||||
SNAPSHOT_ITEM *obj = (SNAPSHOT_ITEM *)(sb->data+sb->data_size);
|
SNAPSHOT_ITEM *obj = (SNAPSHOT_ITEM *)(sb->data+sb->data_size);
|
||||||
|
|
||||||
|
if(engine_stress(0.01f))
|
||||||
|
{
|
||||||
|
size += ((rand()%5) - 2)*4;
|
||||||
|
if(size < 0)
|
||||||
|
size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
mem_zero(obj, sizeof(SNAPSHOT_ITEM) + size);
|
mem_zero(obj, sizeof(SNAPSHOT_ITEM) + size);
|
||||||
obj->type_and_id = (type<<16)|id;
|
obj->type_and_id = (type<<16)|id;
|
||||||
sb->offsets[sb->num_items] = sb->data_size;
|
sb->offsets[sb->num_items] = sb->data_size;
|
||||||
|
|
|
@ -52,6 +52,7 @@ typedef struct SNAPSTORAGE_HOLDER_t
|
||||||
|
|
||||||
int snap_size;
|
int snap_size;
|
||||||
SNAPSHOT *snap;
|
SNAPSHOT *snap;
|
||||||
|
SNAPSHOT *alt_snap;
|
||||||
} SNAPSTORAGE_HOLDER;
|
} SNAPSTORAGE_HOLDER;
|
||||||
|
|
||||||
typedef struct SNAPSTORAGE_t
|
typedef struct SNAPSTORAGE_t
|
||||||
|
@ -63,8 +64,8 @@ typedef struct SNAPSTORAGE_t
|
||||||
void snapstorage_init(SNAPSTORAGE *ss);
|
void snapstorage_init(SNAPSTORAGE *ss);
|
||||||
void snapstorage_purge_all(SNAPSTORAGE *ss);
|
void snapstorage_purge_all(SNAPSTORAGE *ss);
|
||||||
void snapstorage_purge_until(SNAPSTORAGE *ss, int tick);
|
void snapstorage_purge_until(SNAPSTORAGE *ss, int tick);
|
||||||
void snapstorage_add(SNAPSTORAGE *ss, int tick, int64 tagtime, int data_size, void *data);
|
void snapstorage_add(SNAPSTORAGE *ss, int tick, int64 tagtime, int data_size, void *data, int create_alt);
|
||||||
int snapstorage_get(SNAPSTORAGE *ss, int tick, int64 *tagtime, SNAPSHOT **data);
|
int snapstorage_get(SNAPSTORAGE *ss, int tick, int64 *tagtime, SNAPSHOT **data, SNAPSHOT **alt_data);
|
||||||
|
|
||||||
/* SNAPBUILD */
|
/* SNAPBUILD */
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,10 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
IOHANDLE io_stdin() { return (IOHANDLE)stdin; }
|
||||||
|
IOHANDLE io_stdout() { return (IOHANDLE)stdout; }
|
||||||
|
IOHANDLE io_stderr() { return (IOHANDLE)stderr; }
|
||||||
|
|
||||||
IOHANDLE logfile = 0;
|
IOHANDLE logfile = 0;
|
||||||
|
|
||||||
void dbg_assert_imp(const char *filename, int line, int test, const char *msg)
|
void dbg_assert_imp(const char *filename, int line, int test, const char *msg)
|
||||||
|
@ -462,19 +466,21 @@ int net_addr4_cmp(const NETADDR4 *a, const NETADDR4 *b)
|
||||||
|
|
||||||
int net_host_lookup(const char *hostname, unsigned short port, NETADDR4 *addr)
|
int net_host_lookup(const char *hostname, unsigned short port, NETADDR4 *addr)
|
||||||
{
|
{
|
||||||
struct hostent* ip = gethostbyname(hostname);
|
struct addrinfo hints;
|
||||||
|
struct addrinfo *result;
|
||||||
|
int e;
|
||||||
|
|
||||||
if(ip && ip->h_length > 0)
|
mem_zero(&hints, sizeof(hints));
|
||||||
{
|
hints.ai_family = AF_INET;
|
||||||
addr->ip[0] = ip->h_addr_list[0][0];
|
|
||||||
addr->ip[1] = ip->h_addr_list[0][1];
|
|
||||||
addr->ip[2] = ip->h_addr_list[0][2];
|
|
||||||
addr->ip[3] = ip->h_addr_list[0][3];
|
|
||||||
addr->port = port;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
e = getaddrinfo(hostname, NULL, &hints, &result);
|
||||||
|
if(e != 0 || !result)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
sockaddr_to_netaddr4(result->ai_addr, addr);
|
||||||
|
freeaddrinfo(result);
|
||||||
|
addr->port = port;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
NETSOCKET net_udp4_create(NETADDR4 bindaddr)
|
NETSOCKET net_udp4_create(NETADDR4 bindaddr)
|
||||||
|
@ -842,6 +848,31 @@ void str_format(char *buffer, int buffer_size, const char *format, ...)
|
||||||
buffer[buffer_size-1] = 0; /* assure null termination */
|
buffer[buffer_size-1] = 0; /* assure null termination */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* makes sure that the string only contains the characters between 32 and 127 */
|
||||||
|
void str_sanitize_strong(char *str)
|
||||||
|
{
|
||||||
|
while(*str)
|
||||||
|
{
|
||||||
|
*str &= 0x7f;
|
||||||
|
if(*str < 32)
|
||||||
|
*str = 32;
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* makes sure that the string only contains the characters between 32 and 255 + \r\n\t */
|
||||||
|
void str_sanitize(char *str)
|
||||||
|
{
|
||||||
|
while(*str)
|
||||||
|
{
|
||||||
|
if(*str < 32 && !(*str == '\r') && !(*str == '\n') && !(*str == '\t'))
|
||||||
|
*str = ' ';
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -526,6 +526,12 @@ void pstr_format(pstr *str, )*/
|
||||||
void str_append(char *dst, const char *src, int dst_size);
|
void str_append(char *dst, const char *src, int dst_size);
|
||||||
void str_copy(char *dst, const char *src, int dst_size);
|
void str_copy(char *dst, const char *src, int dst_size);
|
||||||
void str_format(char *buffer, int buffer_size, const char *format, ...);
|
void str_format(char *buffer, int buffer_size, const char *format, ...);
|
||||||
|
void str_sanitize_strong(char *str);
|
||||||
|
void str_sanitize(char *str);
|
||||||
|
|
||||||
|
IOHANDLE io_stdin();
|
||||||
|
IOHANDLE io_stdout();
|
||||||
|
IOHANDLE io_stderr();
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -371,14 +371,14 @@ static void server_do_snap()
|
||||||
snapstorage_purge_until(&clients[i].snapshots, current_tick-SERVER_TICK_SPEED);
|
snapstorage_purge_until(&clients[i].snapshots, current_tick-SERVER_TICK_SPEED);
|
||||||
|
|
||||||
/* save it the snapshot */
|
/* save it the snapshot */
|
||||||
snapstorage_add(&clients[i].snapshots, current_tick, time_get(), snapshot_size, data);
|
snapstorage_add(&clients[i].snapshots, current_tick, time_get(), snapshot_size, data, 0);
|
||||||
|
|
||||||
/* find snapshot that we can preform delta against */
|
/* find snapshot that we can preform delta against */
|
||||||
emptysnap.data_size = 0;
|
emptysnap.data_size = 0;
|
||||||
emptysnap.num_items = 0;
|
emptysnap.num_items = 0;
|
||||||
|
|
||||||
{
|
{
|
||||||
deltashot_size = snapstorage_get(&clients[i].snapshots, clients[i].last_acked_snapshot, 0, &deltashot);
|
deltashot_size = snapstorage_get(&clients[i].snapshots, clients[i].last_acked_snapshot, 0, &deltashot, 0);
|
||||||
if(deltashot_size >= 0)
|
if(deltashot_size >= 0)
|
||||||
delta_tick = clients[i].last_acked_snapshot;
|
delta_tick = clients[i].last_acked_snapshot;
|
||||||
else
|
else
|
||||||
|
@ -625,15 +625,19 @@ static void server_process_client_packet(NETPACKET *packet)
|
||||||
int64 tagtime;
|
int64 tagtime;
|
||||||
|
|
||||||
clients[cid].last_acked_snapshot = msg_unpack_int();
|
clients[cid].last_acked_snapshot = msg_unpack_int();
|
||||||
|
tick = msg_unpack_int();
|
||||||
|
size = msg_unpack_int();
|
||||||
|
|
||||||
|
/* check for errors */
|
||||||
|
if(msg_unpack_error() || size/4 > MAX_INPUT_SIZE)
|
||||||
|
return;
|
||||||
|
|
||||||
if(clients[cid].last_acked_snapshot > 0)
|
if(clients[cid].last_acked_snapshot > 0)
|
||||||
clients[cid].snap_rate = SRVCLIENT_SNAPRATE_FULL;
|
clients[cid].snap_rate = SRVCLIENT_SNAPRATE_FULL;
|
||||||
|
|
||||||
if(snapstorage_get(&clients[cid].snapshots, clients[cid].last_acked_snapshot, &tagtime, 0) >= 0)
|
if(snapstorage_get(&clients[cid].snapshots, clients[cid].last_acked_snapshot, &tagtime, 0, 0) >= 0)
|
||||||
clients[cid].latency = (int)(((time_get()-tagtime)*1000)/time_freq());
|
clients[cid].latency = (int)(((time_get()-tagtime)*1000)/time_freq());
|
||||||
|
|
||||||
tick = msg_unpack_int();
|
|
||||||
size = msg_unpack_int();
|
|
||||||
|
|
||||||
input = &clients[cid].inputs[clients[cid].current_input];
|
input = &clients[cid].inputs[clients[cid].current_input];
|
||||||
input->timeleft = server_tick_start_time(tick)-time_get();
|
input->timeleft = server_tick_start_time(tick)-time_get();
|
||||||
input->pred_tick = tick;
|
input->pred_tick = tick;
|
||||||
|
|
|
@ -27,7 +27,7 @@ extern "C" {
|
||||||
struct data_container *data = 0;
|
struct data_container *data = 0;
|
||||||
int64 debug_firedelay = 0;
|
int64 debug_firedelay = 0;
|
||||||
|
|
||||||
player_input input_data = {0};
|
NETOBJ_PLAYER_INPUT input_data = {0};
|
||||||
int input_target_lock = 0;
|
int input_target_lock = 0;
|
||||||
|
|
||||||
int chat_mode = CHATMODE_NONE;
|
int chat_mode = CHATMODE_NONE;
|
||||||
|
@ -40,11 +40,16 @@ tuning_params tuning;
|
||||||
vec2 mouse_pos;
|
vec2 mouse_pos;
|
||||||
vec2 local_character_pos;
|
vec2 local_character_pos;
|
||||||
vec2 local_target_pos;
|
vec2 local_target_pos;
|
||||||
const obj_player_character *local_character = 0;
|
|
||||||
const obj_player_character *local_prev_character = 0;
|
/*
|
||||||
const obj_player_info *local_info = 0;
|
const NETOBJ_PLAYER_CHARACTER *local_character = 0;
|
||||||
const obj_flag *flags[2] = {0,0};
|
const NETOBJ_PLAYER_CHARACTER *local_prev_character = 0;
|
||||||
const obj_game *gameobj = 0;
|
const NETOBJ_PLAYER_INFO *local_info = 0;
|
||||||
|
const NETOBJ_FLAG *flags[2] = {0,0};
|
||||||
|
const NETOBJ_GAME *gameobj = 0;
|
||||||
|
*/
|
||||||
|
|
||||||
|
snapstate netobjects;
|
||||||
|
|
||||||
int picked_up_weapon = -1;
|
int picked_up_weapon = -1;
|
||||||
|
|
||||||
|
@ -54,7 +59,7 @@ void client_data::update_render_info()
|
||||||
render_info = skin_info;
|
render_info = skin_info;
|
||||||
|
|
||||||
// force team colors
|
// force team colors
|
||||||
if(gameobj && gameobj->gametype != GAMETYPE_DM)
|
if(netobjects.gameobj && netobjects.gameobj->gametype != GAMETYPE_DM)
|
||||||
{
|
{
|
||||||
const int team_colors[2] = {65387, 10223467};
|
const int team_colors[2] = {65387, 10223467};
|
||||||
if(team >= 0 || team <= 1)
|
if(team >= 0 || team <= 1)
|
||||||
|
@ -232,7 +237,7 @@ void chat_add_line(int client_id, int team, const char *line)
|
||||||
if(client_datas[client_id].team == -1)
|
if(client_datas[client_id].team == -1)
|
||||||
chat_lines[chat_current_line].name_color = -1;
|
chat_lines[chat_current_line].name_color = -1;
|
||||||
|
|
||||||
if(gameobj && gameobj->gametype != GAMETYPE_DM)
|
if(netobjects.gameobj && netobjects.gameobj->gametype != GAMETYPE_DM)
|
||||||
{
|
{
|
||||||
if(client_datas[client_id].team == 0)
|
if(client_datas[client_id].team == 0)
|
||||||
chat_lines[chat_current_line].name_color = 0;
|
chat_lines[chat_current_line].name_color = 0;
|
||||||
|
@ -261,41 +266,40 @@ void process_events(int snaptype)
|
||||||
SNAP_ITEM item;
|
SNAP_ITEM item;
|
||||||
const void *data = snap_get_item(snaptype, index, &item);
|
const void *data = snap_get_item(snaptype, index, &item);
|
||||||
|
|
||||||
if(item.type == EVENT_DAMAGEINDICATION)
|
if(item.type == NETEVENTTYPE_DAMAGEIND)
|
||||||
{
|
{
|
||||||
ev_damageind *ev = (ev_damageind *)data;
|
NETEVENT_DAMAGEIND *ev = (NETEVENT_DAMAGEIND *)data;
|
||||||
effect_damage_indicator(vec2(ev->x, ev->y), get_direction(ev->angle));
|
effect_damage_indicator(vec2(ev->x, ev->y), get_direction(ev->angle));
|
||||||
}
|
}
|
||||||
else if(item.type == EVENT_AIR_JUMP)
|
else if(item.type == NETEVENTTYPE_AIR_JUMP)
|
||||||
{
|
{
|
||||||
ev_common *ev = (ev_common *)data;
|
NETEVENT_COMMON *ev = (NETEVENT_COMMON *)data;
|
||||||
effect_air_jump(vec2(ev->x, ev->y));
|
effect_air_jump(vec2(ev->x, ev->y));
|
||||||
}
|
}
|
||||||
else if(item.type == EVENT_EXPLOSION)
|
else if(item.type == NETEVENTTYPE_EXPLOSION)
|
||||||
{
|
{
|
||||||
ev_explosion *ev = (ev_explosion *)data;
|
NETEVENT_EXPLOSION *ev = (NETEVENT_EXPLOSION *)data;
|
||||||
effect_explosion(vec2(ev->x, ev->y));
|
effect_explosion(vec2(ev->x, ev->y));
|
||||||
}
|
}
|
||||||
else if(item.type == EVENT_SMOKE)
|
/*else if(item.type == EVENT_SMOKE)
|
||||||
{
|
{
|
||||||
ev_explosion *ev = (ev_explosion *)data;
|
EV_EXPLOSION *ev = (EV_EXPLOSION *)data;
|
||||||
vec2 p(ev->x, ev->y);
|
vec2 p(ev->x, ev->y);
|
||||||
}
|
}*/
|
||||||
else if(item.type == EVENT_PLAYERSPAWN)
|
else if(item.type == NETEVENTTYPE_SPAWN)
|
||||||
{
|
{
|
||||||
ev_explosion *ev = (ev_explosion *)data;
|
NETEVENT_SPAWN *ev = (NETEVENT_SPAWN *)data;
|
||||||
effect_playerspawn(vec2(ev->x, ev->y));
|
effect_playerspawn(vec2(ev->x, ev->y));
|
||||||
}
|
}
|
||||||
else if(item.type == EVENT_DEATH)
|
else if(item.type == NETEVENTTYPE_DEATH)
|
||||||
{
|
{
|
||||||
ev_explosion *ev = (ev_explosion *)data;
|
NETEVENT_DEATH *ev = (NETEVENT_DEATH *)data;
|
||||||
effect_playerdeath(vec2(ev->x, ev->y));
|
effect_playerdeath(vec2(ev->x, ev->y));
|
||||||
}
|
}
|
||||||
else if(item.type == EVENT_SOUND_WORLD)
|
else if(item.type == NETEVENTTYPE_SOUND_WORLD)
|
||||||
{
|
{
|
||||||
ev_sound *ev = (ev_sound *)data;
|
NETEVENT_SOUND_WORLD *ev = (NETEVENT_SOUND_WORLD *)data;
|
||||||
if(ev->sound >= 0 && ev->sound < NUM_SOUNDS)
|
snd_play_random(CHN_WORLD, ev->soundid, 1.0f, vec2(ev->x, ev->y));
|
||||||
snd_play_random(CHN_WORLD, ev->sound, 1.0f, vec2(ev->x, ev->y));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -303,12 +307,7 @@ void process_events(int snaptype)
|
||||||
void clear_object_pointers()
|
void clear_object_pointers()
|
||||||
{
|
{
|
||||||
// clear out the invalid pointers
|
// clear out the invalid pointers
|
||||||
local_character = 0;
|
mem_zero(&netobjects, sizeof(netobjects));
|
||||||
local_prev_character = 0;
|
|
||||||
local_info = 0;
|
|
||||||
flags[0] = 0;
|
|
||||||
flags[1] = 0;
|
|
||||||
gameobj = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_info(bool start)
|
void send_info(bool start)
|
||||||
|
@ -526,16 +525,16 @@ void render_goals(float x, float y, float w)
|
||||||
|
|
||||||
// render goals
|
// render goals
|
||||||
//y = ystart+h-54;
|
//y = ystart+h-54;
|
||||||
if(gameobj && gameobj->time_limit)
|
if(netobjects.gameobj && netobjects.gameobj->time_limit)
|
||||||
{
|
{
|
||||||
char buf[64];
|
char buf[64];
|
||||||
str_format(buf, sizeof(buf), "Time Limit: %d min", gameobj->time_limit);
|
str_format(buf, sizeof(buf), "Time Limit: %d min", netobjects.gameobj->time_limit);
|
||||||
gfx_text(0, x+w/2, y, 24.0f, buf, -1);
|
gfx_text(0, x+w/2, y, 24.0f, buf, -1);
|
||||||
}
|
}
|
||||||
if(gameobj && gameobj->score_limit)
|
if(netobjects.gameobj && netobjects.gameobj->score_limit)
|
||||||
{
|
{
|
||||||
char buf[64];
|
char buf[64];
|
||||||
str_format(buf, sizeof(buf), "Score Limit: %d", gameobj->score_limit);
|
str_format(buf, sizeof(buf), "Score Limit: %d", netobjects.gameobj->score_limit);
|
||||||
gfx_text(0, x+40, y, 24.0f, buf, -1);
|
gfx_text(0, x+40, y, 24.0f, buf, -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -560,14 +559,14 @@ void render_spectators(float x, float y, float w)
|
||||||
SNAP_ITEM item;
|
SNAP_ITEM item;
|
||||||
const void *data = snap_get_item(SNAP_CURRENT, i, &item);
|
const void *data = snap_get_item(SNAP_CURRENT, i, &item);
|
||||||
|
|
||||||
if(item.type == OBJTYPE_PLAYER_INFO)
|
if(item.type == NETOBJTYPE_PLAYER_INFO)
|
||||||
{
|
{
|
||||||
const obj_player_info *info = (const obj_player_info *)data;
|
const NETOBJ_PLAYER_INFO *info = (const NETOBJ_PLAYER_INFO *)data;
|
||||||
if(info->team == -1)
|
if(info->team == -1)
|
||||||
{
|
{
|
||||||
if(count)
|
if(count)
|
||||||
strcat(buffer, ", ");
|
strcat(buffer, ", ");
|
||||||
strcat(buffer, client_datas[info->clientid].name);
|
strcat(buffer, client_datas[info->cid].name);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -595,7 +594,7 @@ void render_scoreboard(float x, float y, float w, int team, const char *title)
|
||||||
// render title
|
// render title
|
||||||
if(!title)
|
if(!title)
|
||||||
{
|
{
|
||||||
if(gameobj->game_over)
|
if(netobjects.gameobj->game_over)
|
||||||
title = "Game Over";
|
title = "Game Over";
|
||||||
else
|
else
|
||||||
title = "Score Board";
|
title = "Score Board";
|
||||||
|
@ -611,10 +610,11 @@ void render_scoreboard(float x, float y, float w, int team, const char *title)
|
||||||
{
|
{
|
||||||
gfx_text(0, x+10, y, 48, title, -1);
|
gfx_text(0, x+10, y, 48, title, -1);
|
||||||
|
|
||||||
if(gameobj)
|
if(netobjects.gameobj)
|
||||||
{
|
{
|
||||||
char buf[128];
|
char buf[128];
|
||||||
str_format(buf, sizeof(buf), "%d", gameobj->teamscore[team&1]);
|
int score = team ? netobjects.gameobj->teamscore_blue : netobjects.gameobj->teamscore_red;
|
||||||
|
str_format(buf, sizeof(buf), "%d", score);
|
||||||
tw = gfx_text_width(0, 48, buf, -1);
|
tw = gfx_text_width(0, 48, buf, -1);
|
||||||
gfx_text(0, x+w-tw-30, y, 48, buf, -1);
|
gfx_text(0, x+w-tw-30, y, 48, buf, -1);
|
||||||
}
|
}
|
||||||
|
@ -623,16 +623,16 @@ void render_scoreboard(float x, float y, float w, int team, const char *title)
|
||||||
y += 54.0f;
|
y += 54.0f;
|
||||||
|
|
||||||
// find players
|
// find players
|
||||||
const obj_player_info *players[MAX_CLIENTS] = {0};
|
const NETOBJ_PLAYER_INFO *players[MAX_CLIENTS] = {0};
|
||||||
int num_players = 0;
|
int num_players = 0;
|
||||||
for(int i = 0; i < snap_num_items(SNAP_CURRENT); i++)
|
for(int i = 0; i < snap_num_items(SNAP_CURRENT); i++)
|
||||||
{
|
{
|
||||||
SNAP_ITEM item;
|
SNAP_ITEM item;
|
||||||
const void *data = snap_get_item(SNAP_CURRENT, i, &item);
|
const void *data = snap_get_item(SNAP_CURRENT, i, &item);
|
||||||
|
|
||||||
if(item.type == OBJTYPE_PLAYER_INFO)
|
if(item.type == NETOBJTYPE_PLAYER_INFO)
|
||||||
{
|
{
|
||||||
players[num_players] = (const obj_player_info *)data;
|
players[num_players] = (const NETOBJ_PLAYER_INFO *)data;
|
||||||
num_players++;
|
num_players++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -644,7 +644,7 @@ void render_scoreboard(float x, float y, float w, int team, const char *title)
|
||||||
{
|
{
|
||||||
if(players[i]->score < players[i+1]->score)
|
if(players[i]->score < players[i+1]->score)
|
||||||
{
|
{
|
||||||
const obj_player_info *tmp = players[i];
|
const NETOBJ_PLAYER_INFO *tmp = players[i];
|
||||||
players[i] = players[i+1];
|
players[i] = players[i+1];
|
||||||
players[i+1] = tmp;
|
players[i+1] = tmp;
|
||||||
}
|
}
|
||||||
|
@ -660,7 +660,7 @@ void render_scoreboard(float x, float y, float w, int team, const char *title)
|
||||||
// render player scores
|
// render player scores
|
||||||
for(int i = 0; i < num_players; i++)
|
for(int i = 0; i < num_players; i++)
|
||||||
{
|
{
|
||||||
const obj_player_info *info = players[i];
|
const NETOBJ_PLAYER_INFO *info = players[i];
|
||||||
|
|
||||||
// make sure that we render the correct team
|
// make sure that we render the correct team
|
||||||
if(team == -1 || info->team != team)
|
if(team == -1 || info->team != team)
|
||||||
|
@ -683,18 +683,19 @@ void render_scoreboard(float x, float y, float w, int team, const char *title)
|
||||||
|
|
||||||
if(config.cl_show_player_ids)
|
if(config.cl_show_player_ids)
|
||||||
{
|
{
|
||||||
str_format(buf, sizeof(buf), "%d | %s", info->clientid, client_datas[info->clientid].name);
|
str_format(buf, sizeof(buf), "%d | %s", info->cid, client_datas[info->cid].name);
|
||||||
gfx_text(0, x+128, y, font_size, buf, -1);
|
gfx_text(0, x+128, y, font_size, buf, -1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
gfx_text(0, x+128, y, font_size, client_datas[info->clientid].name, -1);
|
gfx_text(0, x+128, y, font_size, client_datas[info->cid].name, -1);
|
||||||
|
|
||||||
str_format(buf, sizeof(buf), "%4d", info->latency);
|
str_format(buf, sizeof(buf), "%4d", info->latency);
|
||||||
float tw = gfx_text_width(0, font_size, buf, -1);
|
float tw = gfx_text_width(0, font_size, buf, -1);
|
||||||
gfx_text(0, x+w-tw-35, y, font_size, buf, -1);
|
gfx_text(0, x+w-tw-35, y, font_size, buf, -1);
|
||||||
|
|
||||||
// render avatar
|
// render avatar
|
||||||
if((flags[0] && flags[0]->carried_by == info->clientid) || (flags[1] && flags[1]->carried_by == info->clientid))
|
if((netobjects.flags[0] && netobjects.flags[0]->carried_by == info->cid) ||
|
||||||
|
(netobjects.flags[1] && netobjects.flags[1]->carried_by == info->cid))
|
||||||
{
|
{
|
||||||
gfx_blend_normal();
|
gfx_blend_normal();
|
||||||
gfx_texture_set(data->images[IMAGE_GAME].id);
|
gfx_texture_set(data->images[IMAGE_GAME].id);
|
||||||
|
@ -708,7 +709,7 @@ void render_scoreboard(float x, float y, float w, int team, const char *title)
|
||||||
gfx_quads_end();
|
gfx_quads_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
render_tee(&idlestate, &client_datas[info->clientid].render_info, EMOTE_NORMAL, vec2(1,0), vec2(x+90, y+28));
|
render_tee(&idlestate, &client_datas[info->cid].render_info, EMOTE_NORMAL, vec2(1,0), vec2(x+90, y+28));
|
||||||
|
|
||||||
|
|
||||||
y += 50.0f;
|
y += 50.0f;
|
||||||
|
@ -739,21 +740,21 @@ void render_game()
|
||||||
|
|
||||||
if(config.cl_predict)
|
if(config.cl_predict)
|
||||||
{
|
{
|
||||||
if(!local_character || (local_character->health < 0) || (gameobj && gameobj->game_over))
|
if(!netobjects.local_character || (netobjects.local_character->health < 0) || (netobjects.gameobj && netobjects.gameobj->game_over))
|
||||||
{
|
{
|
||||||
// don't use predicted
|
// don't use predicted
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
local_character_pos = mix(predicted_prev_player.pos, predicted_player.pos, client_predintratick());
|
local_character_pos = mix(predicted_prev_player.pos, predicted_player.pos, client_predintratick());
|
||||||
}
|
}
|
||||||
else if(local_character && local_prev_character)
|
else if(netobjects.local_character && netobjects.local_prev_character)
|
||||||
{
|
{
|
||||||
local_character_pos = mix(
|
local_character_pos = mix(
|
||||||
vec2(local_prev_character->x, local_prev_character->y),
|
vec2(netobjects.local_prev_character->x, netobjects.local_prev_character->y),
|
||||||
vec2(local_character->x, local_character->y), client_intratick());
|
vec2(netobjects.local_character->x, netobjects.local_character->y), client_intratick());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(local_info && local_info->team == -1)
|
if(netobjects.local_info && netobjects.local_info->team == -1)
|
||||||
spectate = true;
|
spectate = true;
|
||||||
|
|
||||||
animstate idlestate;
|
animstate idlestate;
|
||||||
|
@ -1089,7 +1090,7 @@ void render_game()
|
||||||
gfx_quads_end();
|
gfx_quads_end();
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
if(local_character && !spectate && !(gameobj && gameobj->game_over))
|
if(netobjects.local_character && !spectate && !(netobjects.gameobj && netobjects.gameobj->game_over))
|
||||||
{
|
{
|
||||||
gfx_texture_set(data->images[IMAGE_GAME].id);
|
gfx_texture_set(data->images[IMAGE_GAME].id);
|
||||||
gfx_quads_begin();
|
gfx_quads_begin();
|
||||||
|
@ -1097,7 +1098,7 @@ void render_game()
|
||||||
// render cursor
|
// render cursor
|
||||||
if (!menu_active && !emoticon_selector_active)
|
if (!menu_active && !emoticon_selector_active)
|
||||||
{
|
{
|
||||||
select_sprite(data->weapons[local_character->weapon%data->num_weapons].sprite_cursor);
|
select_sprite(data->weapons[netobjects.local_character->weapon%data->num_weapons].sprite_cursor);
|
||||||
float cursorsize = 64;
|
float cursorsize = 64;
|
||||||
draw_sprite(local_target_pos.x, local_target_pos.y, cursorsize);
|
draw_sprite(local_target_pos.x, local_target_pos.y, cursorsize);
|
||||||
}
|
}
|
||||||
|
@ -1113,10 +1114,10 @@ void render_game()
|
||||||
|
|
||||||
// if weaponstage is active, put a "glow" around the stage ammo
|
// if weaponstage is active, put a "glow" around the stage ammo
|
||||||
select_sprite(SPRITE_TEE_BODY);
|
select_sprite(SPRITE_TEE_BODY);
|
||||||
for (int i = 0; i < local_character->weaponstage; i++)
|
for (int i = 0; i < netobjects.local_character->weaponstage; i++)
|
||||||
gfx_quads_drawTL(x+local_character->ammocount * 12 -i*12, y+22, 11, 11);
|
gfx_quads_drawTL(x+netobjects.local_character->ammocount * 12 -i*12, y+22, 11, 11);
|
||||||
select_sprite(data->weapons[local_character->weapon%data->num_weapons].sprite_proj);
|
select_sprite(data->weapons[netobjects.local_character->weapon%data->num_weapons].sprite_proj);
|
||||||
for (int i = 0; i < min(local_character->ammocount, 10); i++)
|
for (int i = 0; i < min(netobjects.local_character->ammocount, 10); i++)
|
||||||
gfx_quads_drawTL(x+i*12,y+24,10,10);
|
gfx_quads_drawTL(x+i*12,y+24,10,10);
|
||||||
|
|
||||||
gfx_quads_end();
|
gfx_quads_end();
|
||||||
|
@ -1127,7 +1128,7 @@ void render_game()
|
||||||
|
|
||||||
// render health
|
// render health
|
||||||
select_sprite(SPRITE_HEALTH_FULL);
|
select_sprite(SPRITE_HEALTH_FULL);
|
||||||
for(; h < local_character->health; h++)
|
for(; h < netobjects.local_character->health; h++)
|
||||||
gfx_quads_drawTL(x+h*12,y,10,10);
|
gfx_quads_drawTL(x+h*12,y,10,10);
|
||||||
|
|
||||||
select_sprite(SPRITE_HEALTH_EMPTY);
|
select_sprite(SPRITE_HEALTH_EMPTY);
|
||||||
|
@ -1137,7 +1138,7 @@ void render_game()
|
||||||
// render armor meter
|
// render armor meter
|
||||||
h = 0;
|
h = 0;
|
||||||
select_sprite(SPRITE_ARMOR_FULL);
|
select_sprite(SPRITE_ARMOR_FULL);
|
||||||
for(; h < local_character->armor; h++)
|
for(; h < netobjects.local_character->armor; h++)
|
||||||
gfx_quads_drawTL(x+h*12,y+12,10,10);
|
gfx_quads_drawTL(x+h*12,y+12,10,10);
|
||||||
|
|
||||||
select_sprite(SPRITE_ARMOR_EMPTY);
|
select_sprite(SPRITE_ARMOR_EMPTY);
|
||||||
|
@ -1172,7 +1173,7 @@ void render_game()
|
||||||
// render victim tee
|
// render victim tee
|
||||||
x -= 24.0f;
|
x -= 24.0f;
|
||||||
|
|
||||||
if(gameobj && gameobj->gametype == GAMETYPE_CTF)
|
if(netobjects.gameobj && netobjects.gameobj->gametype == GAMETYPE_CTF)
|
||||||
{
|
{
|
||||||
if(killmsgs[r].mode_special&1)
|
if(killmsgs[r].mode_special&1)
|
||||||
{
|
{
|
||||||
|
@ -1206,7 +1207,7 @@ void render_game()
|
||||||
|
|
||||||
if(killmsgs[r].victim != killmsgs[r].killer)
|
if(killmsgs[r].victim != killmsgs[r].killer)
|
||||||
{
|
{
|
||||||
if(gameobj && gameobj->gametype == GAMETYPE_CTF)
|
if(netobjects.gameobj && netobjects.gameobj->gametype == GAMETYPE_CTF)
|
||||||
{
|
{
|
||||||
if(killmsgs[r].mode_special&2)
|
if(killmsgs[r].mode_special&2)
|
||||||
{
|
{
|
||||||
|
@ -1305,34 +1306,34 @@ void render_game()
|
||||||
}
|
}
|
||||||
|
|
||||||
// render goals
|
// render goals
|
||||||
if(gameobj)
|
if(netobjects.gameobj)
|
||||||
{
|
{
|
||||||
int gametype = gameobj->gametype;
|
int gametype = netobjects.gameobj->gametype;
|
||||||
|
|
||||||
float whole = 300*gfx_screenaspect();
|
float whole = 300*gfx_screenaspect();
|
||||||
float half = whole/2.0f;
|
float half = whole/2.0f;
|
||||||
|
|
||||||
gfx_mapscreen(0,0,300*gfx_screenaspect(),300);
|
gfx_mapscreen(0,0,300*gfx_screenaspect(),300);
|
||||||
if(!gameobj->sudden_death)
|
if(!netobjects.gameobj->sudden_death)
|
||||||
{
|
{
|
||||||
char buf[32];
|
char buf[32];
|
||||||
int time = 0;
|
int time = 0;
|
||||||
if(gameobj->time_limit)
|
if(netobjects.gameobj->time_limit)
|
||||||
{
|
{
|
||||||
time = gameobj->time_limit*60 - ((client_tick()-gameobj->round_start_tick)/client_tickspeed());
|
time = netobjects.gameobj->time_limit*60 - ((client_tick()-netobjects.gameobj->round_start_tick)/client_tickspeed());
|
||||||
|
|
||||||
if(gameobj->game_over)
|
if(netobjects.gameobj->game_over)
|
||||||
time = 0;
|
time = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
time = (client_tick()-gameobj->round_start_tick)/client_tickspeed();
|
time = (client_tick()-netobjects.gameobj->round_start_tick)/client_tickspeed();
|
||||||
|
|
||||||
str_format(buf, sizeof(buf), "%d:%02d", time /60, time %60);
|
str_format(buf, sizeof(buf), "%d:%02d", time /60, time %60);
|
||||||
float w = gfx_text_width(0, 16, buf, -1);
|
float w = gfx_text_width(0, 16, buf, -1);
|
||||||
gfx_text(0, half-w/2, 2, 16, buf, -1);
|
gfx_text(0, half-w/2, 2, 16, buf, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(gameobj->sudden_death)
|
if(netobjects.gameobj->sudden_death)
|
||||||
{
|
{
|
||||||
const char *text = "Sudden Death";
|
const char *text = "Sudden Death";
|
||||||
float w = gfx_text_width(0, 16, text, -1);
|
float w = gfx_text_width(0, 16, text, -1);
|
||||||
|
@ -1340,7 +1341,7 @@ void render_game()
|
||||||
}
|
}
|
||||||
|
|
||||||
// render small score hud
|
// render small score hud
|
||||||
if(!(gameobj && gameobj->game_over) && (gametype == GAMETYPE_TDM || gametype == GAMETYPE_CTF))
|
if(!(netobjects.gameobj && netobjects.gameobj->game_over) && (gametype == GAMETYPE_TDM || gametype == GAMETYPE_CTF))
|
||||||
{
|
{
|
||||||
for(int t = 0; t < 2; t++)
|
for(int t = 0; t < 2; t++)
|
||||||
{
|
{
|
||||||
|
@ -1355,15 +1356,15 @@ void render_game()
|
||||||
gfx_quads_end();
|
gfx_quads_end();
|
||||||
|
|
||||||
char buf[32];
|
char buf[32];
|
||||||
str_format(buf, sizeof(buf), "%d", gameobj->teamscore[t]);
|
str_format(buf, sizeof(buf), "%d", t?netobjects.gameobj->teamscore_blue:netobjects.gameobj->teamscore_red);
|
||||||
float w = gfx_text_width(0, 14, buf, -1);
|
float w = gfx_text_width(0, 14, buf, -1);
|
||||||
|
|
||||||
if(gametype == GAMETYPE_CTF)
|
if(gametype == GAMETYPE_CTF)
|
||||||
{
|
{
|
||||||
gfx_text(0, whole-20-w/2+5, 300-40-15+t*20+2, 14, buf, -1);
|
gfx_text(0, whole-20-w/2+5, 300-40-15+t*20+2, 14, buf, -1);
|
||||||
if(flags[t])
|
if(netobjects.flags[t])
|
||||||
{
|
{
|
||||||
if(flags[t]->carried_by == -2 || (flags[t]->carried_by == -1 && ((client_tick()/10)&1)))
|
if(netobjects.flags[t]->carried_by == -2 || (netobjects.flags[t]->carried_by == -1 && ((client_tick()/10)&1)))
|
||||||
{
|
{
|
||||||
gfx_blend_normal();
|
gfx_blend_normal();
|
||||||
gfx_texture_set(data->images[IMAGE_GAME].id);
|
gfx_texture_set(data->images[IMAGE_GAME].id);
|
||||||
|
@ -1376,9 +1377,9 @@ void render_game()
|
||||||
gfx_quads_drawTL(whole-40+5, 300-40-15+t*20+1, size/2, size);
|
gfx_quads_drawTL(whole-40+5, 300-40-15+t*20+1, size/2, size);
|
||||||
gfx_quads_end();
|
gfx_quads_end();
|
||||||
}
|
}
|
||||||
else if(flags[t]->carried_by >= 0)
|
else if(netobjects.flags[t]->carried_by >= 0)
|
||||||
{
|
{
|
||||||
int id = flags[t]->carried_by%MAX_CLIENTS;
|
int id = netobjects.flags[t]->carried_by%MAX_CLIENTS;
|
||||||
const char *name = client_datas[id].name;
|
const char *name = client_datas[id].name;
|
||||||
float w = gfx_text_width(0, 10, name, -1);
|
float w = gfx_text_width(0, 10, name, -1);
|
||||||
gfx_text(0, whole-40-5-w, 300-40-15+t*20+2, 10, name, -1);
|
gfx_text(0, whole-40-5-w, 300-40-15+t*20+2, 10, name, -1);
|
||||||
|
@ -1396,15 +1397,15 @@ void render_game()
|
||||||
}
|
}
|
||||||
|
|
||||||
// render warmup timer
|
// render warmup timer
|
||||||
if(gameobj->warmup)
|
if(netobjects.gameobj->warmup)
|
||||||
{
|
{
|
||||||
char buf[256];
|
char buf[256];
|
||||||
float w = gfx_text_width(0, 24, "Warmup", -1);
|
float w = gfx_text_width(0, 24, "Warmup", -1);
|
||||||
gfx_text(0, 150*gfx_screenaspect()+-w/2, 50, 24, "Warmup", -1);
|
gfx_text(0, 150*gfx_screenaspect()+-w/2, 50, 24, "Warmup", -1);
|
||||||
|
|
||||||
int seconds = gameobj->warmup/SERVER_TICK_SPEED;
|
int seconds = netobjects.gameobj->warmup/SERVER_TICK_SPEED;
|
||||||
if(seconds < 5)
|
if(seconds < 5)
|
||||||
str_format(buf, sizeof(buf), "%d.%d", seconds, (gameobj->warmup*10/SERVER_TICK_SPEED)%10);
|
str_format(buf, sizeof(buf), "%d.%d", seconds, (netobjects.gameobj->warmup*10/SERVER_TICK_SPEED)%10);
|
||||||
else
|
else
|
||||||
str_format(buf, sizeof(buf), "%d", seconds);
|
str_format(buf, sizeof(buf), "%d", seconds);
|
||||||
w = gfx_text_width(0, 24, buf, -1);
|
w = gfx_text_width(0, 24, buf, -1);
|
||||||
|
@ -1439,12 +1440,12 @@ void render_game()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(config.debug && local_character && local_prev_character)
|
if(config.debug && netobjects.local_character && netobjects.local_prev_character)
|
||||||
{
|
{
|
||||||
gfx_mapscreen(0, 0, 300*gfx_screenaspect(), 300);
|
gfx_mapscreen(0, 0, 300*gfx_screenaspect(), 300);
|
||||||
|
|
||||||
float speed = distance(vec2(local_prev_character->x, local_prev_character->y),
|
float speed = distance(vec2(netobjects.local_prev_character->x, netobjects.local_prev_character->y),
|
||||||
vec2(local_character->x, local_character->y));
|
vec2(netobjects.local_character->x, netobjects.local_character->y));
|
||||||
|
|
||||||
char buf[512];
|
char buf[512];
|
||||||
str_format(buf, sizeof(buf), "%.2f", speed/2);
|
str_format(buf, sizeof(buf), "%.2f", speed/2);
|
||||||
|
@ -1453,15 +1454,15 @@ void render_game()
|
||||||
|
|
||||||
// render score board
|
// render score board
|
||||||
if(inp_key_pressed(KEY_TAB) || // user requested
|
if(inp_key_pressed(KEY_TAB) || // user requested
|
||||||
(!spectate && (!local_character || local_character->health < 0)) || // not spectating and is dead
|
(!spectate && (!netobjects.local_character || netobjects.local_character->health < 0)) || // not spectating and is dead
|
||||||
(gameobj && gameobj->game_over) // game over
|
(netobjects.gameobj && netobjects.gameobj->game_over) // game over
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
gfx_mapscreen(0, 0, width, height);
|
gfx_mapscreen(0, 0, width, height);
|
||||||
|
|
||||||
float w = 650.0f;
|
float w = 650.0f;
|
||||||
|
|
||||||
if (gameobj && gameobj->gametype == GAMETYPE_DM)
|
if(netobjects.gameobj && netobjects.gameobj->gametype == GAMETYPE_DM)
|
||||||
{
|
{
|
||||||
render_scoreboard(width/2-w/2, 150.0f, w, 0, 0);
|
render_scoreboard(width/2-w/2, 150.0f, w, 0, 0);
|
||||||
//render_scoreboard(gameobj, 0, 0, -1, 0);
|
//render_scoreboard(gameobj, 0, 0, -1, 0);
|
||||||
|
@ -1469,12 +1470,12 @@ void render_game()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
if(gameobj && gameobj->game_over)
|
if(netobjects.gameobj && netobjects.gameobj->game_over)
|
||||||
{
|
{
|
||||||
const char *text = "DRAW!";
|
const char *text = "DRAW!";
|
||||||
if(gameobj->teamscore[0] > gameobj->teamscore[1])
|
if(netobjects.gameobj->teamscore_red > netobjects.gameobj->teamscore_blue)
|
||||||
text = "Red Team Wins!";
|
text = "Red Team Wins!";
|
||||||
else if(gameobj->teamscore[1] > gameobj->teamscore[0])
|
else if(netobjects.gameobj->teamscore_blue > netobjects.gameobj->teamscore_red)
|
||||||
text = "Blue Team Wins!";
|
text = "Blue Team Wins!";
|
||||||
|
|
||||||
float w = gfx_text_width(0, 92.0f, text, -1);
|
float w = gfx_text_width(0, 92.0f, text, -1);
|
||||||
|
|
|
@ -20,11 +20,29 @@ extern vec2 local_character_pos;
|
||||||
extern vec2 local_target_pos;
|
extern vec2 local_target_pos;
|
||||||
|
|
||||||
// snap pointers
|
// snap pointers
|
||||||
extern const obj_player_character *local_character;
|
struct snapstate
|
||||||
extern const obj_player_character *local_prev_character;
|
{
|
||||||
extern const obj_player_info *local_info;
|
const NETOBJ_PLAYER_CHARACTER *local_character;
|
||||||
extern const obj_flag *flags[2];
|
const NETOBJ_PLAYER_CHARACTER *local_prev_character;
|
||||||
extern const obj_game *gameobj;
|
const NETOBJ_PLAYER_INFO *local_info;
|
||||||
|
const NETOBJ_FLAG *flags[2];
|
||||||
|
const NETOBJ_GAME *gameobj;
|
||||||
|
|
||||||
|
const NETOBJ_PLAYER_INFO *player_infos[MAX_CLIENTS];
|
||||||
|
const NETOBJ_PLAYER_INFO *info_by_score[MAX_CLIENTS];
|
||||||
|
int num_players;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern snapstate netobjects;
|
||||||
|
|
||||||
|
/*
|
||||||
|
extern const NETOBJ_PLAYER_CHARACTER *local_character;
|
||||||
|
extern const NETOBJ_PLAYER_CHARACTER *local_prev_character;
|
||||||
|
extern const NETOBJ_PLAYER_INFO *local_info;
|
||||||
|
extern const NETOBJ_FLAG *flags[2];
|
||||||
|
extern const NETOBJ_GAME *gameobj;
|
||||||
|
* */
|
||||||
|
|
||||||
extern tuning_params tuning;
|
extern tuning_params tuning;
|
||||||
|
|
||||||
// predicted players
|
// predicted players
|
||||||
|
@ -33,7 +51,7 @@ extern player_core predicted_player;
|
||||||
|
|
||||||
// input
|
// input
|
||||||
extern int picked_up_weapon;
|
extern int picked_up_weapon;
|
||||||
extern player_input input_data;
|
extern NETOBJ_PLAYER_INPUT input_data;
|
||||||
extern int input_target_lock;
|
extern int input_target_lock;
|
||||||
|
|
||||||
// debug
|
// debug
|
||||||
|
@ -45,7 +63,7 @@ enum
|
||||||
MAX_EXTRA_PROJECTILES=32,
|
MAX_EXTRA_PROJECTILES=32,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern obj_projectile extraproj_projectiles[MAX_EXTRA_PROJECTILES];
|
extern NETOBJ_PROJECTILE extraproj_projectiles[MAX_EXTRA_PROJECTILES];
|
||||||
extern int extraproj_num;
|
extern int extraproj_num;
|
||||||
|
|
||||||
void extraproj_reset();
|
void extraproj_reset();
|
||||||
|
|
|
@ -120,17 +120,17 @@ extern "C" void modc_predict()
|
||||||
const void *data = snap_get_item(SNAP_CURRENT, i, &item);
|
const void *data = snap_get_item(SNAP_CURRENT, i, &item);
|
||||||
int client_id = item.id;
|
int client_id = item.id;
|
||||||
|
|
||||||
if(item.type == OBJTYPE_PLAYER_CHARACTER)
|
if(item.type == NETOBJTYPE_PLAYER_CHARACTER)
|
||||||
{
|
{
|
||||||
const obj_player_character *character = (const obj_player_character *)data;
|
const NETOBJ_PLAYER_CHARACTER *character = (const NETOBJ_PLAYER_CHARACTER *)data;
|
||||||
client_datas[client_id].predicted.world = &world;
|
client_datas[client_id].predicted.world = &world;
|
||||||
world.players[client_id] = &client_datas[client_id].predicted;
|
world.players[client_id] = &client_datas[client_id].predicted;
|
||||||
|
|
||||||
client_datas[client_id].predicted.read(character);
|
client_datas[client_id].predicted.read(character);
|
||||||
}
|
}
|
||||||
else if(item.type == OBJTYPE_PLAYER_INFO)
|
else if(item.type == NETOBJTYPE_PLAYER_INFO)
|
||||||
{
|
{
|
||||||
const obj_player_info *info = (const obj_player_info *)data;
|
const NETOBJ_PLAYER_INFO *info = (const NETOBJ_PLAYER_INFO *)data;
|
||||||
if(info->local)
|
if(info->local)
|
||||||
local_cid = client_id;
|
local_cid = client_id;
|
||||||
}
|
}
|
||||||
|
@ -155,7 +155,7 @@ extern "C" void modc_predict()
|
||||||
// apply player input
|
// apply player input
|
||||||
int *input = client_get_input(tick);
|
int *input = client_get_input(tick);
|
||||||
if(input)
|
if(input)
|
||||||
world.players[c]->input = *((player_input*)input);
|
world.players[c]->input = *((NETOBJ_PLAYER_INPUT*)input);
|
||||||
}
|
}
|
||||||
|
|
||||||
world.players[c]->tick();
|
world.players[c]->tick();
|
||||||
|
@ -230,6 +230,23 @@ extern "C" void modc_newsnapshot()
|
||||||
static int snapshot_count = 0;
|
static int snapshot_count = 0;
|
||||||
snapshot_count++;
|
snapshot_count++;
|
||||||
|
|
||||||
|
// secure snapshot
|
||||||
|
{
|
||||||
|
int num = snap_num_items(SNAP_CURRENT);
|
||||||
|
for(int index = 0; index < num; index++)
|
||||||
|
{
|
||||||
|
SNAP_ITEM item;
|
||||||
|
void *data = snap_get_item(SNAP_CURRENT, index, &item);
|
||||||
|
if(netobj_secure(item.type, data, item.datasize) != 0)
|
||||||
|
{
|
||||||
|
if(config.debug)
|
||||||
|
dbg_msg("game", "invalidated %d %d (%s) %d", index, item.type, netobj_get_name(item.type), item.id);
|
||||||
|
snap_invalidate_item(SNAP_CURRENT, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
process_events(SNAP_CURRENT);
|
process_events(SNAP_CURRENT);
|
||||||
|
|
||||||
if(config.dbg_stress)
|
if(config.dbg_stress)
|
||||||
|
@ -256,32 +273,32 @@ extern "C" void modc_newsnapshot()
|
||||||
SNAP_ITEM item;
|
SNAP_ITEM item;
|
||||||
const void *data = snap_get_item(SNAP_CURRENT, i, &item);
|
const void *data = snap_get_item(SNAP_CURRENT, i, &item);
|
||||||
|
|
||||||
if(item.type == OBJTYPE_PLAYER_INFO)
|
if(item.type == NETOBJTYPE_PLAYER_INFO)
|
||||||
{
|
{
|
||||||
const obj_player_info *info = (const obj_player_info *)data;
|
const NETOBJ_PLAYER_INFO *info = (const NETOBJ_PLAYER_INFO *)data;
|
||||||
|
|
||||||
client_datas[info->clientid].team = info->team;
|
client_datas[info->cid].team = info->team;
|
||||||
|
|
||||||
if(info->local)
|
if(info->local)
|
||||||
{
|
{
|
||||||
local_info = info;
|
netobjects.local_info = info;
|
||||||
const void *data = snap_find_item(SNAP_CURRENT, OBJTYPE_PLAYER_CHARACTER, item.id);
|
const void *data = snap_find_item(SNAP_CURRENT, NETOBJTYPE_PLAYER_CHARACTER, item.id);
|
||||||
if(data)
|
if(data)
|
||||||
{
|
{
|
||||||
local_character = (const obj_player_character *)data;
|
netobjects.local_character = (const NETOBJ_PLAYER_CHARACTER *)data;
|
||||||
local_character_pos = vec2(local_character->x, local_character->y);
|
local_character_pos = vec2(netobjects.local_character->x, netobjects.local_character->y);
|
||||||
|
|
||||||
const void *p = snap_find_item(SNAP_PREV, OBJTYPE_PLAYER_CHARACTER, item.id);
|
const void *p = snap_find_item(SNAP_PREV, NETOBJTYPE_PLAYER_CHARACTER, item.id);
|
||||||
if(p)
|
if(p)
|
||||||
local_prev_character = (obj_player_character *)p;
|
netobjects.local_prev_character = (NETOBJ_PLAYER_CHARACTER *)p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(item.type == OBJTYPE_GAME)
|
else if(item.type == NETOBJTYPE_GAME)
|
||||||
gameobj = (obj_game *)data;
|
netobjects.gameobj = (NETOBJ_GAME *)data;
|
||||||
else if(item.type == OBJTYPE_FLAG)
|
else if(item.type == NETOBJTYPE_FLAG)
|
||||||
{
|
{
|
||||||
flags[item.id%2] = (const obj_flag *)data;
|
netobjects.flags[item.id%2] = (const NETOBJ_FLAG *)data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -394,7 +411,7 @@ extern "C" void modc_statechange(int state, int old)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
obj_projectile extraproj_projectiles[MAX_EXTRA_PROJECTILES];
|
NETOBJ_PROJECTILE extraproj_projectiles[MAX_EXTRA_PROJECTILES];
|
||||||
int extraproj_num;
|
int extraproj_num;
|
||||||
|
|
||||||
void extraproj_reset()
|
void extraproj_reset()
|
||||||
|
@ -409,6 +426,11 @@ extern "C" void modc_message(int msg)
|
||||||
int cid = msg_unpack_int();
|
int cid = msg_unpack_int();
|
||||||
int team = msg_unpack_int();
|
int team = msg_unpack_int();
|
||||||
const char *message = msg_unpack_string();
|
const char *message = msg_unpack_string();
|
||||||
|
|
||||||
|
/* check for errors and invalid inputs */
|
||||||
|
if(msg_unpack_error() || cid < 0 || cid >= MAX_CLIENTS)
|
||||||
|
return;
|
||||||
|
|
||||||
dbg_msg("message", "chat cid=%d team=%d msg='%s'", cid, team, message);
|
dbg_msg("message", "chat cid=%d team=%d msg='%s'", cid, team, message);
|
||||||
chat_add_line(cid, team, message);
|
chat_add_line(cid, team, message);
|
||||||
|
|
||||||
|
@ -423,10 +445,13 @@ extern "C" void modc_message(int msg)
|
||||||
|
|
||||||
for(int k = 0; k < num; k++)
|
for(int k = 0; k < num; k++)
|
||||||
{
|
{
|
||||||
obj_projectile proj;
|
NETOBJ_PROJECTILE proj;
|
||||||
for(unsigned i = 0; i < sizeof(obj_projectile)/sizeof(int); i++)
|
for(unsigned i = 0; i < sizeof(NETOBJ_PROJECTILE)/sizeof(int); i++)
|
||||||
((int *)&proj)[i] = msg_unpack_int();
|
((int *)&proj)[i] = msg_unpack_int();
|
||||||
|
|
||||||
|
if(msg_unpack_error())
|
||||||
|
return;
|
||||||
|
|
||||||
if(extraproj_num != MAX_EXTRA_PROJECTILES)
|
if(extraproj_num != MAX_EXTRA_PROJECTILES)
|
||||||
{
|
{
|
||||||
extraproj_projectiles[extraproj_num] = proj;
|
extraproj_projectiles[extraproj_num] = proj;
|
||||||
|
@ -440,6 +465,10 @@ extern "C" void modc_message(int msg)
|
||||||
const char *name = msg_unpack_string();
|
const char *name = msg_unpack_string();
|
||||||
const char *skinname = msg_unpack_string();
|
const char *skinname = msg_unpack_string();
|
||||||
|
|
||||||
|
/* check for errors and invalid inputs */
|
||||||
|
if(msg_unpack_error() || cid < 0 || cid >= MAX_CLIENTS)
|
||||||
|
return;
|
||||||
|
|
||||||
strncpy(client_datas[cid].name, name, 64);
|
strncpy(client_datas[cid].name, name, 64);
|
||||||
strncpy(client_datas[cid].skin_name, skinname, 64);
|
strncpy(client_datas[cid].skin_name, skinname, 64);
|
||||||
|
|
||||||
|
@ -466,13 +495,24 @@ extern "C" void modc_message(int msg)
|
||||||
}
|
}
|
||||||
else if(msg == MSG_TUNE_PARAMS)
|
else if(msg == MSG_TUNE_PARAMS)
|
||||||
{
|
{
|
||||||
int *params = (int *)&tuning;
|
// unpack the new tuning
|
||||||
|
tuning_params new_tuning;
|
||||||
|
int *params = (int *)&new_tuning;
|
||||||
for(unsigned i = 0; i < sizeof(tuning_params)/sizeof(int); i++)
|
for(unsigned i = 0; i < sizeof(tuning_params)/sizeof(int); i++)
|
||||||
params[i] = msg_unpack_int();
|
params[i] = msg_unpack_int();
|
||||||
|
|
||||||
|
// check for unpacking errors
|
||||||
|
if(msg_unpack_error())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// apply new tuning
|
||||||
|
tuning = new_tuning;
|
||||||
}
|
}
|
||||||
else if(msg == MSG_WEAPON_PICKUP)
|
else if(msg == MSG_WEAPON_PICKUP)
|
||||||
{
|
{
|
||||||
int weapon = msg_unpack_int();
|
int weapon = msg_unpack_int();
|
||||||
|
if(msg_unpack_error())
|
||||||
|
return;
|
||||||
picked_up_weapon = weapon+1;
|
picked_up_weapon = weapon+1;
|
||||||
}
|
}
|
||||||
else if(msg == MSG_READY_TO_ENTER)
|
else if(msg == MSG_READY_TO_ENTER)
|
||||||
|
@ -481,23 +521,41 @@ extern "C" void modc_message(int msg)
|
||||||
}
|
}
|
||||||
else if(msg == MSG_KILLMSG)
|
else if(msg == MSG_KILLMSG)
|
||||||
{
|
{
|
||||||
|
// unpack messages
|
||||||
|
killmsg msg;
|
||||||
|
msg.killer = msg_unpack_int();
|
||||||
|
msg.victim = msg_unpack_int();
|
||||||
|
msg.weapon = msg_unpack_int();
|
||||||
|
msg.mode_special = msg_unpack_int();
|
||||||
|
msg.tick = client_tick();
|
||||||
|
|
||||||
|
// check for unpacking errors
|
||||||
|
if(msg_unpack_error() || msg.killer >= MAX_CLIENTS || msg.victim >= MAX_CLIENTS || msg.weapon >= NUM_WEAPONS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// add the message
|
||||||
killmsg_current = (killmsg_current+1)%killmsg_max;
|
killmsg_current = (killmsg_current+1)%killmsg_max;
|
||||||
killmsgs[killmsg_current].killer = msg_unpack_int();
|
killmsgs[killmsg_current] = msg;
|
||||||
killmsgs[killmsg_current].victim = msg_unpack_int();
|
|
||||||
killmsgs[killmsg_current].weapon = msg_unpack_int();
|
|
||||||
killmsgs[killmsg_current].mode_special = msg_unpack_int();
|
|
||||||
killmsgs[killmsg_current].tick = client_tick();
|
|
||||||
}
|
}
|
||||||
else if (msg == MSG_EMOTICON)
|
else if (msg == MSG_EMOTICON)
|
||||||
{
|
{
|
||||||
|
// unpack
|
||||||
int cid = msg_unpack_int();
|
int cid = msg_unpack_int();
|
||||||
int emoticon = msg_unpack_int();
|
int emoticon = msg_unpack_int();
|
||||||
|
|
||||||
|
// check for errors
|
||||||
|
if(msg_unpack_error() || cid < 0 || cid >= MAX_CLIENTS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// apply
|
||||||
client_datas[cid].emoticon = emoticon;
|
client_datas[cid].emoticon = emoticon;
|
||||||
client_datas[cid].emoticon_start = client_tick();
|
client_datas[cid].emoticon_start = client_tick();
|
||||||
}
|
}
|
||||||
else if(msg == MSG_SOUND_GLOBAL)
|
else if(msg == MSG_SOUND_GLOBAL)
|
||||||
{
|
{
|
||||||
int soundid = msg_unpack_int();
|
int soundid = msg_unpack_int();
|
||||||
|
if(msg_unpack_error() || soundid < 0)
|
||||||
|
return;
|
||||||
snd_play_random(CHN_GLOBAL, soundid, 1.0f, vec2(0,0));
|
snd_play_random(CHN_GLOBAL, soundid, 1.0f, vec2(0,0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,10 +27,6 @@ extern "C" {
|
||||||
|
|
||||||
extern data_container *data;
|
extern data_container *data;
|
||||||
|
|
||||||
// abit uglyness
|
|
||||||
extern const obj_player_info *local_info;
|
|
||||||
extern const obj_game *gameobj;
|
|
||||||
|
|
||||||
extern bool menu_active;
|
extern bool menu_active;
|
||||||
extern bool menu_game_active;
|
extern bool menu_game_active;
|
||||||
|
|
||||||
|
@ -1614,9 +1610,9 @@ static void menu2_render_game(RECT main_view)
|
||||||
if(ui_do_button(&disconnect_button, "Disconnect", 0, &button, ui_draw_menu_button, 0))
|
if(ui_do_button(&disconnect_button, "Disconnect", 0, &button, ui_draw_menu_button, 0))
|
||||||
client_disconnect();
|
client_disconnect();
|
||||||
|
|
||||||
if(local_info && gameobj)
|
if(netobjects.local_info && netobjects.gameobj)
|
||||||
{
|
{
|
||||||
if(local_info->team != -1)
|
if(netobjects.local_info->team != -1)
|
||||||
{
|
{
|
||||||
ui_vsplit_l(&main_view, 10.0f, &button, &main_view);
|
ui_vsplit_l(&main_view, 10.0f, &button, &main_view);
|
||||||
ui_vsplit_l(&main_view, 120.0f, &button, &main_view);
|
ui_vsplit_l(&main_view, 120.0f, &button, &main_view);
|
||||||
|
@ -1628,9 +1624,9 @@ static void menu2_render_game(RECT main_view)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(gameobj->gametype == GAMETYPE_DM)
|
if(netobjects.gameobj->gametype == GAMETYPE_DM)
|
||||||
{
|
{
|
||||||
if(local_info->team != 0)
|
if(netobjects.local_info->team != 0)
|
||||||
{
|
{
|
||||||
ui_vsplit_l(&main_view, 10.0f, &button, &main_view);
|
ui_vsplit_l(&main_view, 10.0f, &button, &main_view);
|
||||||
ui_vsplit_l(&main_view, 120.0f, &button, &main_view);
|
ui_vsplit_l(&main_view, 120.0f, &button, &main_view);
|
||||||
|
@ -1644,7 +1640,7 @@ static void menu2_render_game(RECT main_view)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(local_info->team != 0)
|
if(netobjects.local_info->team != 0)
|
||||||
{
|
{
|
||||||
ui_vsplit_l(&main_view, 10.0f, &button, &main_view);
|
ui_vsplit_l(&main_view, 10.0f, &button, &main_view);
|
||||||
ui_vsplit_l(&main_view, 120.0f, &button, &main_view);
|
ui_vsplit_l(&main_view, 120.0f, &button, &main_view);
|
||||||
|
@ -1656,7 +1652,7 @@ static void menu2_render_game(RECT main_view)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(local_info->team != 1)
|
if(netobjects.local_info->team != 1)
|
||||||
{
|
{
|
||||||
ui_vsplit_l(&main_view, 10.0f, &button, &main_view);
|
ui_vsplit_l(&main_view, 10.0f, &button, &main_view);
|
||||||
ui_vsplit_l(&main_view, 120.0f, &button, &main_view);
|
ui_vsplit_l(&main_view, 120.0f, &button, &main_view);
|
||||||
|
|
|
@ -349,25 +349,25 @@ static void render_items()
|
||||||
SNAP_ITEM item;
|
SNAP_ITEM item;
|
||||||
const void *data = snap_get_item(SNAP_CURRENT, i, &item);
|
const void *data = snap_get_item(SNAP_CURRENT, i, &item);
|
||||||
|
|
||||||
if(item.type == OBJTYPE_PROJECTILE)
|
if(item.type == NETOBJTYPE_PROJECTILE)
|
||||||
{
|
{
|
||||||
render_projectile((const obj_projectile *)data, item.id);
|
render_projectile((const NETOBJ_PROJECTILE *)data, item.id);
|
||||||
}
|
}
|
||||||
else if(item.type == OBJTYPE_POWERUP)
|
else if(item.type == NETOBJTYPE_POWERUP)
|
||||||
{
|
{
|
||||||
const void *prev = snap_find_item(SNAP_PREV, item.type, item.id);
|
const void *prev = snap_find_item(SNAP_PREV, item.type, item.id);
|
||||||
if(prev)
|
if(prev)
|
||||||
render_powerup((const obj_powerup *)prev, (const obj_powerup *)data);
|
render_powerup((const NETOBJ_POWERUP *)prev, (const NETOBJ_POWERUP *)data);
|
||||||
}
|
}
|
||||||
else if(item.type == OBJTYPE_LASER)
|
else if(item.type == NETOBJTYPE_LASER)
|
||||||
{
|
{
|
||||||
render_laser((const obj_laser *)data);
|
render_laser((const NETOBJ_LASER *)data);
|
||||||
}
|
}
|
||||||
else if(item.type == OBJTYPE_FLAG)
|
else if(item.type == NETOBJTYPE_FLAG)
|
||||||
{
|
{
|
||||||
const void *prev = snap_find_item(SNAP_PREV, item.type, item.id);
|
const void *prev = snap_find_item(SNAP_PREV, item.type, item.id);
|
||||||
if (prev)
|
if (prev)
|
||||||
render_flag((const obj_flag *)prev, (const obj_flag *)data);
|
render_flag((const NETOBJ_FLAG *)prev, (const NETOBJ_FLAG *)data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,19 +393,19 @@ static void render_players()
|
||||||
SNAP_ITEM item;
|
SNAP_ITEM item;
|
||||||
const void *data = snap_get_item(SNAP_CURRENT, i, &item);
|
const void *data = snap_get_item(SNAP_CURRENT, i, &item);
|
||||||
|
|
||||||
if(item.type == OBJTYPE_PLAYER_CHARACTER)
|
if(item.type == NETOBJTYPE_PLAYER_CHARACTER)
|
||||||
{
|
{
|
||||||
const void *prev = snap_find_item(SNAP_PREV, item.type, item.id);
|
const void *prev = snap_find_item(SNAP_PREV, item.type, item.id);
|
||||||
const void *prev_info = snap_find_item(SNAP_PREV, OBJTYPE_PLAYER_INFO, item.id);
|
const void *prev_info = snap_find_item(SNAP_PREV, NETOBJTYPE_PLAYER_INFO, item.id);
|
||||||
const void *info = snap_find_item(SNAP_CURRENT, OBJTYPE_PLAYER_INFO, item.id);
|
const void *info = snap_find_item(SNAP_CURRENT, NETOBJTYPE_PLAYER_INFO, item.id);
|
||||||
|
|
||||||
if(prev && prev_info && info)
|
if(prev && prev_info && info)
|
||||||
{
|
{
|
||||||
render_player(
|
render_player(
|
||||||
(const obj_player_character *)prev,
|
(const NETOBJ_PLAYER_CHARACTER *)prev,
|
||||||
(const obj_player_character *)data,
|
(const NETOBJ_PLAYER_CHARACTER *)data,
|
||||||
(const obj_player_info *)prev_info,
|
(const NETOBJ_PLAYER_INFO *)prev_info,
|
||||||
(const obj_player_info *)info
|
(const NETOBJ_PLAYER_INFO *)info
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,13 +54,13 @@ void render_particles();
|
||||||
|
|
||||||
// object render methods (gc_render_obj.cpp)
|
// object render methods (gc_render_obj.cpp)
|
||||||
void render_tee(class animstate *anim, tee_render_info *info, int emote, vec2 dir, vec2 pos);
|
void render_tee(class animstate *anim, tee_render_info *info, int emote, vec2 dir, vec2 pos);
|
||||||
void render_flag(const struct obj_flag *prev, const struct obj_flag *current);
|
void render_flag(const struct NETOBJ_FLAG *prev, const struct NETOBJ_FLAG *current);
|
||||||
void render_powerup(const struct obj_powerup *prev, const struct obj_powerup *current);
|
void render_powerup(const struct NETOBJ_POWERUP *prev, const struct NETOBJ_POWERUP *current);
|
||||||
void render_projectile(const struct obj_projectile *current, int itemid);
|
void render_projectile(const struct NETOBJ_PROJECTILE *current, int itemid);
|
||||||
void render_laser(const struct obj_laser *current);
|
void render_laser(const struct NETOBJ_LASER *current);
|
||||||
void render_player(
|
void render_player(
|
||||||
const struct obj_player_character *prev_char, const struct obj_player_character *player_char,
|
const struct NETOBJ_PLAYER_CHARACTER *prev_char, const struct NETOBJ_PLAYER_CHARACTER *player_char,
|
||||||
const struct obj_player_info *prev_info, const struct obj_player_info *player_info);
|
const struct NETOBJ_PLAYER_INFO *prev_info, const struct NETOBJ_PLAYER_INFO *player_info);
|
||||||
|
|
||||||
// map render methods (gc_render_map.cpp)
|
// map render methods (gc_render_map.cpp)
|
||||||
void render_eval_envelope(ENVPOINT *points, int num_points, int channels, float time, float *result);
|
void render_eval_envelope(ENVPOINT *points, int num_points, int channels, float time, float *result);
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include "gc_client.h"
|
#include "gc_client.h"
|
||||||
|
|
||||||
|
|
||||||
void render_projectile(const obj_projectile *current, int itemid)
|
void render_projectile(const NETOBJ_PROJECTILE *current, int itemid)
|
||||||
{
|
{
|
||||||
if(debug_firedelay)
|
if(debug_firedelay)
|
||||||
{
|
{
|
||||||
|
@ -34,7 +34,7 @@ void render_projectile(const obj_projectile *current, int itemid)
|
||||||
vec2 pos = calc_pos(startpos, startvel, gravity, ct);
|
vec2 pos = calc_pos(startpos, startvel, gravity, ct);
|
||||||
vec2 prevpos = calc_pos(startpos, startvel, gravity, ct-0.001f);
|
vec2 prevpos = calc_pos(startpos, startvel, gravity, ct-0.001f);
|
||||||
|
|
||||||
select_sprite(data->weapons[current->type%data->num_weapons].sprite_proj);
|
select_sprite(data->weapons[clamp(current->type, 0, NUM_WEAPONS-1)].sprite_proj);
|
||||||
vec2 vel = pos-prevpos;
|
vec2 vel = pos-prevpos;
|
||||||
//vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), client_intratick());
|
//vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), client_intratick());
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ void render_projectile(const obj_projectile *current, int itemid)
|
||||||
gfx_quads_end();
|
gfx_quads_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void render_powerup(const obj_powerup *prev, const obj_powerup *current)
|
void render_powerup(const NETOBJ_POWERUP *prev, const NETOBJ_POWERUP *current)
|
||||||
{
|
{
|
||||||
gfx_texture_set(data->images[IMAGE_GAME].id);
|
gfx_texture_set(data->images[IMAGE_GAME].id);
|
||||||
gfx_quads_begin();
|
gfx_quads_begin();
|
||||||
|
@ -73,8 +73,8 @@ void render_powerup(const obj_powerup *prev, const obj_powerup *current)
|
||||||
if (current->type == POWERUP_WEAPON)
|
if (current->type == POWERUP_WEAPON)
|
||||||
{
|
{
|
||||||
angle = 0; //-pi/6;//-0.25f * pi * 2.0f;
|
angle = 0; //-pi/6;//-0.25f * pi * 2.0f;
|
||||||
select_sprite(data->weapons[current->subtype%data->num_weapons].sprite_body);
|
select_sprite(data->weapons[clamp(current->subtype, 0, NUM_WEAPONS-1)].sprite_body);
|
||||||
size = data->weapons[current->subtype%data->num_weapons].visual_size;
|
size = data->weapons[clamp(current->subtype, 0, NUM_WEAPONS-1)].visual_size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -107,7 +107,7 @@ void render_powerup(const obj_powerup *prev, const obj_powerup *current)
|
||||||
gfx_quads_end();
|
gfx_quads_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void render_flag(const obj_flag *prev, const obj_flag *current)
|
void render_flag(const NETOBJ_FLAG *prev, const NETOBJ_FLAG *current)
|
||||||
{
|
{
|
||||||
float angle = 0.0f;
|
float angle = 0.0f;
|
||||||
float size = 42.0f;
|
float size = 42.0f;
|
||||||
|
@ -125,7 +125,7 @@ void render_flag(const obj_flag *prev, const obj_flag *current)
|
||||||
|
|
||||||
vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), client_intratick());
|
vec2 pos = mix(vec2(prev->x, prev->y), vec2(current->x, current->y), client_intratick());
|
||||||
|
|
||||||
if(local_info && current->carried_by == local_info->clientid)
|
if(netobjects.local_info && current->carried_by == netobjects.local_info->cid)
|
||||||
pos = local_character_pos;
|
pos = local_character_pos;
|
||||||
|
|
||||||
//gfx_setcolor(current->team ? 0 : 1,0,current->team ? 1 : 0,1);
|
//gfx_setcolor(current->team ? 0 : 1,0,current->team ? 1 : 0,1);
|
||||||
|
@ -135,7 +135,7 @@ void render_flag(const obj_flag *prev, const obj_flag *current)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void render_laser(const struct obj_laser *current)
|
void render_laser(const struct NETOBJ_LASER *current)
|
||||||
{
|
{
|
||||||
|
|
||||||
vec2 pos = vec2(current->x, current->y);
|
vec2 pos = vec2(current->x, current->y);
|
||||||
|
@ -245,19 +245,19 @@ static void render_hand(tee_render_info *info, vec2 center_pos, vec2 dir, float
|
||||||
}
|
}
|
||||||
|
|
||||||
void render_player(
|
void render_player(
|
||||||
const obj_player_character *prev_char,
|
const NETOBJ_PLAYER_CHARACTER *prev_char,
|
||||||
const obj_player_character *player_char,
|
const NETOBJ_PLAYER_CHARACTER *player_char,
|
||||||
const obj_player_info *prev_info,
|
const NETOBJ_PLAYER_INFO *prev_info,
|
||||||
const obj_player_info *player_info
|
const NETOBJ_PLAYER_INFO *player_info
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
obj_player_character prev;
|
NETOBJ_PLAYER_CHARACTER prev;
|
||||||
obj_player_character player;
|
NETOBJ_PLAYER_CHARACTER player;
|
||||||
prev = *prev_char;
|
prev = *prev_char;
|
||||||
player = *player_char;
|
player = *player_char;
|
||||||
|
|
||||||
obj_player_info info = *player_info;
|
NETOBJ_PLAYER_INFO info = *player_info;
|
||||||
tee_render_info render_info = client_datas[info.clientid].render_info;
|
tee_render_info render_info = client_datas[info.cid].render_info;
|
||||||
|
|
||||||
float intratick = client_intratick();
|
float intratick = client_intratick();
|
||||||
float ticktime = client_ticktime();
|
float ticktime = client_ticktime();
|
||||||
|
@ -267,7 +267,7 @@ void render_player(
|
||||||
|
|
||||||
if(info.local && config.cl_predict)
|
if(info.local && config.cl_predict)
|
||||||
{
|
{
|
||||||
if(!local_character || (local_character->health < 0) || (gameobj && gameobj->game_over))
|
if(!netobjects.local_character || (netobjects.local_character->health < 0) || (netobjects.gameobj && netobjects.gameobj->game_over))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -329,7 +329,7 @@ void render_player(
|
||||||
|
|
||||||
if(player_char->hooked_player != -1)
|
if(player_char->hooked_player != -1)
|
||||||
{
|
{
|
||||||
if(local_info && player_char->hooked_player == local_info->clientid)
|
if(netobjects.local_info && player_char->hooked_player == netobjects.local_info->cid)
|
||||||
{
|
{
|
||||||
hook_pos = mix(vec2(predicted_prev_player.pos.x, predicted_prev_player.pos.y),
|
hook_pos = mix(vec2(predicted_prev_player.pos.x, predicted_prev_player.pos.y),
|
||||||
vec2(predicted_player.pos.x, predicted_player.pos.y), client_predintratick());
|
vec2(predicted_player.pos.x, predicted_player.pos.y), client_predintratick());
|
||||||
|
@ -351,7 +351,8 @@ void render_player(
|
||||||
|
|
||||||
// render chain
|
// render chain
|
||||||
select_sprite(SPRITE_HOOK_CHAIN);
|
select_sprite(SPRITE_HOOK_CHAIN);
|
||||||
for(float f = 24; f < d; f += 24)
|
int i = 0;
|
||||||
|
for(float f = 24; f < d && i < 1024; f += 24, i++)
|
||||||
{
|
{
|
||||||
vec2 p = hook_pos + dir*f;
|
vec2 p = hook_pos + dir*f;
|
||||||
gfx_quads_draw(p.x, p.y,24,16);
|
gfx_quads_draw(p.x, p.y,24,16);
|
||||||
|
@ -360,7 +361,7 @@ void render_player(
|
||||||
gfx_quads_setrotation(0);
|
gfx_quads_setrotation(0);
|
||||||
gfx_quads_end();
|
gfx_quads_end();
|
||||||
|
|
||||||
render_hand(&client_datas[info.clientid].render_info, position, normalize(hook_pos-pos), -pi/2, vec2(20, 0));
|
render_hand(&client_datas[info.cid].render_info, position, normalize(hook_pos-pos), -pi/2, vec2(20, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw gun
|
// draw gun
|
||||||
|
@ -478,9 +479,9 @@ void render_player(
|
||||||
|
|
||||||
switch (player.weapon)
|
switch (player.weapon)
|
||||||
{
|
{
|
||||||
case WEAPON_GUN: render_hand(&client_datas[info.clientid].render_info, p, direction, -3*pi/4, vec2(-15, 4)); break;
|
case WEAPON_GUN: render_hand(&client_datas[info.cid].render_info, p, direction, -3*pi/4, vec2(-15, 4)); break;
|
||||||
case WEAPON_SHOTGUN: render_hand(&client_datas[info.clientid].render_info, p, direction, -pi/2, vec2(-5, 4)); break;
|
case WEAPON_SHOTGUN: render_hand(&client_datas[info.cid].render_info, p, direction, -pi/2, vec2(-5, 4)); break;
|
||||||
case WEAPON_GRENADE: render_hand(&client_datas[info.clientid].render_info, p, direction, -pi/2, vec2(-4, 7)); break;
|
case WEAPON_GRENADE: render_hand(&client_datas[info.cid].render_info, p, direction, -pi/2, vec2(-4, 7)); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -507,13 +508,13 @@ void render_player(
|
||||||
gfx_quads_end();
|
gfx_quads_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client_datas[info.clientid].emoticon_start != -1 && client_datas[info.clientid].emoticon_start + 2 * client_tickspeed() > client_tick())
|
if (client_datas[info.cid].emoticon_start != -1 && client_datas[info.cid].emoticon_start + 2 * client_tickspeed() > client_tick())
|
||||||
{
|
{
|
||||||
gfx_texture_set(data->images[IMAGE_EMOTICONS].id);
|
gfx_texture_set(data->images[IMAGE_EMOTICONS].id);
|
||||||
gfx_quads_begin();
|
gfx_quads_begin();
|
||||||
|
|
||||||
int since_start = client_tick() - client_datas[info.clientid].emoticon_start;
|
int since_start = client_tick() - client_datas[info.cid].emoticon_start;
|
||||||
int from_end = client_datas[info.clientid].emoticon_start + 2 * client_tickspeed() - client_tick();
|
int from_end = client_datas[info.cid].emoticon_start + 2 * client_tickspeed() - client_tick();
|
||||||
|
|
||||||
float a = 1;
|
float a = 1;
|
||||||
|
|
||||||
|
@ -534,7 +535,7 @@ void render_player(
|
||||||
|
|
||||||
gfx_setcolor(1.0f,1.0f,1.0f,a);
|
gfx_setcolor(1.0f,1.0f,1.0f,a);
|
||||||
// client_datas::emoticon is an offset from the first emoticon
|
// client_datas::emoticon is an offset from the first emoticon
|
||||||
select_sprite(SPRITE_OOP + client_datas[info.clientid].emoticon);
|
select_sprite(SPRITE_OOP + client_datas[info.cid].emoticon);
|
||||||
gfx_quads_draw(position.x, position.y - 23 - 32*h, 64, 64*h);
|
gfx_quads_draw(position.x, position.y - 23 - 32*h, 64, 64*h);
|
||||||
gfx_quads_end();
|
gfx_quads_end();
|
||||||
}
|
}
|
||||||
|
@ -547,7 +548,7 @@ void render_player(
|
||||||
if(config.cl_nameplates_always == 0)
|
if(config.cl_nameplates_always == 0)
|
||||||
a = clamp(1-powf(distance(local_target_pos, position)/200.0f,16.0f), 0.0f, 1.0f);
|
a = clamp(1-powf(distance(local_target_pos, position)/200.0f,16.0f), 0.0f, 1.0f);
|
||||||
|
|
||||||
const char *name = client_datas[info.clientid].name;
|
const char *name = client_datas[info.cid].name;
|
||||||
float tw = gfx_text_width(0, 28.0f, name, -1);
|
float tw = gfx_text_width(0, 28.0f, name, -1);
|
||||||
gfx_text_color(1,1,1,a);
|
gfx_text_color(1,1,1,a);
|
||||||
gfx_text(0, position.x-tw/2.0f, position.y-60, 28.0f, name, -1);
|
gfx_text(0, position.x-tw/2.0f, position.y-60, 28.0f, name, -1);
|
||||||
|
|
|
@ -400,7 +400,7 @@ void player_core::move()
|
||||||
move_box(&pos, &vel, vec2(28.0f, 28.0f), 0);
|
move_box(&pos, &vel, vec2(28.0f, 28.0f), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void player_core::write(obj_player_core *obj_core)
|
void player_core::write(NETOBJ_PLAYER_CORE *obj_core)
|
||||||
{
|
{
|
||||||
obj_core->x = (int)pos.x;
|
obj_core->x = (int)pos.x;
|
||||||
obj_core->y = (int)pos.y;
|
obj_core->y = (int)pos.y;
|
||||||
|
@ -427,7 +427,7 @@ void player_core::write(obj_player_core *obj_core)
|
||||||
obj_core->angle = (int)(a*256.0f);
|
obj_core->angle = (int)(a*256.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void player_core::read(const obj_player_core *obj_core)
|
void player_core::read(const NETOBJ_PLAYER_CORE *obj_core)
|
||||||
{
|
{
|
||||||
pos.x = obj_core->x;
|
pos.x = obj_core->x;
|
||||||
pos.y = obj_core->y;
|
pos.y = obj_core->y;
|
||||||
|
@ -445,7 +445,7 @@ void player_core::read(const obj_player_core *obj_core)
|
||||||
|
|
||||||
void player_core::quantize()
|
void player_core::quantize()
|
||||||
{
|
{
|
||||||
obj_player_core c;
|
NETOBJ_PLAYER_CORE c;
|
||||||
write(&c);
|
write(&c);
|
||||||
read(&c);
|
read(&c);
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,15 +133,15 @@ public:
|
||||||
int hooked_player;
|
int hooked_player;
|
||||||
|
|
||||||
int jumped;
|
int jumped;
|
||||||
player_input input;
|
NETOBJ_PLAYER_INPUT input;
|
||||||
|
|
||||||
int triggered_events;
|
int triggered_events;
|
||||||
|
|
||||||
void tick();
|
void tick();
|
||||||
void move();
|
void move();
|
||||||
|
|
||||||
void read(const obj_player_core *obj_core);
|
void read(const NETOBJ_PLAYER_CORE *obj_core);
|
||||||
void write(obj_player_core *obj_core);
|
void write(NETOBJ_PLAYER_CORE *obj_core);
|
||||||
void quantize();
|
void quantize();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -33,12 +33,10 @@ void layers_init()
|
||||||
|
|
||||||
if(tilemap->flags&1)
|
if(tilemap->flags&1)
|
||||||
{
|
{
|
||||||
dbg_msg("layers", "game");
|
|
||||||
game_layer = tilemap;
|
game_layer = tilemap;
|
||||||
p = 2;
|
p = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dbg_msg("layers", "%d %d", i, layer->type);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
211
src/game/g_protocol.def
Normal file
211
src/game/g_protocol.def
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
|
||||||
|
raw_source
|
||||||
|
#include "g_protocol.h"
|
||||||
|
#include "g_protocol_ids.h"
|
||||||
|
#include <engine/e_common_interface.h>
|
||||||
|
#define max_int 100000
|
||||||
|
end
|
||||||
|
|
||||||
|
raw_header
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
// emotes
|
||||||
|
EMOTE_NORMAL=0,
|
||||||
|
EMOTE_PAIN,
|
||||||
|
EMOTE_HAPPY,
|
||||||
|
EMOTE_SURPRISE,
|
||||||
|
EMOTE_ANGRY,
|
||||||
|
EMOTE_BLINK,
|
||||||
|
NUM_EMOTES,
|
||||||
|
|
||||||
|
// playerstates
|
||||||
|
PLAYERSTATE_UNKNOWN=0,
|
||||||
|
PLAYERSTATE_PLAYING,
|
||||||
|
PLAYERSTATE_IN_MENU,
|
||||||
|
PLAYERSTATE_CHATTING,
|
||||||
|
NUM_PLAYERSTATES,
|
||||||
|
|
||||||
|
// game types
|
||||||
|
GAMETYPE_DM=0,
|
||||||
|
GAMETYPE_TDM,
|
||||||
|
GAMETYPE_CTF,
|
||||||
|
NUM_GAMETYPES,
|
||||||
|
|
||||||
|
// other stuff
|
||||||
|
INPUT_STATE_MASK=0x1f,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
MSG_NULL=0,
|
||||||
|
MSG_SAY, // client -> server
|
||||||
|
MSG_CHAT, // server -> client
|
||||||
|
MSG_SETINFO, // server -> client - contains name, skin and color info
|
||||||
|
MSG_KILLMSG, // server -> client
|
||||||
|
MSG_SETTEAM,
|
||||||
|
MSG_JOIN,
|
||||||
|
MSG_QUIT,
|
||||||
|
MSG_EMOTICON,
|
||||||
|
MSG_STARTINFO, // client -> server
|
||||||
|
MSG_CHANGEINFO, // client -> server
|
||||||
|
MSG_READY_TO_ENTER, // server -> client
|
||||||
|
MSG_WEAPON_PICKUP,
|
||||||
|
MSG_SOUND_GLOBAL,
|
||||||
|
MSG_TUNE_PARAMS,
|
||||||
|
MSG_KILL,
|
||||||
|
MSG_EXTRA_PROJECTILE, // server -> client
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
object player_input
|
||||||
|
any left
|
||||||
|
any right
|
||||||
|
|
||||||
|
any target_x
|
||||||
|
any target_y
|
||||||
|
|
||||||
|
any jump
|
||||||
|
any fire
|
||||||
|
any hook
|
||||||
|
any blink
|
||||||
|
|
||||||
|
any player_state
|
||||||
|
|
||||||
|
any wanted_weapon
|
||||||
|
any next_weapon
|
||||||
|
any prev_weapon
|
||||||
|
end
|
||||||
|
|
||||||
|
object projectile
|
||||||
|
any x, y
|
||||||
|
any vx, vy
|
||||||
|
range(0, NUM_WEAPONS) type
|
||||||
|
range(0, max_int) start_tick
|
||||||
|
end
|
||||||
|
|
||||||
|
object laser
|
||||||
|
any x
|
||||||
|
any y
|
||||||
|
any from_x
|
||||||
|
any from_y
|
||||||
|
range(0, max_int) eval_tick
|
||||||
|
end
|
||||||
|
|
||||||
|
object powerup
|
||||||
|
any x, y
|
||||||
|
range(0, max_int) type
|
||||||
|
range(0, max_int) subtype
|
||||||
|
end
|
||||||
|
|
||||||
|
object flag
|
||||||
|
any x, y
|
||||||
|
range(0, 1) team
|
||||||
|
clientid carried_by
|
||||||
|
end
|
||||||
|
|
||||||
|
object game
|
||||||
|
range(0, max_int) round_start_tick
|
||||||
|
|
||||||
|
range(0, 1) game_over
|
||||||
|
range(0, 1) sudden_death
|
||||||
|
range(0, 1) paused
|
||||||
|
|
||||||
|
range(0, max_int) score_limit
|
||||||
|
range(0, max_int) time_limit
|
||||||
|
range(0, NUM_GAMETYPES-1) gametype
|
||||||
|
|
||||||
|
range(0, max_int) warmup
|
||||||
|
|
||||||
|
any teamscore_red
|
||||||
|
any teamscore_blue
|
||||||
|
end
|
||||||
|
|
||||||
|
// core object needed for physics
|
||||||
|
object player_core
|
||||||
|
any x, y
|
||||||
|
any vx, vy
|
||||||
|
|
||||||
|
any angle
|
||||||
|
range(0, 2) jumped
|
||||||
|
|
||||||
|
clientid hooked_player
|
||||||
|
range(0, 3) hook_state
|
||||||
|
range(0, max_int) hook_tick
|
||||||
|
|
||||||
|
any hook_x
|
||||||
|
any hook_y
|
||||||
|
any hook_dx
|
||||||
|
any hook_dy
|
||||||
|
end
|
||||||
|
|
||||||
|
// info about the player that is only needed when it's on screen
|
||||||
|
object player_character extends player_core
|
||||||
|
range(0, NUM_PLAYERSTATES-1) player_state
|
||||||
|
|
||||||
|
range(0, 10) health
|
||||||
|
range(0, 10) armor
|
||||||
|
range(0, 10) ammocount
|
||||||
|
range(0, 10) weaponstage
|
||||||
|
|
||||||
|
range(0, NUM_WEAPONS-1) weapon
|
||||||
|
range(0, NUM_EMOTES-1) emote
|
||||||
|
|
||||||
|
range(0, max_int) attacktick
|
||||||
|
end
|
||||||
|
|
||||||
|
// information about the player that is always needed
|
||||||
|
object player_info
|
||||||
|
range(0, 1) local
|
||||||
|
clientid cid
|
||||||
|
range(-1, 1) team
|
||||||
|
|
||||||
|
any score
|
||||||
|
|
||||||
|
any latency
|
||||||
|
any latency_flux
|
||||||
|
end
|
||||||
|
|
||||||
|
event common
|
||||||
|
any x, y
|
||||||
|
end
|
||||||
|
|
||||||
|
event explosion
|
||||||
|
any x, y
|
||||||
|
end
|
||||||
|
|
||||||
|
event spawn
|
||||||
|
any x, y
|
||||||
|
end
|
||||||
|
|
||||||
|
event death
|
||||||
|
any x, y
|
||||||
|
end
|
||||||
|
|
||||||
|
event air_jump
|
||||||
|
any x, y
|
||||||
|
end
|
||||||
|
|
||||||
|
event sound_global
|
||||||
|
any x, y
|
||||||
|
range(0, NUM_SOUNDS-1) soundid
|
||||||
|
end
|
||||||
|
|
||||||
|
event sound_world
|
||||||
|
any x, y
|
||||||
|
range(0, NUM_SOUNDS-1) soundid
|
||||||
|
end
|
||||||
|
|
||||||
|
event damageind
|
||||||
|
any x, y
|
||||||
|
any angle
|
||||||
|
end
|
||||||
|
|
||||||
|
//msg say
|
||||||
|
// clientid cid
|
||||||
|
// range(-1, 1) team
|
||||||
|
// string message
|
||||||
|
//end
|
|
@ -4,7 +4,10 @@
|
||||||
#ifndef GAME_PROTOCOL_H
|
#ifndef GAME_PROTOCOL_H
|
||||||
#define GAME_PROTOCOL_H
|
#define GAME_PROTOCOL_H
|
||||||
|
|
||||||
|
#include <game/generated/g_protocol.h>
|
||||||
|
|
||||||
// Network stuff
|
// Network stuff
|
||||||
|
/*
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
OBJTYPE_NULL=0,
|
OBJTYPE_NULL=0,
|
||||||
|
@ -209,6 +212,6 @@ struct obj_player_info
|
||||||
int score;
|
int score;
|
||||||
int latency;
|
int latency;
|
||||||
int latency_flux;
|
int latency_flux;
|
||||||
};
|
};*/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -204,7 +204,7 @@ public:
|
||||||
projectile(int type, int owner, vec2 pos, vec2 vel, int span, entity* powner,
|
projectile(int type, int owner, vec2 pos, vec2 vel, int span, entity* powner,
|
||||||
int damage, int flags, float force, int sound_impact, int weapon);
|
int damage, int flags, float force, int sound_impact, int weapon);
|
||||||
|
|
||||||
void fill_info(obj_projectile *proj);
|
void fill_info(NETOBJ_PROJECTILE *proj);
|
||||||
|
|
||||||
virtual void reset();
|
virtual void reset();
|
||||||
virtual void tick();
|
virtual void tick();
|
||||||
|
@ -270,12 +270,12 @@ public:
|
||||||
int color_feet;
|
int color_feet;
|
||||||
|
|
||||||
// these are non-heldback inputs
|
// these are non-heldback inputs
|
||||||
player_input latest_previnput;
|
NETOBJ_PLAYER_INPUT latest_previnput;
|
||||||
player_input latest_input;
|
NETOBJ_PLAYER_INPUT latest_input;
|
||||||
|
|
||||||
// input
|
// input
|
||||||
player_input previnput;
|
NETOBJ_PLAYER_INPUT previnput;
|
||||||
player_input input;
|
NETOBJ_PLAYER_INPUT input;
|
||||||
int num_inputs;
|
int num_inputs;
|
||||||
int jumped;
|
int jumped;
|
||||||
|
|
||||||
|
@ -332,7 +332,7 @@ public:
|
||||||
int handle_weapons();
|
int handle_weapons();
|
||||||
int handle_ninja();
|
int handle_ninja();
|
||||||
|
|
||||||
void on_direct_input(player_input *input);
|
void on_direct_input(NETOBJ_PLAYER_INPUT *input);
|
||||||
void fire_weapon();
|
void fire_weapon();
|
||||||
|
|
||||||
virtual void tick();
|
virtual void tick();
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include "gs_common.h"
|
#include "gs_common.h"
|
||||||
|
|
||||||
gameobject::gameobject()
|
gameobject::gameobject()
|
||||||
: entity(OBJTYPE_GAME)
|
: entity(NETOBJTYPE_GAME)
|
||||||
{
|
{
|
||||||
// select gametype
|
// select gametype
|
||||||
if(strcmp(config.sv_gametype, "ctf") == 0)
|
if(strcmp(config.sv_gametype, "ctf") == 0)
|
||||||
|
@ -260,7 +260,7 @@ void gameobject::tick()
|
||||||
|
|
||||||
void gameobject::snap(int snapping_client)
|
void gameobject::snap(int snapping_client)
|
||||||
{
|
{
|
||||||
obj_game *game = (obj_game *)snap_new_item(OBJTYPE_GAME, 0, sizeof(obj_game));
|
NETOBJ_GAME *game = (NETOBJ_GAME *)snap_new_item(NETOBJTYPE_GAME, 0, sizeof(NETOBJ_GAME));
|
||||||
game->paused = world->paused;
|
game->paused = world->paused;
|
||||||
game->game_over = game_over_tick==-1?0:1;
|
game->game_over = game_over_tick==-1?0:1;
|
||||||
game->sudden_death = sudden_death;
|
game->sudden_death = sudden_death;
|
||||||
|
@ -272,8 +272,8 @@ void gameobject::snap(int snapping_client)
|
||||||
|
|
||||||
game->warmup = warmup;
|
game->warmup = warmup;
|
||||||
|
|
||||||
game->teamscore[0] = teamscore[0];
|
game->teamscore_red = teamscore[0];
|
||||||
game->teamscore[1] = teamscore[1];
|
game->teamscore_blue = teamscore[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
int gameobject::getteam(int notthisid)
|
int gameobject::getteam(int notthisid)
|
||||||
|
|
|
@ -99,7 +99,7 @@ void gameobject_ctf::tick()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
player *close_players[MAX_CLIENTS];
|
player *close_players[MAX_CLIENTS];
|
||||||
int types[] = {OBJTYPE_PLAYER_CHARACTER};
|
int types[] = {NETOBJTYPE_PLAYER_CHARACTER};
|
||||||
int num = world->find_entities(f->pos, 32.0f, (entity**)close_players, MAX_CLIENTS, types, 1);
|
int num = world->find_entities(f->pos, 32.0f, (entity**)close_players, MAX_CLIENTS, types, 1);
|
||||||
for(int i = 0; i < num; i++)
|
for(int i = 0; i < num; i++)
|
||||||
{
|
{
|
||||||
|
@ -161,7 +161,7 @@ void gameobject_ctf::tick()
|
||||||
|
|
||||||
// Flag
|
// Flag
|
||||||
flag::flag(int _team)
|
flag::flag(int _team)
|
||||||
: entity(OBJTYPE_FLAG)
|
: entity(NETOBJTYPE_FLAG)
|
||||||
{
|
{
|
||||||
team = _team;
|
team = _team;
|
||||||
proximity_radius = phys_size;
|
proximity_radius = phys_size;
|
||||||
|
@ -183,7 +183,7 @@ void flag::reset()
|
||||||
|
|
||||||
void flag::snap(int snapping_client)
|
void flag::snap(int snapping_client)
|
||||||
{
|
{
|
||||||
obj_flag *flag = (obj_flag *)snap_new_item(OBJTYPE_FLAG, team, sizeof(obj_flag));
|
NETOBJ_FLAG *flag = (NETOBJ_FLAG *)snap_new_item(NETOBJTYPE_FLAG, team, sizeof(NETOBJ_FLAG));
|
||||||
flag->x = (int)pos.x;
|
flag->x = (int)pos.x;
|
||||||
flag->y = (int)pos.y;
|
flag->y = (int)pos.y;
|
||||||
flag->team = team;
|
flag->team = team;
|
||||||
|
|
|
@ -107,7 +107,7 @@ void event_handler::snap(int snapping_client)
|
||||||
{
|
{
|
||||||
if(cmask_is_set(client_masks[i], snapping_client))
|
if(cmask_is_set(client_masks[i], snapping_client))
|
||||||
{
|
{
|
||||||
ev_common *ev = (ev_common *)&data[offsets[i]];
|
NETEVENT_COMMON *ev = (NETEVENT_COMMON *)&data[offsets[i]];
|
||||||
if(distance(players[snapping_client].pos, vec2(ev->x, ev->y)) < 1500.0f)
|
if(distance(players[snapping_client].pos, vec2(ev->x, ev->y)) < 1500.0f)
|
||||||
{
|
{
|
||||||
void *d = snap_new_item(types[i], i, sizes[i]);
|
void *d = snap_new_item(types[i], i, sizes[i]);
|
||||||
|
@ -297,6 +297,7 @@ void game_world::tick()
|
||||||
|
|
||||||
if(!paused)
|
if(!paused)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
static PERFORMACE_INFO scopes[OBJTYPE_FLAG+1] =
|
static PERFORMACE_INFO scopes[OBJTYPE_FLAG+1] =
|
||||||
{
|
{
|
||||||
{"null", 0},
|
{"null", 0},
|
||||||
|
@ -320,31 +321,32 @@ void game_world::tick()
|
||||||
};
|
};
|
||||||
|
|
||||||
static PERFORMACE_INFO tick_scope = {"tick", 0};
|
static PERFORMACE_INFO tick_scope = {"tick", 0};
|
||||||
perf_start(&tick_scope);
|
perf_start(&tick_scope);*/
|
||||||
|
|
||||||
// update all objects
|
// update all objects
|
||||||
for(entity *ent = first_entity; ent; ent = ent->next_entity)
|
for(entity *ent = first_entity; ent; ent = ent->next_entity)
|
||||||
{
|
{
|
||||||
if(ent->objtype >= 0 && ent->objtype < OBJTYPE_FLAG)
|
/*if(ent->objtype >= 0 && ent->objtype < OBJTYPE_FLAG)
|
||||||
perf_start(&scopes[ent->objtype]);
|
perf_start(&scopes[ent->objtype]);*/
|
||||||
ent->tick();
|
ent->tick();
|
||||||
if(ent->objtype >= 0 && ent->objtype < OBJTYPE_FLAG)
|
/*if(ent->objtype >= 0 && ent->objtype < OBJTYPE_FLAG)
|
||||||
perf_end();
|
perf_end();*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
perf_end();
|
perf_end();
|
||||||
|
|
||||||
static PERFORMACE_INFO deftick_scope = {"tick_defered", 0};
|
static PERFORMACE_INFO deftick_scope = {"tick_defered", 0};
|
||||||
perf_start(&deftick_scope);
|
perf_start(&deftick_scope);*/
|
||||||
for(entity *ent = first_entity; ent; ent = ent->next_entity)
|
for(entity *ent = first_entity; ent; ent = ent->next_entity)
|
||||||
{
|
{
|
||||||
if(ent->objtype >= 0 && ent->objtype < OBJTYPE_FLAG)
|
/*if(ent->objtype >= 0 && ent->objtype < OBJTYPE_FLAG)
|
||||||
perf_start(&scopes_def[ent->objtype]);
|
perf_start(&scopes_def[ent->objtype]);*/
|
||||||
ent->tick_defered();
|
ent->tick_defered();
|
||||||
if(ent->objtype >= 0 && ent->objtype < OBJTYPE_FLAG)
|
/*if(ent->objtype >= 0 && ent->objtype < OBJTYPE_FLAG)
|
||||||
perf_end();
|
perf_end();*/
|
||||||
}
|
}
|
||||||
perf_end();
|
/*perf_end();*/
|
||||||
}
|
}
|
||||||
|
|
||||||
remove_entities();
|
remove_entities();
|
||||||
|
@ -380,7 +382,7 @@ static input_count count_input(int prev, int cur)
|
||||||
//////////////////////////////////////////////////
|
//////////////////////////////////////////////////
|
||||||
projectile::projectile(int type, int owner, vec2 pos, vec2 vel, int span, entity* powner,
|
projectile::projectile(int type, int owner, vec2 pos, vec2 vel, int span, entity* powner,
|
||||||
int damage, int flags, float force, int sound_impact, int weapon)
|
int damage, int flags, float force, int sound_impact, int weapon)
|
||||||
: entity(OBJTYPE_PROJECTILE)
|
: entity(NETOBJTYPE_PROJECTILE)
|
||||||
{
|
{
|
||||||
this->type = type;
|
this->type = type;
|
||||||
this->pos = pos;
|
this->pos = pos;
|
||||||
|
@ -437,7 +439,7 @@ void projectile::tick()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void projectile::fill_info(obj_projectile *proj)
|
void projectile::fill_info(NETOBJ_PROJECTILE *proj)
|
||||||
{
|
{
|
||||||
proj->x = (int)pos.x;
|
proj->x = (int)pos.x;
|
||||||
proj->y = (int)pos.y;
|
proj->y = (int)pos.y;
|
||||||
|
@ -455,7 +457,7 @@ void projectile::snap(int snapping_client)
|
||||||
if(distance(players[snapping_client].pos, curpos) > 1000.0f)
|
if(distance(players[snapping_client].pos, curpos) > 1000.0f)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
obj_projectile *proj = (obj_projectile *)snap_new_item(OBJTYPE_PROJECTILE, id, sizeof(obj_projectile));
|
NETOBJ_PROJECTILE *proj = (NETOBJ_PROJECTILE *)snap_new_item(NETOBJTYPE_PROJECTILE, id, sizeof(NETOBJ_PROJECTILE));
|
||||||
fill_info(proj);
|
fill_info(proj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,7 +466,7 @@ void projectile::snap(int snapping_client)
|
||||||
// laser
|
// laser
|
||||||
//////////////////////////////////////////////////
|
//////////////////////////////////////////////////
|
||||||
laser::laser(vec2 pos, vec2 direction, float start_energy, player *owner)
|
laser::laser(vec2 pos, vec2 direction, float start_energy, player *owner)
|
||||||
: entity(OBJTYPE_LASER)
|
: entity(NETOBJTYPE_LASER)
|
||||||
{
|
{
|
||||||
this->pos = pos;
|
this->pos = pos;
|
||||||
this->owner = owner;
|
this->owner = owner;
|
||||||
|
@ -554,7 +556,7 @@ void laser::snap(int snapping_client)
|
||||||
if(distance(players[snapping_client].pos, pos) > 1000.0f)
|
if(distance(players[snapping_client].pos, pos) > 1000.0f)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
obj_laser *obj = (obj_laser *)snap_new_item(OBJTYPE_LASER, id, sizeof(obj_laser));
|
NETOBJ_LASER *obj = (NETOBJ_LASER *)snap_new_item(NETOBJTYPE_LASER, id, sizeof(NETOBJ_LASER));
|
||||||
obj->x = (int)pos.x;
|
obj->x = (int)pos.x;
|
||||||
obj->y = (int)pos.y;
|
obj->y = (int)pos.y;
|
||||||
obj->from_x = (int)from.x;
|
obj->from_x = (int)from.x;
|
||||||
|
@ -568,7 +570,7 @@ void laser::snap(int snapping_client)
|
||||||
//////////////////////////////////////////////////
|
//////////////////////////////////////////////////
|
||||||
// TODO: move to separate file
|
// TODO: move to separate file
|
||||||
player::player()
|
player::player()
|
||||||
: entity(OBJTYPE_PLAYER_CHARACTER)
|
: entity(NETOBJTYPE_PLAYER_CHARACTER)
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
@ -788,7 +790,7 @@ void player::try_respawn()
|
||||||
|
|
||||||
// check if the position is occupado
|
// check if the position is occupado
|
||||||
entity *ents[2] = {0};
|
entity *ents[2] = {0};
|
||||||
int types[] = {OBJTYPE_PLAYER_CHARACTER};
|
int types[] = {NETOBJTYPE_PLAYER_CHARACTER};
|
||||||
int num_ents = world->find_entities(spawnpos, 64, ents, 2, types, 1);
|
int num_ents = world->find_entities(spawnpos, 64, ents, 2, types, 1);
|
||||||
for(int i = 0; i < num_ents; i++)
|
for(int i = 0; i < num_ents; i++)
|
||||||
{
|
{
|
||||||
|
@ -901,12 +903,12 @@ int player::handle_ninja()
|
||||||
core.vel = vec2(0.0f,0.0f);
|
core.vel = vec2(0.0f,0.0f);
|
||||||
if ((ninja.currentmovetime % 2) == 0)
|
if ((ninja.currentmovetime % 2) == 0)
|
||||||
{
|
{
|
||||||
create_smoke(pos);
|
//create_smoke(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if we hit anything along the way
|
// check if we hit anything along the way
|
||||||
{
|
{
|
||||||
int type = OBJTYPE_PLAYER_CHARACTER;
|
int type = NETOBJTYPE_PLAYER_CHARACTER;
|
||||||
entity *ents[64];
|
entity *ents[64];
|
||||||
vec2 dir = pos - oldpos;
|
vec2 dir = pos - oldpos;
|
||||||
float radius = phys_size * 2.0f; //length(dir * 0.5f);
|
float radius = phys_size * 2.0f; //length(dir * 0.5f);
|
||||||
|
@ -990,12 +992,12 @@ void player::fire_weapon()
|
||||||
1, 0, 0, -1, WEAPON_GUN);
|
1, 0, 0, -1, WEAPON_GUN);
|
||||||
|
|
||||||
// pack the projectile and send it to the client directly
|
// pack the projectile and send it to the client directly
|
||||||
obj_projectile p;
|
NETOBJ_PROJECTILE p;
|
||||||
proj->fill_info(&p);
|
proj->fill_info(&p);
|
||||||
|
|
||||||
msg_pack_start(MSG_EXTRA_PROJECTILE, 0);
|
msg_pack_start(MSG_EXTRA_PROJECTILE, 0);
|
||||||
msg_pack_int(1);
|
msg_pack_int(1);
|
||||||
for(unsigned i = 0; i < sizeof(obj_projectile)/sizeof(int); i++)
|
for(unsigned i = 0; i < sizeof(NETOBJ_PROJECTILE)/sizeof(int); i++)
|
||||||
msg_pack_int(((int *)&p)[i]);
|
msg_pack_int(((int *)&p)[i]);
|
||||||
msg_pack_end();
|
msg_pack_end();
|
||||||
server_send_msg(client_id);
|
server_send_msg(client_id);
|
||||||
|
@ -1014,12 +1016,12 @@ void player::fire_weapon()
|
||||||
1, projectile::PROJECTILE_FLAGS_EXPLODE, 0, SOUND_GRENADE_EXPLODE, WEAPON_GRENADE);
|
1, projectile::PROJECTILE_FLAGS_EXPLODE, 0, SOUND_GRENADE_EXPLODE, WEAPON_GRENADE);
|
||||||
|
|
||||||
// pack the projectile and send it to the client directly
|
// pack the projectile and send it to the client directly
|
||||||
obj_projectile p;
|
NETOBJ_PROJECTILE p;
|
||||||
proj->fill_info(&p);
|
proj->fill_info(&p);
|
||||||
|
|
||||||
msg_pack_start(MSG_EXTRA_PROJECTILE, 0);
|
msg_pack_start(MSG_EXTRA_PROJECTILE, 0);
|
||||||
msg_pack_int(1);
|
msg_pack_int(1);
|
||||||
for(unsigned i = 0; i < sizeof(obj_projectile)/sizeof(int); i++)
|
for(unsigned i = 0; i < sizeof(NETOBJ_PROJECTILE)/sizeof(int); i++)
|
||||||
msg_pack_int(((int *)&p)[i]);
|
msg_pack_int(((int *)&p)[i]);
|
||||||
msg_pack_end();
|
msg_pack_end();
|
||||||
server_send_msg(client_id);
|
server_send_msg(client_id);
|
||||||
|
@ -1050,10 +1052,10 @@ void player::fire_weapon()
|
||||||
1, 0, 0, -1, WEAPON_SHOTGUN);
|
1, 0, 0, -1, WEAPON_SHOTGUN);
|
||||||
|
|
||||||
// pack the projectile and send it to the client directly
|
// pack the projectile and send it to the client directly
|
||||||
obj_projectile p;
|
NETOBJ_PROJECTILE p;
|
||||||
proj->fill_info(&p);
|
proj->fill_info(&p);
|
||||||
|
|
||||||
for(unsigned i = 0; i < sizeof(obj_projectile)/sizeof(int); i++)
|
for(unsigned i = 0; i < sizeof(NETOBJ_PROJECTILE)/sizeof(int); i++)
|
||||||
msg_pack_int(((int *)&p)[i]);
|
msg_pack_int(((int *)&p)[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1245,7 +1247,7 @@ int player::handle_weapons()
|
||||||
// only one that needs update (for now)
|
// only one that needs update (for now)
|
||||||
// do selection for the weapon and bash anything in it
|
// do selection for the weapon and bash anything in it
|
||||||
// check if we hit anything along the way
|
// check if we hit anything along the way
|
||||||
int type = OBJTYPE_PLAYER_CHARACTER;
|
int type = NETOBJTYPE_PLAYER_CHARACTER;
|
||||||
entity *ents[64];
|
entity *ents[64];
|
||||||
vec2 lookdir(direction.x > 0.0f ? 1.0f : -1.0f, 0.0f);
|
vec2 lookdir(direction.x > 0.0f ? 1.0f : -1.0f, 0.0f);
|
||||||
vec2 dir = lookdir * data->weapons[active_weapon].meleereach;
|
vec2 dir = lookdir * data->weapons[active_weapon].meleereach;
|
||||||
|
@ -1278,7 +1280,7 @@ int player::handle_weapons()
|
||||||
vec2 fdir = normalize(ents[i]->pos- pos);
|
vec2 fdir = normalize(ents[i]->pos- pos);
|
||||||
|
|
||||||
// set his velocity to fast upward (for now)
|
// set his velocity to fast upward (for now)
|
||||||
create_smoke(ents[i]->pos);
|
//create_smoke(ents[i]->pos);
|
||||||
create_sound(pos, SOUND_HAMMER_HIT);
|
create_sound(pos, SOUND_HAMMER_HIT);
|
||||||
if(numobjectshit < 10)
|
if(numobjectshit < 10)
|
||||||
hitobjects[numobjectshit++] = ents[i];
|
hitobjects[numobjectshit++] = ents[i];
|
||||||
|
@ -1318,7 +1320,7 @@ int player::handle_weapons()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void player::on_direct_input(player_input *new_input)
|
void player::on_direct_input(NETOBJ_PLAYER_INPUT *new_input)
|
||||||
{
|
{
|
||||||
mem_copy(&latest_previnput, &latest_input, sizeof(latest_input));
|
mem_copy(&latest_previnput, &latest_input, sizeof(latest_input));
|
||||||
mem_copy(&latest_input, new_input, sizeof(latest_input));
|
mem_copy(&latest_input, new_input, sizeof(latest_input));
|
||||||
|
@ -1444,7 +1446,7 @@ void player::tick_defered()
|
||||||
if(events&COREEVENT_AIR_JUMP)
|
if(events&COREEVENT_AIR_JUMP)
|
||||||
{
|
{
|
||||||
create_sound(pos, SOUND_PLAYER_AIRJUMP, mask);
|
create_sound(pos, SOUND_PLAYER_AIRJUMP, mask);
|
||||||
ev_common *c = (ev_common *)::events.create(EVENT_AIR_JUMP, sizeof(ev_common), mask);
|
NETEVENT_COMMON *c = (NETEVENT_COMMON *)::events.create(NETEVENTTYPE_AIR_JUMP, sizeof(NETEVENT_COMMON), mask);
|
||||||
if(c)
|
if(c)
|
||||||
{
|
{
|
||||||
c->x = (int)pos.x;
|
c->x = (int)pos.x;
|
||||||
|
@ -1580,12 +1582,12 @@ void player::snap(int snaping_client)
|
||||||
{
|
{
|
||||||
if(1)
|
if(1)
|
||||||
{
|
{
|
||||||
obj_player_info *info = (obj_player_info *)snap_new_item(OBJTYPE_PLAYER_INFO, client_id, sizeof(obj_player_info));
|
NETOBJ_PLAYER_INFO *info = (NETOBJ_PLAYER_INFO *)snap_new_item(NETOBJTYPE_PLAYER_INFO, client_id, sizeof(NETOBJ_PLAYER_INFO));
|
||||||
|
|
||||||
info->latency = latency_min;
|
info->latency = latency_min;
|
||||||
info->latency_flux = latency_max-latency_min;
|
info->latency_flux = latency_max-latency_min;
|
||||||
info->local = 0;
|
info->local = 0;
|
||||||
info->clientid = client_id;
|
info->cid = client_id;
|
||||||
info->score = score;
|
info->score = score;
|
||||||
info->team = team;
|
info->team = team;
|
||||||
|
|
||||||
|
@ -1595,7 +1597,7 @@ void player::snap(int snaping_client)
|
||||||
|
|
||||||
if(health > 0 && team >= 0 && distance(players[snaping_client].pos, pos) < 1000.0f)
|
if(health > 0 && team >= 0 && distance(players[snaping_client].pos, pos) < 1000.0f)
|
||||||
{
|
{
|
||||||
obj_player_character *character = (obj_player_character *)snap_new_item(OBJTYPE_PLAYER_CHARACTER, client_id, sizeof(obj_player_character));
|
NETOBJ_PLAYER_CHARACTER *character = (NETOBJ_PLAYER_CHARACTER *)snap_new_item(NETOBJTYPE_PLAYER_CHARACTER, client_id, sizeof(NETOBJ_PLAYER_CHARACTER));
|
||||||
|
|
||||||
core.write(character);
|
core.write(character);
|
||||||
|
|
||||||
|
@ -1651,7 +1653,7 @@ player *players;
|
||||||
// powerup
|
// powerup
|
||||||
//////////////////////////////////////////////////
|
//////////////////////////////////////////////////
|
||||||
powerup::powerup(int _type, int _subtype)
|
powerup::powerup(int _type, int _subtype)
|
||||||
: entity(OBJTYPE_POWERUP)
|
: entity(NETOBJTYPE_POWERUP)
|
||||||
{
|
{
|
||||||
type = _type;
|
type = _type;
|
||||||
subtype = _subtype;
|
subtype = _subtype;
|
||||||
|
@ -1747,7 +1749,7 @@ void powerup::tick()
|
||||||
|
|
||||||
// loop through all players, setting their emotes
|
// loop through all players, setting their emotes
|
||||||
entity *ents[64];
|
entity *ents[64];
|
||||||
const int types[] = {OBJTYPE_PLAYER_CHARACTER};
|
const int types[] = {NETOBJTYPE_PLAYER_CHARACTER};
|
||||||
int num = world->find_entities(vec2(0, 0), 1000000, ents, 64, types, 1);
|
int num = world->find_entities(vec2(0, 0), 1000000, ents, 64, types, 1);
|
||||||
for (int i = 0; i < num; i++)
|
for (int i = 0; i < num; i++)
|
||||||
{
|
{
|
||||||
|
@ -1782,7 +1784,7 @@ void powerup::snap(int snapping_client)
|
||||||
if(spawntick != -1)
|
if(spawntick != -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
obj_powerup *up = (obj_powerup *)snap_new_item(OBJTYPE_POWERUP, id, sizeof(obj_powerup));
|
NETOBJ_POWERUP *up = (NETOBJ_POWERUP *)snap_new_item(NETOBJTYPE_POWERUP, id, sizeof(NETOBJ_POWERUP));
|
||||||
up->x = (int)pos.x;
|
up->x = (int)pos.x;
|
||||||
up->y = (int)pos.y;
|
up->y = (int)pos.y;
|
||||||
up->type = type; // TODO: two diffrent types? what gives?
|
up->type = type; // TODO: two diffrent types? what gives?
|
||||||
|
@ -1805,7 +1807,7 @@ void create_damageind(vec2 p, float angle, int amount)
|
||||||
for(int i = 0; i < amount; i++)
|
for(int i = 0; i < amount; i++)
|
||||||
{
|
{
|
||||||
float f = mix(s, e, float(i+1)/float(amount+2));
|
float f = mix(s, e, float(i+1)/float(amount+2));
|
||||||
ev_damageind *ev = (ev_damageind *)events.create(EVENT_DAMAGEINDICATION, sizeof(ev_damageind));
|
NETEVENT_DAMAGEIND *ev = (NETEVENT_DAMAGEIND *)events.create(NETEVENTTYPE_DAMAGEIND, sizeof(NETEVENT_DAMAGEIND));
|
||||||
if(ev)
|
if(ev)
|
||||||
{
|
{
|
||||||
ev->x = (int)p.x;
|
ev->x = (int)p.x;
|
||||||
|
@ -1818,7 +1820,7 @@ void create_damageind(vec2 p, float angle, int amount)
|
||||||
void create_explosion(vec2 p, int owner, int weapon, bool bnodamage)
|
void create_explosion(vec2 p, int owner, int weapon, bool bnodamage)
|
||||||
{
|
{
|
||||||
// create the event
|
// create the event
|
||||||
ev_explosion *ev = (ev_explosion *)events.create(EVENT_EXPLOSION, sizeof(ev_explosion));
|
NETEVENT_EXPLOSION *ev = (NETEVENT_EXPLOSION *)events.create(NETEVENTTYPE_EXPLOSION, sizeof(NETEVENT_EXPLOSION));
|
||||||
if(ev)
|
if(ev)
|
||||||
{
|
{
|
||||||
ev->x = (int)p.x;
|
ev->x = (int)p.x;
|
||||||
|
@ -1848,21 +1850,22 @@ void create_explosion(vec2 p, int owner, int weapon, bool bnodamage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
void create_smoke(vec2 p)
|
void create_smoke(vec2 p)
|
||||||
{
|
{
|
||||||
// create the event
|
// create the event
|
||||||
ev_explosion *ev = (ev_explosion *)events.create(EVENT_SMOKE, sizeof(ev_explosion));
|
EV_EXPLOSION *ev = (EV_EXPLOSION *)events.create(EVENT_SMOKE, sizeof(EV_EXPLOSION));
|
||||||
if(ev)
|
if(ev)
|
||||||
{
|
{
|
||||||
ev->x = (int)p.x;
|
ev->x = (int)p.x;
|
||||||
ev->y = (int)p.y;
|
ev->y = (int)p.y;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
void create_playerspawn(vec2 p)
|
void create_playerspawn(vec2 p)
|
||||||
{
|
{
|
||||||
// create the event
|
// create the event
|
||||||
ev_spawn *ev = (ev_spawn *)events.create(EVENT_PLAYERSPAWN, sizeof(ev_spawn));
|
NETEVENT_SPAWN *ev = (NETEVENT_SPAWN *)events.create(NETEVENTTYPE_SPAWN, sizeof(NETEVENT_SPAWN));
|
||||||
if(ev)
|
if(ev)
|
||||||
{
|
{
|
||||||
ev->x = (int)p.x;
|
ev->x = (int)p.x;
|
||||||
|
@ -1873,7 +1876,7 @@ void create_playerspawn(vec2 p)
|
||||||
void create_death(vec2 p)
|
void create_death(vec2 p)
|
||||||
{
|
{
|
||||||
// create the event
|
// create the event
|
||||||
ev_death *ev = (ev_death *)events.create(EVENT_DEATH, sizeof(ev_death));
|
NETEVENT_DEATH *ev = (NETEVENT_DEATH *)events.create(NETEVENTTYPE_DEATH, sizeof(NETEVENT_DEATH));
|
||||||
if(ev)
|
if(ev)
|
||||||
{
|
{
|
||||||
ev->x = (int)p.x;
|
ev->x = (int)p.x;
|
||||||
|
@ -1887,12 +1890,12 @@ void create_sound(vec2 pos, int sound, int mask)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// create a sound
|
// create a sound
|
||||||
ev_sound *ev = (ev_sound *)events.create(EVENT_SOUND_WORLD, sizeof(ev_sound), mask);
|
NETEVENT_SOUND_WORLD *ev = (NETEVENT_SOUND_WORLD *)events.create(NETEVENTTYPE_SOUND_WORLD, sizeof(NETEVENT_SOUND_WORLD), mask);
|
||||||
if(ev)
|
if(ev)
|
||||||
{
|
{
|
||||||
ev->x = (int)pos.x;
|
ev->x = (int)pos.x;
|
||||||
ev->y = (int)pos.y;
|
ev->y = (int)pos.y;
|
||||||
ev->sound = sound;
|
ev->soundid = sound;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2043,7 +2046,7 @@ void mods_snap(int client_id)
|
||||||
void mods_client_direct_input(int client_id, void *input)
|
void mods_client_direct_input(int client_id, void *input)
|
||||||
{
|
{
|
||||||
if(!world->paused)
|
if(!world->paused)
|
||||||
players[client_id].on_direct_input((player_input *)input);
|
players[client_id].on_direct_input((NETOBJ_PLAYER_INPUT *)input);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if(i->fire)
|
if(i->fire)
|
||||||
|
@ -2058,11 +2061,11 @@ void mods_client_predicted_input(int client_id, void *input)
|
||||||
{
|
{
|
||||||
if(!world->paused)
|
if(!world->paused)
|
||||||
{
|
{
|
||||||
if (memcmp(&players[client_id].input, input, sizeof(player_input)) != 0)
|
if (memcmp(&players[client_id].input, input, sizeof(NETOBJ_PLAYER_INPUT)) != 0)
|
||||||
players[client_id].last_action = server_tick();
|
players[client_id].last_action = server_tick();
|
||||||
|
|
||||||
//players[client_id].previnput = players[client_id].input;
|
//players[client_id].previnput = players[client_id].input;
|
||||||
players[client_id].input = *(player_input*)input;
|
players[client_id].input = *(NETOBJ_PLAYER_INPUT*)input;
|
||||||
players[client_id].num_inputs++;
|
players[client_id].num_inputs++;
|
||||||
|
|
||||||
if(players[client_id].input.target_x == 0 && players[client_id].input.target_y == 0)
|
if(players[client_id].input.target_x == 0 && players[client_id].input.target_y == 0)
|
||||||
|
|
36
src/tools/packetgen.c
Normal file
36
src/tools/packetgen.c
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||||
|
#include <engine/e_system.h>
|
||||||
|
|
||||||
|
enum { NUM_SOCKETS = 64 };
|
||||||
|
|
||||||
|
int run(NETADDR4 dest)
|
||||||
|
{
|
||||||
|
NETSOCKET sockets[NUM_SOCKETS];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < NUM_SOCKETS; i++)
|
||||||
|
{
|
||||||
|
NETADDR4 bindaddr = {{0,0,0,0}, 0};
|
||||||
|
sockets[i] = net_udp4_create(bindaddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
unsigned char data[1024];
|
||||||
|
int size = 0;
|
||||||
|
int socket_to_use = 0;
|
||||||
|
io_read(io_stdin(), &size, 2);
|
||||||
|
io_read(io_stdin(), &socket_to_use, 1);
|
||||||
|
size %= 256;
|
||||||
|
socket_to_use %= NUM_SOCKETS;
|
||||||
|
io_read(io_stdin(), data, size);
|
||||||
|
net_udp4_send(sockets[socket_to_use], &dest, data, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
NETADDR4 dest = {{127,0,0,1},8303};
|
||||||
|
run(dest);
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in a new issue