Compare commits

...

2 Commits

Author SHA1 Message Date
Pascal Abresch f76f59015d adjust run script 2024-02-25 13:28:01 +01:00
Pascal Abresch 0d1b808848 Add new network encoded/decoder 2024-02-25 13:27:44 +01:00
3 changed files with 162 additions and 3 deletions

View File

@ -5,7 +5,10 @@ end
function love.load(args)
if args[1] == "--server" then
if args[1] == "--nwTest" then
local format = require("shared.networkFormat")
format.testEncoder()
elseif args[1] == "--server" then
if not args[2]then
print("Missing server adress!")
love.event.quit()

6
run
View File

@ -1,11 +1,13 @@
#!/bin/sh
#adjust the next line... not sure how to figure this out from a shellscript, sorry :)
cd ~/proj/poppy
# This mechanism is fairly unreliable, but it is the only "okay" way currently :/
# realpath is also not part of any POSIX standard
cd $(dirname $(realpath "$0"))
if test $? -eq 1; then
alert --stop "cant figure out where this script is" "Ill adjust it!"
exit
fi
uname=`uname -o`
if test "$uname" = "Haiku"
then

154
shared/networkFormat.lua Normal file
View File

@ -0,0 +1,154 @@
table.unpack = table.unpack or unpack
string.pack = string.pack or function(...) return love.data.pack("string", ...) end
string.unpack = string.unpack or love.data.unpack
string.packsize = string.packsize or love.data.getPackedSize
-- Lua data types: nil, boolean, number, string, function, userdata, thread, and table.
-- Not representable here: function, userdata, thread.
format = {
--[[ Poppy specific
0x81 = "remoteCall",
-- lua specific
0x02 = "shortString",
0x03 = "longString",
0x04 = "nil",
0x05 = "true",
0x06 = "false",
0x07 = "number",
-- love2d/poppy specific
0x48 = "colorAlpha",
0x49 = "color"]]--
}
format.decoder = function(encoded)
local index = 1
local DecoderType, index = string.unpack("<I1", encoded, index)
assert(DecoderType == 0x81)
local nameLength, index = string.unpack("<I1", encoded, index)
local name, index = string.unpack("<c".. nameLength, encoded, index)
local argNumber, index = string.unpack("<I1", encoded, index)
local arguments = {}
for i = 1, argNumber do
local argtype = ""
argType, index = string.unpack("<I1", encoded, index)
if argType == 0x02 then
local stringLength, nwString
stringLength, index = string.unpack("<I1", encoded, index)
nwString, index = string.unpack("<c"..stringLength, encoded, index)
arguments[i] = nwString
elseif argType == 0x03 then
local stringLength, nwString
stringLength, index = string.unpack("<I2", encoded, index)
nwString, index = string.unpack("<c"..stringLength, encoded, index)
arguments[i] = string
elseif argType == 0x04 then
arguments[i] = nil
elseif argType == 0x05 then
arguments[i] = true
elseif argType == 0x06 then
arguments[i] = false
elseif argType == 0x07 then
local number
number, index = string.unpack("<n", encoded, index)
arguments[i] = number
elseif argType == 0x48 then
local color = {}
color[1], color[2], color[3], color[4], index = string.unpack("<ffff", encoded, index)
arguments[i] = color
elseif argType == 0x49 then
local color = {}
color[1], color[2], color[3], index = string.unpack("<fff", encoded, index)
arguments[i] = color
else
error("failed to decode argument " .. i .. " index is at " ..index.. " len is " .. encoded:len() .. "value is " .. argType)
end
end
return name, arguments
end
format.encoder = function(name, ...)
assert(name)
-- Format
-- byte1 0x81 to indicate a function
-- byte2 length of the name of the function
-- byte3-byteN name of the function
-- byteN+1 number of arguments to the function
-- byteN+2 type of argument
-- byteN+3-byteM argument specific syntax
-- byteM+1 type of next argument
-- and so on
local encoded = "\x81"
encoded = encoded .. string.pack("<I1", name:len())
encoded = encoded .. name .. string.pack("<I1", select("#", ...))
-- can't use ipairs, it does stop on nil
-- can't use pairs, it ignores nil :D
local args = { ... }
for i=1, select("#", ...) do
local value = args[i]
if type(value) == "function" or type(value) == "CFunction" or type(value) == "userdata"
or type(value) == "thread" then
error("unencodeable data passed! of type: " .. type(value))
elseif type(value) == "nil" then
encoded = encoded .. "\x04"
elseif type(value) == "boolean" then
if value then
encoded = encoded .. "\x05"
else
encoded = encoded .. "\x06"
end
elseif type(value) == "string" then
if value:len() > 255 then
encoded = encoded .. "\x03" .. string.pack("<I2", value:len()) .. value
else
encoded = encoded .. "\x02" .. string.pack("<I1", value:len()) .. value
end
elseif type(value) == "number" then
encoded = encoded .. "\x07" .. string.pack("<n", value)
elseif type(value) == "table" then
if value.nwType == "color" and #value == 3 then
encoded = encoded .. "\x49" .. string.pack("<fff", value[1], value[2], value[3])
elseif value.nwType == "color" and #value == 4 then
encoded = encoded .. "\x48" ..
string.pack("<ffff", value[1], value[2], value[3], value[4])
else
error("Got table but don't know how to encode it")
end
else
error("unimplemented type for encoding!")
end
end
return encoded
end
function format.testEncoder()
local testCases = {
Jeremeeeey = { true, true, nil, false, 69, "Jeremy stop that >:(" },
buildBlocks = { 32, 32, 64, 64, "longHashValueISwear" },
colorWorld = { {nwType = "color", 0.4, 0.4, 0.4 }, {nwType = "color", 0.4, 0.4, 0.4, 0.5}},
slangvariants = { "oy mate", "how ya doing", "sup brooo", "heya", "hey there ma dude" }
}
print("Running encoder tests...")
for name, value in pairs(testCases) do
local encoded = format.encoder(name, table.unpack(value))
local name, decodedArgs = format.decoder(encoded)
local sucess = true
for iter= 1, #value do
local var = value[iter]
if var ~= decodedArgs[iter] and not type(var) == table then
sucess = false
end
end
if sucess then
print(name .. " suceeded!")
else
print(name .. " failed.")
end
end
end
return format