|
|
local skynet = require 'skynet'
|
|
|
local cjson = require 'cjson'
|
|
|
local cluster = require 'skynet.cluster'
|
|
|
local login_logic = require "login_logic"
|
|
|
local mongohelper = require "mongohelper"
|
|
|
local redishelper = require "redishelper"
|
|
|
local keysutils = require "keysutils"
|
|
|
local settings = require 'settings'
|
|
|
local bson = require "bson"
|
|
|
local dateutils = require "dateutils"
|
|
|
|
|
|
require "functions"
|
|
|
|
|
|
local max_client = settings.login_conf.max_client
|
|
|
|
|
|
local M = {}
|
|
|
|
|
|
function M.init()
|
|
|
DEBUG("myself = ", skynet.self())
|
|
|
end
|
|
|
|
|
|
local pattern = "(%d+)-(%d+)-(%d+) (%d+):(%d+):(%d+)"
|
|
|
|
|
|
|
|
|
function M.gen_secret()
|
|
|
math.randomseed(tostring(os.time()):reverse():sub(1, 6))
|
|
|
return tostring(math.random(1, 10000000))
|
|
|
end
|
|
|
|
|
|
|
|
|
function M.wx_auth(parms)
|
|
|
local openid = parms.openid
|
|
|
local access_token = parms.access_token
|
|
|
local serverid = parms.serverid
|
|
|
local ok, user = skynet.call(".mysqld", "lua", "loaduser", {openid=openid})
|
|
|
if ok then
|
|
|
return user.id, serverid
|
|
|
else
|
|
|
local resp = login_logic.wx_auth(openid, access_token)
|
|
|
resp.openid = openid
|
|
|
resp.serverid = serverid
|
|
|
local ok, uid = skynet.call(".mysqld", "lua", "register", resp)
|
|
|
if not access_token then
|
|
|
error("wx_auth register failed")
|
|
|
end
|
|
|
return uid, serverid
|
|
|
end
|
|
|
end
|
|
|
|
|
|
--APP微信登录
|
|
|
function M.wxlogin(parms)
|
|
|
local count = login_logic.get_online_count()
|
|
|
if count >= max_client then
|
|
|
error(string.format("online count=%d more than max_client=%d", count, max_client))
|
|
|
end
|
|
|
local uid, serverid = M.wx_auth(parms)
|
|
|
local secret = M.gen_secret()
|
|
|
|
|
|
local server, gate, port = login_logic.get_server_cfg(serverid, parms.protocol)
|
|
|
-- INFO(string.format("%s@%s is login, secret is %s", uid, server, secret))
|
|
|
-- only one can login, because disallow multilogin
|
|
|
-- TODO:把 此数据 单独 个 服务
|
|
|
local last = login_logic.get_user_online(uid)
|
|
|
-- 如果该用户已经在某个服务器上登录了,先踢下线
|
|
|
if last then
|
|
|
-- DEBUG(string.format("call last server %s to kick uid=%d subid=%d ...", last.server, uid, last.subid))
|
|
|
local ok = pcall(cluster.call, last.server, ".watchdog", "kick", uid, last.subid)
|
|
|
skynet.error(" watchdog kick ok = ", ok)
|
|
|
if ok then
|
|
|
login_logic.del_user_online(uid)
|
|
|
end
|
|
|
end
|
|
|
|
|
|
-- login_handler会被并发,可能同一用户在另一处中又登录了,所以再次确认是否登录
|
|
|
if login_logic.get_user_online(uid) then
|
|
|
ERROR("user %d is already online", uid)
|
|
|
error(string.format("user %d is already online", uid))
|
|
|
end
|
|
|
|
|
|
-- 登录游戏服务器
|
|
|
-- INFO(string.format("uid=%s is login to gameserver %s ...", uid, server))
|
|
|
local ok, subid = pcall(cluster.call, server, ".watchdog", "login",uid, secret)
|
|
|
if not ok then
|
|
|
error("login call gameserver error")
|
|
|
end
|
|
|
|
|
|
login_logic.add_user_online(uid, { subid = subid, server = server })
|
|
|
return 0, "登录成功", {uid = uid, subid = subid, gate = gate, port = port, secret = secret}
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
function M.mini_auth(parms)
|
|
|
DEBUG("mini_auth parms = ", DUMP(parms))
|
|
|
DEBUG("mini_auth settings = ", DUMP(settings))
|
|
|
local openid = parms.openid
|
|
|
if not openid or openid == "" then
|
|
|
return 101, nil, nil
|
|
|
end
|
|
|
|
|
|
local unionid = parms.unionid
|
|
|
if not unionid or unionid == "" then
|
|
|
return 101, nil, nil
|
|
|
end
|
|
|
local parent_id = parms.parent_id or ""
|
|
|
local friend_id = parms.friend_id or ""
|
|
|
local user = mongohelper.findOne(settings.agent_mongodb_key.tname, settings.agent_mongodb_key.cname, {_id=parent_id})
|
|
|
if not user then
|
|
|
parent_id = ""
|
|
|
end
|
|
|
|
|
|
local serverid = skynet.call(".redisd", "lua", "getserverid", unionid)
|
|
|
serverid = checkint(serverid)
|
|
|
local regionid = 0
|
|
|
if serverid == 0 then
|
|
|
local servers = mongohelper.find(settings.server_item_mongodb_key.tname, settings.server_item_mongodb_key.cname, {status=1})
|
|
|
local r = math.random(1, #servers)
|
|
|
local s = servers[r]
|
|
|
serverid = checkint(s._id)
|
|
|
regionid = checkint(s.server_id)
|
|
|
end
|
|
|
|
|
|
if serverid == 0 then
|
|
|
return 102, nil, nil
|
|
|
end
|
|
|
if settings.debug then
|
|
|
local user = mongohelper.findOne(settings.user_mongodb_key.tname, settings.user_mongodb_key.cname, {unionid=unionid, serverid=serverid})
|
|
|
if not user then
|
|
|
if regionid == 0 then
|
|
|
return 102, nil, nil
|
|
|
end
|
|
|
local uid = math.floor(skynet.call(".redisd", "lua", "genid"))
|
|
|
local userinfo = {
|
|
|
uid=uid,
|
|
|
parent_id=parent_id,
|
|
|
openid=openid,
|
|
|
unionid=unionid,
|
|
|
regionid=regionid,
|
|
|
serverid=serverid,
|
|
|
nickname = "SG:"..uid,
|
|
|
lv = 1,
|
|
|
stage = 0,
|
|
|
max_level = 1,
|
|
|
recharge_total = 0,
|
|
|
vip_lv = 0,
|
|
|
avatar = "",
|
|
|
last_login_time = "",
|
|
|
last_logout_time = "",
|
|
|
account_status = 0,
|
|
|
updated_at = os.date("%Y-%m-%d %H:%M:%S"),
|
|
|
created_at = os.date("%Y-%m-%d %H:%M:%S")
|
|
|
}
|
|
|
local ok1 = mongohelper.upsert(settings.user_mongodb_key.tname, settings.user_mongodb_key.cname, {["$set"]=userinfo}, {uid=uid})
|
|
|
|
|
|
local bag = {
|
|
|
uid=uid,
|
|
|
serverid=serverid,
|
|
|
box_lv1 = 0,
|
|
|
coin = 10,
|
|
|
gold = 0,
|
|
|
xiaoyugan= 10,
|
|
|
updated_at = os.date("%Y-%m-%d %H:%M:%S"),
|
|
|
created_at = os.date("%Y-%m-%d %H:%M:%S")
|
|
|
}
|
|
|
|
|
|
local ok2 = mongohelper.upsert(settings.bag_mongodb_key.tname, settings.bag_mongodb_key.cname, {["$set"]=bag}, {uid=uid})
|
|
|
|
|
|
local ok = skynet.call(".redisd", "lua", "setserverid", openid, serverid)
|
|
|
-- DEBUG('setserverid ok = ', ok)
|
|
|
if friend_id ~= "" then
|
|
|
skynet.call(".redisd", "lua", "addinvitenum", friend_id)
|
|
|
end
|
|
|
return 200, uid, serverid
|
|
|
end
|
|
|
if user.account_status and user.account_status == 1 then
|
|
|
if user.freeze_date and user.freeze_date ~= "" then
|
|
|
if os.time() < dateutils.get_timestamp_by_datetime(user.freeze_date, pattern) then
|
|
|
return 302, user.freeze_season, nil
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
return 200, user.uid, serverid
|
|
|
else
|
|
|
local resp = {}
|
|
|
local user = mongohelper.findOne(settings.user_mongodb_key.tname, settings.user_mongodb_key.cname, {unionid=unionid, serverid=serverid})
|
|
|
if not user then
|
|
|
if regionid == 0 then
|
|
|
return 102, nil, nil
|
|
|
end
|
|
|
local uid = math.floor(skynet.call(".redisd", "lua", "genid"))
|
|
|
local userinfo = {
|
|
|
uid=uid,
|
|
|
parent_id=parent_id,
|
|
|
openid=openid,
|
|
|
unionid=unionid,
|
|
|
regionid=regionid,
|
|
|
serverid=serverid,
|
|
|
nickname = resp.nickname or "SG:"..uid,
|
|
|
avatar = resp.headimgurl or "",
|
|
|
lv = 1,
|
|
|
stage = 0,
|
|
|
max_level = 1,
|
|
|
recharge_total = 0,
|
|
|
vip_lv = 0,
|
|
|
last_login_time = "",
|
|
|
last_logout_time = "",
|
|
|
account_status = 0,
|
|
|
updated_at = os.date("%Y-%m-%d %H:%M:%S"),
|
|
|
created_at = os.date("%Y-%m-%d %H:%M:%S")
|
|
|
}
|
|
|
|
|
|
local ok1 = mongohelper.upsert(settings.user_mongodb_key.tname, settings.user_mongodb_key.cname, {["$set"]=userinfo}, {uid=uid})
|
|
|
local bag = {
|
|
|
uid=uid,
|
|
|
serverid=serverid,
|
|
|
box_lv1 = 0,
|
|
|
coin = 10,
|
|
|
gold = 0,
|
|
|
xiaoyugan= 10,
|
|
|
updated_at = os.date("%Y-%m-%d %H:%M:%S"),
|
|
|
created_at = os.date("%Y-%m-%d %H:%M:%S")
|
|
|
}
|
|
|
local ok2 = mongohelper.upsert(settings.bag_mongodb_key.tname, settings.bag_mongodb_key.cname, {["$set"]=bag}, {uid=uid})
|
|
|
local ok = skynet.call(".redisd", "lua", "setserverid", unionid, serverid)
|
|
|
if friend_id ~= "" then
|
|
|
skynet.call(".redisd", "lua", "addinvitenum", friend_id)
|
|
|
end
|
|
|
return 200, uid, serverid
|
|
|
end
|
|
|
if user.account_status and user.account_status == 1 then
|
|
|
if user.freeze_date and user.freeze_date ~= "" then
|
|
|
if os.time() < dateutils.get_timestamp_by_datetime(user.freeze_date, pattern) then
|
|
|
return 302, user.freeze_season, nil
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
|
|
|
|
|
|
return 200, user.uid, serverid
|
|
|
end
|
|
|
end
|
|
|
|
|
|
|
|
|
function M.add_login_log(uid, serverid)
|
|
|
local log = {
|
|
|
uid=uid,
|
|
|
serverid=serverid,
|
|
|
logind_at = os.date("%Y-%m-%d %H:%M:%S")
|
|
|
}
|
|
|
local ok2 = mongohelper.insert(settings.user_login_mongodb_key.tname, settings.user_login_mongodb_key.cname, log)
|
|
|
end
|
|
|
|
|
|
--小程序
|
|
|
function M.minilogin(parms)
|
|
|
local count = login_logic.get_online_count()
|
|
|
if count >= max_client then
|
|
|
error(string.format("online count=%d more than max_client=%d", count, max_client))
|
|
|
end
|
|
|
local uid, serverid = M.mini_auth(parms)
|
|
|
local secret = M.gen_secret()
|
|
|
|
|
|
local server, gate, port = login_logic.get_server_cfg(serverid, parms.protocol)
|
|
|
-- INFO(string.format("%s@%s is login, gate is %s secret is %s", uid, server, gate, secret))
|
|
|
-- only one can login, because disallow multilogin
|
|
|
-- TODO:把 此数据 单独 个 服务
|
|
|
local last = login_logic.get_user_online(uid)
|
|
|
-- 如果该用户已经在某个服务器上登录了,先踢下线
|
|
|
if last then
|
|
|
-- DEBUG(string.format("call last server %s to kick uid=%d subid=%d ...", last.server, uid, last.subid))
|
|
|
local ok = pcall(cluster.call, last.server, ".watchdog", "kick", uid, last.subid)
|
|
|
skynet.error(" watchdog kick ok = ", ok)
|
|
|
if ok then
|
|
|
login_logic.del_user_online(uid)
|
|
|
end
|
|
|
end
|
|
|
|
|
|
-- login_handler会被并发,可能同一用户在另一处中又登录了,所以再次确认是否登录
|
|
|
if login_logic.get_user_online(uid) then
|
|
|
error(string.format("user %d is already online", uid))
|
|
|
end
|
|
|
|
|
|
-- 登录游戏服务器
|
|
|
-- INFO(string.format("uid=%s is login to gameserver %s ...", uid, server))
|
|
|
local ok, subid = pcall(cluster.call, server, ".watchdog", "login", uid, secret)
|
|
|
if not ok then
|
|
|
error("login call gameserver error")
|
|
|
end
|
|
|
|
|
|
login_logic.add_user_online(uid, { subid = subid, server = server })
|
|
|
return 0, "登录成功", {uid = uid, subid = subid, gate = gate, port = port, secret = secret}
|
|
|
end
|
|
|
|
|
|
|
|
|
--小程序code2Session
|
|
|
-- function M.code2Session(parms)
|
|
|
-- local code = parms.code
|
|
|
-- local resp = login_logic.code2Session(code)
|
|
|
-- if resp.errcode ~= 0 then
|
|
|
-- return 401, "请求失败", resp
|
|
|
-- end
|
|
|
-- --TODO:通过openid 去找serverid
|
|
|
-- resp.serverid = 1
|
|
|
-- return 0, "请求成功", resp
|
|
|
-- end
|
|
|
|
|
|
|
|
|
function M.code2Session(parms)
|
|
|
local count = login_logic.get_online_count()
|
|
|
if count >= max_client then
|
|
|
-- error(string.format("online count=%d more than max_client=%d", count, max_client))
|
|
|
return 400, "当前人数过多,请等待", {}
|
|
|
end
|
|
|
local code = parms.code
|
|
|
local parent_id = parms.parent_id or ""
|
|
|
local friend_id = parms.friend_id or ""
|
|
|
|
|
|
local app = parms.app or "sg"
|
|
|
DEBUG("parms = ", DUMP(parms))
|
|
|
if settings.debug then
|
|
|
parms.openid = code
|
|
|
parms.unionid = code
|
|
|
else
|
|
|
if parms.platform and parms.platform == "h5" then
|
|
|
parms.openid = code
|
|
|
parms.unionid = code
|
|
|
else
|
|
|
local resp = login_logic.code2Session(app, code)
|
|
|
-- DEBUG("code2Session resp = ", DUMP(resp))
|
|
|
if resp.errcode and resp.errcode ~= 0 then
|
|
|
return 401, "请求失败", resp
|
|
|
end
|
|
|
parms.openid = resp.openid
|
|
|
parms.unionid = resp.unionid
|
|
|
end
|
|
|
end
|
|
|
|
|
|
local code, uid, serverid = M.mini_auth(parms)
|
|
|
|
|
|
if code == 101 then
|
|
|
return 101, "参数错误,openid获取", {}
|
|
|
end
|
|
|
|
|
|
if code == 102 then
|
|
|
return 102, "服务器选择失败", {}
|
|
|
end
|
|
|
|
|
|
if code == 302 then
|
|
|
return 302, "该账号已冻结, ".. uid, {}
|
|
|
end
|
|
|
|
|
|
local secret = M.gen_secret()
|
|
|
local server, gate, port = login_logic.get_server_cfg(serverid, parms.protocol or "ws")
|
|
|
-- only one can login, because disallow multilogin
|
|
|
-- TODO:把 此数据 单独 个 服务
|
|
|
local last = login_logic.get_user_online(uid)
|
|
|
-- 如果该用户已经在某个服务器上登录了,先踢下线
|
|
|
if last then
|
|
|
-- DEBUG(string.format("call last server %s to kick uid=%d subid=%d ...", last.server, uid, last.subid))
|
|
|
local ok = pcall(cluster.call, last.server, ".watchdog", "kick", uid, last.subid)
|
|
|
-- skynet.error(" watchdog kick ok = ", ok)
|
|
|
if ok then
|
|
|
login_logic.del_user_online(uid)
|
|
|
end
|
|
|
end
|
|
|
|
|
|
-- login_handler会被并发,可能同一用户在另一处中又登录了,所以再次确认是否登录
|
|
|
if login_logic.get_user_online(uid) then
|
|
|
return 402, "关闭之前登录用户得链接", {}
|
|
|
end
|
|
|
-- 登录游戏服务器
|
|
|
-- INFO(string.format("uid=%s is login to gameserver %s ...", uid, server))
|
|
|
local ok, subid = pcall(cluster.call, server, ".watchdog", "login", uid, secret)
|
|
|
if not ok then
|
|
|
return 403, "系统繁忙", {}
|
|
|
end
|
|
|
|
|
|
login_logic.add_user_online(uid, { subid = subid, server = server })
|
|
|
|
|
|
M.add_login_log(uid, serverid)
|
|
|
return 0, "登录成功", {uid = uid, subid = subid, gate = gate, port = port, secret = secret}
|
|
|
end
|
|
|
|
|
|
--停服
|
|
|
function M.stop(parms)
|
|
|
end
|
|
|
|
|
|
--开服
|
|
|
function M.start(parms)
|
|
|
end
|
|
|
|
|
|
--踢掉所有用户
|
|
|
function M.kickall(parms)
|
|
|
end
|
|
|
|
|
|
--管理后台踢掉用户
|
|
|
function M.adminkick(parms)
|
|
|
end
|
|
|
|
|
|
return M
|