Skip to content
Snippets Groups Projects
Commit f5a920f0 authored by dg's avatar dg
Browse files

moar

git-svn-id: http://svn.net-core.org/repos/t-engine4@2760 51575b47-30f0-44d4-a5cc-537603b46e54
parent b7a6dcd2
No related branches found
No related tags found
No related merge requests found
......@@ -232,7 +232,10 @@ function _M:instanciate(mod, name, new_game, no_reboot)
table.sort(md5s)
local fmd5 = md5.sumhexa(table.concat(md5s))
print("[MODULE LOADER] module MD5", fmd5, "computed in ", core.game.getTime() - t)
local hash_valid, hash_err = profile:checkModuleHash(mod.version_name, fmd5)
local hash_valid, hash_err
if mod.short_name ~= "boot" then
hash_valid, hash_err = profile:checkModuleHash(mod.version_name, fmd5)
end
-- If bad hash, switch to dev profile
if not hash_valid and not profile.auth then
......@@ -272,7 +275,7 @@ function _M:instanciate(mod, name, new_game, no_reboot)
-- Disable the profile if ungood
if mod.short_name ~= "boot" then
if not hash_valid then
game.log("#LIGHT_RED#Profile disabled(switching to development profile) due to %s.", hash_err)
game.log("#LIGHT_RED#Profile disabled(switching to development profile) due to %s.", hash_err or "???")
end
end
end
......
......@@ -84,8 +84,6 @@ function _M:init(name)
self.login = self.generic.online.login
self.pass = self.generic.online.pass
self:tryAuth()
self:getConfigs("generic")
self:syncOnline("generic")
end
end
......@@ -192,15 +190,24 @@ function _M:saveModuleProfile(name, data, module, nosync)
if not nosync then self:setConfigs(module, name, data) end
end
function _M:checkFirstRun()
local result = self.generic.firstrun
if not result then
firstrun = { When=os.time() }
self:saveGenericProfile("firstrun", firstrun, false)
end
return result
end
-----------------------------------------------------------------------
-- Events
-----------------------------------------------------------------------
function _M:eventAuth(e)
if e.ok then
print("===", e.ok)
self.auth = e.ok:unserialize()
print("[PROFILE] Main thread got authed", self.auth.name, self.auth.email, self.auth.drupid)
self:getConfigs("generic", function(e) self:syncOnline(e.module) end)
end
end
......@@ -211,6 +218,33 @@ function _M:eventGetNews(e)
end
end
function _M:eventGetConfigs(e)
local data = e.data:unserialize()
local module = e.module
if not data then print("[ONLINE PROFILE] get configs") return end
for name, val in pairs(data) do
print("[ONLINE PROFILE] config ", name)
local field = name
local f, err = loadstring(val)
if not f and err then
print("Error loading profile config: ", err)
else
if module == "generic" then
self.generic[field] = self.generic[field] or {}
self:loadData(f, self.generic[field])
self:saveGenericProfile(field, self.generic[field], true)
else
self.modules[module] = self.modules[module] or {}
self.modules[module][field] = self.modules[module][field] or {}
self:loadData(f, self.modules[module][field])
self:saveModuleProfile(field, self.modules[module][field], module, true)
end
end
end
if self.evt_cbs.GetConfigs then self.evt_cbs.GetConfigs(e) self.evt_cbs.GetConfigs = nil end
end
--- Got an event from the profile thread
function _M:handleEvent(e)
e = e:unserialize()
......@@ -223,55 +257,10 @@ end
-- Online stuff
-----------------------------------------------------------------------
function _M:rpc(data)
-- We can work in asynchronous mode, to not delay the main game execution
if data.async and game and type(game) == "table" and not game.refuse_threads then
data.async = nil
local l = lanes.linda()
function handler(data)
local http = require "socket.http"
local url = require "socket.url"
require "Json2"
print("[ONLINE PROFILE] async rpc called", "http://te4.org/lua/profilesrpc.ws/"..data.action)
local body, status = http.request("http://te4.org/lua/profilesrpc.ws/"..data.action, "json="..url.escape(json.encode(data)))
if not body then
l:send("final", nil)
else
local ok, ret = pcall(json.decode, body)
l:send("final", ok and ret or nil)
end
return true
end
local th = lanes.gen("*", handler)(data)
-- Tell the game to monitor this thread and end it when it's done
game:registerThread(th, l)
return th, l
else
print("[ONLINE PROFILE] rpc called", "http://te4.org/lua/profilesrpc.ws/"..data.action)
local body, status = http.request("http://te4.org/lua/profilesrpc.ws/"..data.action, "json="..url.escape(json.encode(data)))
if not body then return end
local ok, ret = pcall(json.decode, body)
return ok and ret or nil
end
end
function _M:getNews(callback)
print("[ONLINE PROFILE] get news")
core.profile.pushOrder("o='GetNews'")
self.evt_cbs.GetNews = callback
end
function _M:sendError(what, err)
print("[ONLINE PROFILE] sending error")
local popup = Dialog:simplePopup("Sending...", "Sending the error report. Thank you.", nil, true)
popup.__showup = nil
core.display.forceRedraw()
self:rpc{action="SendError", login=self.login, what=what, err=err, module=game.__mod_info.short_name, version=game.__mod_info.version_name}
game:unregisterDialog(popup)
core.profile.pushOrder("o='GetNews'")
end
function _M:tryAuth()
......@@ -279,41 +268,28 @@ function _M:tryAuth()
core.profile.pushOrder(table.serialize{o="Login", l=self.login, p=self.pass})
end
function _M:getConfigs(module)
if not self.auth then return end
local data = self:rpc{action="GetConfigs", login=self.login, hash=self.auth.hash, module=module}
if not data then print("[ONLINE PROFILE] get configs") return end
for name, val in pairs(data) do
print("[ONLINE PROFILE] config ", name)
function _M:logOut()
core.profile.pushOrder(table.serialize{o="Logoff"})
profile.generic.online = nil
profile.auth = nil
local field = name
local f, err = loadstring(val)
if not f and err then
print("Error loading profile config: ", err)
else
if module == "generic" then
self.generic[field] = self.generic[field] or {}
self:loadData(f, self.generic[field])
self:saveGenericProfile(field, self.generic[field], true)
else
self.modules[module] = self.modules[module] or {}
self.modules[module][field] = self.modules[module][field] or {}
self:loadData(f, self.modules[module][field])
self:saveModuleProfile(field, self.modules[module][field], module, true)
end
end
end
local restore = fs.getWritePath()
fs.setWritePath(engine.homepath)
fs.delete("/profiles/"..self.name.."/generic/online.profile")
if restore then fs.setWritePath(restore) end
end
function _M:getConfigs(module, cb)
if not self.auth then return end
self.evt_cbs.GetConfigs = cb
core.profile.pushOrder(table.serialize{o="GetConfigs", module=module})
end
function _M:setConfigs(module, name, val)
if not self.auth then return end
if name == "online" then return end
if type(val) ~= "string" then val = serialize(val) end
local data = self:rpc{async=true, action="SetConfigs", login=self.login, hash=self.auth.hash, module=module, data={[name] = val}}
if not data then return end
print("[ONLINE PROFILE] saved ", module, name, val)
core.profile.pushOrder(table.serialize{o="SetConfigs", module=module, data=table.serialize{[name] = val}})
end
function _M:syncOnline(module)
......@@ -325,9 +301,46 @@ function _M:syncOnline(module)
local data = {}
for k, v in pairs(sync) do if k ~= "online" then data[k] = serialize(v) end end
local data = self:rpc{async=true, action="SetConfigs", login=self.login, hash=self.auth.hash, module=module, data=data}
if not data then return end
print("[ONLINE PROFILE] saved ", module)
core.profile.pushOrder(table.serialize{o="SetConfigs", module=module, data=table.serialize(data)})
end
function _M:checkModuleHash(module, md5)
self.hash_valid = false
-- if not self.auth then return nil, "no online profile active" end
-- if config.settings.cheat then return nil, "cheat mode active" end
-- if game and game:isTainted() then return nil, "savefile tainted" end
core.profile.pushOrder(table.serialize{o="CheckModuleHash", module=module, md5=md5})
-- Wait anwser, this blocks thegame but cant really be avoided :/
local stop = false
local ok = false
while not stop do
local evt = core.profile.popEvent()
while evt do
evt = self:handleEvent(evt) -- Bypass game handling, there is none around at this point
if evt.e == "CheckModuleHash" then
ok = evt.ok
stop = true
break
end
evt = core.profile.popEvent()
end
end
if not ok then return nil, "bad game version" end
print("[ONLINE PROFILE] module hash is valid")
self.hash_valid = true
return true
end
--[[
function _M:sendError(what, err)
print("[ONLINE PROFILE] sending error")
local popup = Dialog:simplePopup("Sending...", "Sending the error report. Thank you.", nil, true)
popup.__showup = nil
core.display.forceRedraw()
self:rpc{action="SendError", login=self.login, what=what, err=err, module=game.__mod_info.short_name, version=game.__mod_info.version_name}
game:unregisterDialog(popup)
end
function _M:newProfile(Login, Name, Password, Email)
......@@ -351,25 +364,6 @@ function _M:performlogin(login, pass, name, email)
end
end
function _M:logOut()
profile.generic.online = nil
profile.auth = nil
local restore = fs.getWritePath()
fs.setWritePath(engine.homepath)
fs.delete("/profiles/"..self.name.."/generic/online.profile")
if restore then fs.setWritePath(restore) end
end
function _M:checkFirstRun()
local result = self.generic.firstrun
if not result then
firstrun = { When=os.time() }
self:saveGenericProfile("firstrun", firstrun, false)
end
return result
end
function _M:registerNewCharacter(module)
if not self.auth or not self.hash_valid then return end
local dialog = Dialog:simplePopup("Registering character", "Character is being registered on http://te4.org/") dialog.__showup = nil core.display.forceRedraw()
......@@ -388,15 +382,4 @@ function _M:registerSaveChardump(module, uuid, title, tags, data)
if not data or not data.ok then return end
print("[ONLINE PROFILE] saved character ", uuid)
end
function _M:checkModuleHash(module, md5)
self.hash_valid = false
if not self.auth then return nil, "no online profile active" end
if config.settings.cheat then return nil, "cheat mode active" end
if game and game:isTainted() then return nil, "savefile tainted" end
local data = self:rpc{action="CheckModuleHash", login=self.login, hash=self.auth.hash, module=module, md5=md5}
if not data or not data.ok then return nil, "bad game version" end
print("[ONLINE PROFILE] module hash is valid")
self.hash_valid = true
return true
end
]]
......@@ -101,8 +101,8 @@ end
function _M:orderLogin(o)
-- Already logged?
if self.auth and self.auth.login == o.login then
print("[PROFILE] reusing login")
if self.auth and self.auth.login == o.l then
print("[PROFILE] reusing login", self.auth.name)
cprofile.pushEvent(string.format("e='Auth' ok=%q", table.serialize(self.auth)))
else
self.user_login = o.l
......@@ -125,7 +125,37 @@ function _M:orderGetNews(o)
end
end
function _M:orderGetConfigs(o)
if not self.auth then return end
self:command("GCFS", o.module)
if self:read("200") then
local _, _, size = self.last_line:find("^([0-9]+)")
size = tonumber(size)
if not size or size < 1 then return end
local body = self.sock:receive(size)
cprofile.pushEvent(string.format("e='GetConfigs' module=%q data=%q", o.module, body))
end
end
function _M:orderSetConfigs(o)
if not self.auth then return end
self:command("SCFS", o.data:len(), o.module)
if self:read("200") then
self.sock:send(o.data)
end
end
function _M:orderCheckModuleHash(o)
self:command("CMD5", o.md5, o.module)
if self:read("200") then
cprofile.pushEvent("e='CheckModuleHash' ok=true")
else
cprofile.pushEvent("e='CheckModuleHash' ok=false")
end
end
function _M:handleOrder(o)
if not self.sock then return end
o = o:unserialize()
if self["order"..o.o] then self["order"..o.o](self, o) end
end
......@@ -35,6 +35,7 @@ int push_order(lua_State *L)
{
size_t len;
const char *code = luaL_checklstring(L, 1, &len);
printf("[profile order] %s\n", code);
profile_queue *q = malloc(sizeof(profile_queue));
char *d = calloc(len, sizeof(char));
......@@ -80,6 +81,7 @@ int push_event(lua_State *L)
{
size_t len;
const char *code = luaL_checklstring(L, 1, &len);
printf("[profile event] %s\n", code);
profile_queue *q = malloc(sizeof(profile_queue));
char *d = calloc(len, sizeof(char));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment