local skynet = require "skynet" require "skynet.manager" local redisdriver = require "skynet.db.redis" local pipeline = require "pipeline" local logger = require "logger" local asset = require "model.asset" local queue = require "skynet.queue" local redis local NAMELIST = "namelist" local stringify = require "stringify" local DEFAULT_NAME = "role" local skynet_retpack = skynet.retpack local synchronized = queue() local population = 0 -- 服务器人口数量 local nickname = {} local duplicate_name = {} local function load_registered_name() local conf = assert(option.redis) local character_redis = redisdriver.connect(conf) character_redis:select(0) -- 载入角色名字和帐号 local block = pipeline(1024) local keys = character_redis:keys("character:*") if #keys > 0 then for _, k in ipairs(keys) do block.add("hmget", k, "nickname", "uid") end population = population + #keys end local resp = block.execute(character_redis, {}) nickname[DEFAULT_NAME] = "" for i, v in ipairs(resp) do assert(v.ok) local k = v.out[1] if k and k ~= DEFAULT_NAME then nickname[k] = v.out[2] end end character_redis:disconnect() end local function init() local conf = assert(option.redis) redis = redisdriver.connect(conf) redis:select(14) local retnuma = redis:hgetall(NAMELIST) for k = 1, #retnuma, 2 do duplicate_name[retnuma[k]] = tonumber(retnuma[k+1]) end end local function get_name(name) local realname = name for i = 1, 100 do if nickname[realname] then duplicate_name[name] = (duplicate_name[name] or 0) + 1 realname = name .. "#" .. (duplicate_name[name]+100) break end end if duplicate_name[name] > 0 then redis:hset(NAMELIST, name, duplicate_name[name]) end if not nickname[realname] then return realname end end local CMD = {} function CMD.start() init() load_registered_name() end function CMD.register_nickname(name, uid) local name = name if not name or name == "" then name = DEFAULT_NAME end if nickname[name] then name = get_name(name) end if not name then return end nickname[name] = uid population = population + 1 logger.trace(" #### 服务器人口数量增加 %s",population) return true, name end --@TODO 服务器人口数量 function CMD.get_population() return population end -- 通过名字查找玩家的基础信息 -- uid: 角色id -- account: 帐号id function CMD.findby(name) if name == DEFAULT_NAME then return end local uid = nickname[name] if uid and type(uid) == "string" then return uid end end -- 玩家改名 -- old_name:以前的名 -- new_name: 新的名字 -- uid :玩家的uid function CMD.rename(old_name, new_name, uid) return synchronized(function () if new_name == DEFAULT_NAME then return STD_ERR.PLYAER_DUPLICATION_NAME -- 名字已经被使用 end -- 没有找到改玩家 if old_name ~= DEFAULT_NAME then if not nickname[tostring(old_name)] or nickname[tostring(old_name)] ~= uid then return STD_ERR.PLYAER_NO_PLAYER -- 不存在的玩家 end end -- 名字已经被使用 if nickname[new_name] then return STD_ERR.PLYAER_DUPLICATION_NAME -- 名字已经被使用 end nickname[new_name] = uid return 0 end) end -- 撤销改名 function CMD.revocation_rename(new_name, uid) return synchronized(function () -- nickname[old_name] = uid nickname[new_name] = nil return 0 end) end -- 取消对name的锁定 function CMD.unlock_name(name) return synchronized(function () nickname[name] = nil return 0 end) end skynet.init(function() skynet.register(".namecenter") end) skynet.start(function() logger.label("") skynet.dispatch("lua", function(session, _, cmd, ...) local f = assert(CMD[cmd]) if session == 0 then f(...) else skynet_retpack(f(...)) end end) end)