├── Chapter1 ├── 1_simple_server.js ├── 2_walk_server.js ├── 3_chat_server.js └── 3_walk_server.js ├── Chapter2 ├── 1_config ├── 2_pingpong_main.lua ├── 2_pingpong_ping.lua ├── 3_echo.lua ├── 4_chat.lua ├── 5_messageboard.lua ├── 5_mysql.lua ├── 6_cluster_main.lua └── 6_cluster_ping.lua ├── Chapter3 └── rill4 │ ├── etc │ ├── config.node1 │ ├── config.node2 │ └── runconfig.lua │ ├── lualib │ └── service.lua │ ├── service │ ├── agent │ │ ├── init.lua │ │ └── scene.lua │ ├── agentmgr │ │ └── init.lua │ ├── gateway │ │ └── init.lua │ ├── login │ │ └── init.lua │ ├── main.lua │ ├── nodemgr │ │ └── init.lua │ └── scene │ │ └── init.lua │ └── start.sh ├── Chapter4 ├── 1_client.lua ├── 1_netpack.lua ├── 2_json.lua ├── 3_login.proto ├── 3_protobuf.lua ├── 4_database.lua ├── 4_playerdata.proto └── rill4 │ ├── etc │ ├── config.node1 │ ├── config.node2 │ └── runconfig.lua │ ├── luaclib │ ├── cjson.so │ └── protobuf.so │ ├── lualib │ ├── cjson.so │ ├── protobuf.lua │ └── service.lua │ ├── proto │ ├── login.pb │ └── login.proto │ ├── service │ ├── Pmain.lua │ ├── admin │ │ └── init.lua │ ├── agent │ │ ├── init.lua │ │ └── scene.lua │ ├── agentmgr │ │ └── init.lua │ ├── gateway │ │ └── init.lua │ ├── login │ │ └── init.lua │ ├── main.lua │ ├── nodemgr │ │ └── init.lua │ └── scene │ │ └── init.lua │ ├── start.sh │ └── storage │ ├── playerdata.pb │ └── playerdata.proto ├── Chapter5 └── sunnet │ ├── CMakeLists.txt │ ├── build │ └── sunnet │ ├── include │ ├── Msg.h │ ├── Service.h │ ├── Sunnet.h │ └── Worker.h │ └── src │ ├── Service.cpp │ ├── Sunnet.cpp │ ├── Worker.cpp │ └── main.cpp ├── Chapter6 └── sunnet │ ├── CMakeLists.txt │ ├── include │ ├── Conn.h │ ├── ConnWriter.h │ ├── Msg.h │ ├── Service.h │ ├── SocketWorker.h │ ├── Sunnet.h │ └── Worker.h │ └── src │ ├── ConnWriter.cpp │ ├── Service.cpp │ ├── SocketWorker.cpp │ ├── Sunnet.cpp │ ├── Worker.cpp │ └── main.cpp ├── Chapter7 └── sunnet │ ├── 3rd │ └── lua-5.3.5 │ │ ├── Makefile │ │ ├── README │ │ ├── doc │ │ ├── contents.html │ │ ├── index.css │ │ ├── logo.gif │ │ ├── lua.1 │ │ ├── lua.css │ │ ├── luac.1 │ │ ├── manual.css │ │ ├── manual.html │ │ ├── osi-certified-72x60.png │ │ └── readme.html │ │ └── src │ │ ├── Makefile │ │ ├── lapi.c │ │ ├── lapi.h │ │ ├── lapi.o │ │ ├── lauxlib.c │ │ ├── lauxlib.h │ │ ├── lauxlib.o │ │ ├── lbaselib.c │ │ ├── lbaselib.o │ │ ├── lbitlib.c │ │ ├── lbitlib.o │ │ ├── lcode.c │ │ ├── lcode.h │ │ ├── lcode.o │ │ ├── lcorolib.c │ │ ├── lcorolib.o │ │ ├── lctype.c │ │ ├── lctype.h │ │ ├── lctype.o │ │ ├── ldblib.c │ │ ├── ldblib.o │ │ ├── ldebug.c │ │ ├── ldebug.h │ │ ├── ldebug.o │ │ ├── ldo.c │ │ ├── ldo.h │ │ ├── ldo.o │ │ ├── ldump.c │ │ ├── ldump.o │ │ ├── lfunc.c │ │ ├── lfunc.h │ │ ├── lfunc.o │ │ ├── lgc.c │ │ ├── lgc.h │ │ ├── lgc.o │ │ ├── liblua.a │ │ ├── linit.c │ │ ├── linit.o │ │ ├── liolib.c │ │ ├── liolib.o │ │ ├── llex.c │ │ ├── llex.h │ │ ├── llex.o │ │ ├── llimits.h │ │ ├── lmathlib.c │ │ ├── lmathlib.o │ │ ├── lmem.c │ │ ├── lmem.h │ │ ├── lmem.o │ │ ├── loadlib.c │ │ ├── loadlib.o │ │ ├── lobject.c │ │ ├── lobject.h │ │ ├── lobject.o │ │ ├── lopcodes.c │ │ ├── lopcodes.h │ │ ├── lopcodes.o │ │ ├── loslib.c │ │ ├── loslib.o │ │ ├── lparser.c │ │ ├── lparser.h │ │ ├── lparser.o │ │ ├── lprefix.h │ │ ├── lstate.c │ │ ├── lstate.h │ │ ├── lstate.o │ │ ├── lstring.c │ │ ├── lstring.h │ │ ├── lstring.o │ │ ├── lstrlib.c │ │ ├── lstrlib.o │ │ ├── ltable.c │ │ ├── ltable.h │ │ ├── ltable.o │ │ ├── ltablib.c │ │ ├── ltablib.o │ │ ├── ltm.c │ │ ├── ltm.h │ │ ├── ltm.o │ │ ├── lua │ │ ├── lua.c │ │ ├── lua.h │ │ ├── lua.hpp │ │ ├── lua.o │ │ ├── luac │ │ ├── luac.c │ │ ├── luac.o │ │ ├── luaconf.h │ │ ├── lualib.h │ │ ├── lundump.c │ │ ├── lundump.h │ │ ├── lundump.o │ │ ├── lutf8lib.c │ │ ├── lutf8lib.o │ │ ├── lvm.c │ │ ├── lvm.h │ │ ├── lvm.o │ │ ├── lzio.c │ │ ├── lzio.h │ │ └── lzio.o │ ├── CMakeLists.txt │ ├── include │ ├── Conn.h │ ├── ConnWriter.h │ ├── LuaAPI.h │ ├── Msg.h │ ├── Service.h │ ├── SocketWorker.h │ ├── Sunnet.h │ └── Worker.h │ ├── service │ ├── chat │ │ └── init.lua │ ├── main │ │ └── init.lua │ └── ping │ │ └── init.lua │ └── src │ ├── ConnWriter.cpp │ ├── LuaAPI.cpp │ ├── Service.cpp │ ├── SocketWorker.cpp │ ├── Sunnet.cpp │ ├── Worker.cpp │ └── main.cpp ├── README.md └── web ├── gg1.jpg ├── gg2.jpg ├── gg3.jpg ├── gg4.jpg ├── qqdzz1.jpg ├── qqdzz2.jpg ├── qqdzz3.jpg ├── readme.md ├── sunnet1.jpg ├── zcover.jpg ├── zcover_big.jpg └── zsx.jpg /Chapter1/1_simple_server.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter1/1_simple_server.js -------------------------------------------------------------------------------- /Chapter1/2_walk_server.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter1/2_walk_server.js -------------------------------------------------------------------------------- /Chapter1/3_chat_server.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter1/3_chat_server.js -------------------------------------------------------------------------------- /Chapter1/3_walk_server.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter1/3_walk_server.js -------------------------------------------------------------------------------- /Chapter2/1_config: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter2/1_config -------------------------------------------------------------------------------- /Chapter2/2_pingpong_main.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | 3 | skynet.start(function() 4 | skynet.error("[Pmain] start") 5 | local ping1 = skynet.newservice("ping") 6 | local ping2 = skynet.newservice("ping") 7 | 8 | skynet.send(ping1, "lua", "start", ping2) 9 | skynet.exit() 10 | end) -------------------------------------------------------------------------------- /Chapter2/2_pingpong_ping.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | 3 | local CMD = {} 4 | 5 | function CMD.start(source, target) 6 | skynet.send(target, "lua", "ping", 1) 7 | end 8 | 9 | function CMD.ping(source, count) 10 | local id = skynet.self() 11 | skynet.error("["..id.."] recv ping count="..count) 12 | skynet.sleep(100) 13 | skynet.send(source, "lua", "ping", count+1) 14 | end 15 | 16 | 17 | skynet.start(function() 18 | skynet.dispatch("lua", function(session, source, cmd, ...) 19 | local f = assert(CMD[cmd]) 20 | f(source,...) 21 | end) 22 | end) -------------------------------------------------------------------------------- /Chapter2/3_echo.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter2/3_echo.lua -------------------------------------------------------------------------------- /Chapter2/4_chat.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter2/4_chat.lua -------------------------------------------------------------------------------- /Chapter2/5_messageboard.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter2/5_messageboard.lua -------------------------------------------------------------------------------- /Chapter2/5_mysql.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter2/5_mysql.lua -------------------------------------------------------------------------------- /Chapter2/6_cluster_main.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local cluster = require "skynet.cluster" 3 | require "skynet.manager" 4 | 5 | skynet.start(function() 6 | cluster.reload({ 7 | node1 = "127.0.0.1:7001", 8 | node2 = "127.0.0.1:7002" 9 | }) 10 | local mynode = skynet.getenv("node") 11 | 12 | if mynode == "node1" then 13 | cluster.open("node1") 14 | local ping1 = skynet.newservice("ping") 15 | local ping2 = skynet.newservice("ping") 16 | skynet.send(ping1, "lua", "start", "node2", "pong") 17 | skynet.send(ping2, "lua", "start", "node2", "pong") 18 | elseif mynode == "node2" then 19 | cluster.open("node2") 20 | local ping3 = skynet.newservice("ping") 21 | skynet.name("pong", ping3) 22 | end 23 | end) -------------------------------------------------------------------------------- /Chapter2/6_cluster_ping.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local cluster = require "skynet.cluster" 3 | local mynode = skynet.getenv("node") 4 | 5 | local CMD = {} 6 | 7 | function CMD.ping(source, source_node, source_srv, count) 8 | local id = skynet.self() 9 | skynet.error("["..id.."] recv ping count="..count) 10 | skynet.sleep(100) 11 | cluster.send(source_node, source_srv, "ping", mynode, skynet.self(), count+1) 12 | end 13 | 14 | function CMD.start(source, target_node, target) 15 | cluster.send(target_node, target, "ping", mynode, skynet.self(), 1) 16 | end 17 | 18 | skynet.start(function() 19 | skynet.dispatch("lua", function(session, source, cmd, ...) 20 | local f = assert(CMD[cmd]) 21 | f(source,...) 22 | end) 23 | end) -------------------------------------------------------------------------------- /Chapter3/rill4/etc/config.node1: -------------------------------------------------------------------------------- 1 | --必须配置 2 | thread = 8 --启用多少个工作线程 3 | cpath = "./skynet/cservice/?.so" --用C编写的服务模块的位置 4 | bootstrap = "snlua bootstrap" --启动的第一个服务 5 | 6 | --bootstrap配置项 7 | start = "main" --主程序入口 8 | harbor = 0 --不使用主从节点模式 9 | 10 | --lua配置项 11 | lualoader = "./skynet/lualib/loader.lua" 12 | luaservice = "./service/?.lua;" .."./service/?/init.lua;".. "./skynet/service/?.lua;" 13 | lua_path = "./etc/?.lua;" .. "./lualib/?.lua;" .. "./skynet/lualib/?.lua;" .. "./skynet/lualib/?/init.lua" 14 | lua_cpath = "./luaclib/?.so;" .. "./skynet/luaclib/?.so" 15 | 16 | --后台模式 17 | --daemon = "./skynet.pid" 18 | --logger = "./userlog" 19 | 20 | --节点 21 | node = "node1" -------------------------------------------------------------------------------- /Chapter3/rill4/etc/config.node2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter3/rill4/etc/config.node2 -------------------------------------------------------------------------------- /Chapter3/rill4/etc/runconfig.lua: -------------------------------------------------------------------------------- 1 | return { 2 | --集群 3 | cluster = { 4 | node1 = "127.0.0.1:7771", 5 | node2 = "127.0.0.1:7772", 6 | }, 7 | --agentmgr 8 | agentmgr = { node = "node1" }, 9 | --scene 10 | scene = { 11 | node1 = {1001, 1002}, 12 | --node2 = {1003}, 13 | }, 14 | --节点1 15 | node1 = { 16 | gateway = { 17 | [1] = {port=8001}, 18 | [2] = {port=8002}, 19 | }, 20 | login = { 21 | [1] = {}, 22 | [2] = {}, 23 | }, 24 | }, 25 | 26 | --节点2 27 | node2 = { 28 | gateway = { 29 | [1] = {port=8011}, 30 | [2] = {port=8022}, 31 | }, 32 | login = { 33 | [1] = {}, 34 | [2] = {}, 35 | }, 36 | }, 37 | } -------------------------------------------------------------------------------- /Chapter3/rill4/lualib/service.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local cluster = require "skynet.cluster" 3 | 4 | local M = { 5 | --类型和id 6 | name = "", 7 | id = 0, 8 | --回调函数 9 | exit = nil, 10 | init = nil, 11 | --分发方法 12 | resp = {}, 13 | } 14 | 15 | --[[ 16 | function exit_dispatch() 17 | if M.exit then 18 | M.exit() 19 | end 20 | skynet.ret() 21 | skynet.exit() 22 | end 23 | --]] 24 | 25 | function traceback(err) 26 | skynet.error(tostring(err)) 27 | skynet.error(debug.traceback()) 28 | end 29 | 30 | local dispatch = function(session, address, cmd, ...) 31 | local fun = M.resp[cmd] 32 | if not fun then 33 | skynet.ret() 34 | return 35 | end 36 | 37 | local ret = table.pack(xpcall(fun, traceback, address, ...)) 38 | local isok = ret[1] 39 | 40 | if not isok then 41 | skynet.ret() 42 | return 43 | end 44 | 45 | skynet.retpack(table.unpack(ret,2)) 46 | end 47 | 48 | function init() 49 | skynet.dispatch("lua", dispatch) 50 | if M.init then 51 | M.init() 52 | end 53 | end 54 | 55 | function M.call(node, srv, ...) 56 | local mynode = skynet.getenv("node") 57 | if node == mynode then 58 | return skynet.call(srv, "lua", ...) 59 | else 60 | return cluster.call(node, srv, ...) 61 | end 62 | end 63 | 64 | function M.send(node, srv, ...) 65 | local mynode = skynet.getenv("node") 66 | if node == mynode then 67 | return skynet.send(srv, "lua", ...) 68 | else 69 | return cluster.send(node, srv, ...) 70 | end 71 | end 72 | 73 | function M.start(name, id, ...) 74 | M.name = name 75 | M.id = tonumber(id) 76 | skynet.start(init) 77 | end 78 | 79 | 80 | return M -------------------------------------------------------------------------------- /Chapter3/rill4/service/agent/init.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local s = require "service" 3 | 4 | s.client = {} 5 | s.gate = nil 6 | 7 | require "scene" 8 | 9 | 10 | s.resp.client = function(source, cmd, msg) 11 | s.gate = source 12 | if s.client[cmd] then 13 | local ret_msg = s.client[cmd]( msg, source) 14 | if ret_msg then 15 | skynet.send(source, "lua", "send", s.id, ret_msg) 16 | end 17 | else 18 | skynet.error("s.resp.client fail", cmd) 19 | end 20 | end 21 | 22 | s.client.work = function(msg) 23 | s.data.coin = s.data.coin + 1 24 | return {"work", s.data.coin} 25 | end 26 | 27 | s.resp.kick = function(source) 28 | s.leave_scene() 29 | --在此处保存角色数据 30 | skynet.sleep(200) 31 | end 32 | 33 | s.resp.exit = function(source) 34 | skynet.exit() 35 | end 36 | 37 | s.resp.send = function(source, msg) 38 | skynet.send(s.gate, "lua", "send", s.id, msg) 39 | end 40 | 41 | s.init = function( ) 42 | --playerid = s.id 43 | --在此处加载角色数据 44 | skynet.sleep(200) 45 | s.data = { 46 | coin = 100, 47 | hp = 200, 48 | } 49 | end 50 | 51 | s.start(...) -------------------------------------------------------------------------------- /Chapter3/rill4/service/agent/scene.lua: -------------------------------------------------------------------------------- 1 | 2 | local skynet = require "skynet" 3 | local s = require "service" 4 | local runconfig = require "runconfig" 5 | local mynode = skynet.getenv("node") 6 | 7 | s.snode = nil --scene_node 8 | s.sname = nil --scene_id 9 | 10 | local function random_scene() 11 | --选择node 12 | local nodes = {} 13 | for i, v in pairs(runconfig.scene) do 14 | table.insert(nodes, i) 15 | if runconfig.scene[mynode] then 16 | table.insert(nodes, mynode) 17 | end 18 | end 19 | local idx = math.random( 1, #nodes) 20 | local scenenode = nodes[idx] 21 | --具体场景 22 | local scenelist = runconfig.scene[scenenode] 23 | local idx = math.random( 1, #scenelist) 24 | local sceneid = scenelist[idx] 25 | return scenenode, sceneid 26 | end 27 | 28 | s.client.enter = function(msg) 29 | if s.sname then 30 | return {"enter",1,"已在场景"} 31 | end 32 | local snode, sid = random_scene() 33 | local sname = "scene"..sid 34 | local isok = s.call(snode, sname, "enter", s.id, mynode, skynet.self()) 35 | if not isok then 36 | return {"enter",1,"进入失败"} 37 | end 38 | s.snode = snode 39 | s.sname = sname 40 | return nil 41 | end 42 | 43 | --改变方向 44 | s.client.shift = function(msg) 45 | if not s.sname then 46 | return 47 | end 48 | local x = msg[2] or 0 49 | local y = msg[3] or 0 50 | s.call(s.snode, s.sname, "shift", s.id, x, y) 51 | end 52 | 53 | s.leave_scene = function() 54 | --不在场景 55 | if not s.sname then 56 | return 57 | end 58 | s.call(s.snode, s.sname, "leave", s.id) 59 | s.snode = nil 60 | s.sname = nil 61 | end -------------------------------------------------------------------------------- /Chapter3/rill4/service/agentmgr/init.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local s = require "service" 3 | 4 | --状态 5 | STATUS = { 6 | LOGIN = 2, 7 | GAME = 3, 8 | LOGOUT = 4, 9 | } 10 | 11 | --玩家列表 12 | local players = {} 13 | 14 | --玩家类 15 | function mgrplayer() 16 | local m = { 17 | playerid = nil, 18 | node = nil, 19 | agent = nil, 20 | status = nil, 21 | gate = nil, 22 | } 23 | return m 24 | end 25 | 26 | s.resp.reqlogin = function(source, playerid, node, gate) 27 | local mplayer = players[playerid] 28 | --登陆过程禁止顶替 29 | if mplayer and mplayer.status == STATUS.LOGOUT then 30 | skynet.error("reqlogin fail, at status LOGOUT " ..playerid ) 31 | return false 32 | end 33 | if mplayer and mplayer.status == STATUS.LOGIN then 34 | skynet.error("reqlogin fail, at status LOGIN " ..playerid) 35 | return false 36 | end 37 | --在线,顶替 38 | if mplayer then 39 | local pnode = mplayer.node 40 | local pagent = mplayer.agent 41 | local pgate = mplayer.gate 42 | mplayer.status = STATUS.LOGOUT, 43 | s.call(pnode, pagent, "kick") 44 | s.send(pnode, pagent, "exit") 45 | s.send(pnode, pgate, "send", playerid, {"kick","顶替下线"}) 46 | s.call(pnode, pgate, "kick", playerid) 47 | end 48 | --上线 49 | local player = mgrplayer() 50 | player.playerid = playerid 51 | player.node = node 52 | player.gate = gate 53 | player.agent = nil 54 | player.status = STATUS.LOGIN 55 | players[playerid] = player 56 | local agent = s.call(node, "nodemgr", "newservice", "agent", "agent", playerid) 57 | player.agent = agent 58 | player.status = STATUS.GAME 59 | return true, agent 60 | end 61 | 62 | s.resp.reqkick = function(source, playerid, reason) 63 | local mplayer = players[playerid] 64 | if not mplayer then 65 | return false 66 | end 67 | 68 | if mplayer.status ~= STATUS.GAME then 69 | return false 70 | end 71 | 72 | local pnode = mplayer.node 73 | local pagent = mplayer.agent 74 | local pgate = mplayer.gate 75 | mplayer.status = STATUS.LOGOUT 76 | 77 | s.call(pnode, pagent, "kick") 78 | s.send(pnode, pagent, "exit") 79 | s.send(pnode, pgate, "kick", playerid) 80 | players[playerid] = nil 81 | 82 | return true 83 | end 84 | 85 | --情况 永不下线 86 | 87 | 88 | s.start(...) 89 | -------------------------------------------------------------------------------- /Chapter3/rill4/service/login/init.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local s = require "service" 3 | 4 | s.client = {} 5 | s.resp.client = function(source, fd, cmd, msg) 6 | if s.client[cmd] then 7 | local ret_msg = s.client[cmd]( fd, msg, source) 8 | skynet.send(source, "lua", "send_by_fd", fd, ret_msg) 9 | else 10 | skynet.error("s.resp.client fail", cmd) 11 | end 12 | end 13 | 14 | s.client.login = function(fd, msg, source) 15 | local playerid = tonumber(msg[2]) 16 | local pw = tonumber(msg[3]) 17 | local gate = source 18 | node = skynet.getenv("node") 19 | --校验用户名密码 20 | if pw ~= 123 then 21 | return {"login", 1, "密码错误"} 22 | end 23 | --发给agentmgr 24 | local isok, agent = skynet.call("agentmgr", "lua", "reqlogin", playerid, node, gate) 25 | if not isok then 26 | return {"login", 1, "请求mgr失败"} 27 | end 28 | --回应gate 29 | local isok = skynet.call(gate, "lua", "sure_agent", fd, playerid, agent) 30 | if not isok then 31 | return {"login", 1, "gate注册失败"} 32 | end 33 | skynet.error("login succ "..playerid) 34 | return {"login", 0, "登陆成功"} 35 | end 36 | 37 | s.start(...) 38 | 39 | -------------------------------------------------------------------------------- /Chapter3/rill4/service/main.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local skynet_manager = require "skynet.manager" 3 | local runconfig = require "runconfig" 4 | local cluster = require "skynet.cluster" 5 | 6 | 7 | 8 | skynet.start(function() 9 | --初始化 10 | local mynode = skynet.getenv("node") 11 | local nodecfg = runconfig[mynode] 12 | --节点管理 13 | local nodemgr = skynet.newservice("nodemgr","nodemgr", 0) 14 | skynet.name("nodemgr", nodemgr) 15 | --集群 16 | cluster.reload(runconfig.cluster) 17 | cluster.open(mynode) 18 | --gate 19 | for i, v in pairs(nodecfg.gateway or {}) do 20 | local srv = skynet.newservice("gateway","gateway", i) 21 | skynet.name("gateway"..i, srv) 22 | end 23 | --login 24 | for i, v in pairs(nodecfg.login or {}) do 25 | local srv = skynet.newservice("login","login", i) 26 | skynet.name("login"..i, srv) 27 | end 28 | --agentmgr 29 | local anode = runconfig.agentmgr.node 30 | if mynode == anode then 31 | local srv = skynet.newservice("agentmgr", "agentmgr", 0) 32 | skynet.name("agentmgr", srv) 33 | else 34 | local proxy = cluster.proxy(anode, "agentmgr") 35 | skynet.name("agentmgr", proxy) 36 | end 37 | --scene (sid->sceneid) 38 | for _, sid in pairs(runconfig.scene[mynode] or {}) do 39 | local srv = skynet.newservice("scene", "scene", sid) 40 | skynet.name("scene"..sid, srv) 41 | end 42 | --退出自身 43 | skynet.exit() 44 | end) -------------------------------------------------------------------------------- /Chapter3/rill4/service/nodemgr/init.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local s = require "service" 3 | 4 | s.resp.newservice = function(source, name, ...) 5 | local srv = skynet.newservice(name, ...) 6 | return srv 7 | end 8 | 9 | s.start(...) -------------------------------------------------------------------------------- /Chapter3/rill4/service/scene/init.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local s = require "service" 3 | 4 | local balls = {} --[playerid] = ball 5 | local foods = {} --[id] = food 6 | local food_maxid = 0 7 | local food_count = 0 8 | --球 9 | function ball() 10 | local m = { 11 | playerid = nil, 12 | node = nil, 13 | agent = nil, 14 | x = math.random( 0, 100), 15 | y = math.random( 0, 100), 16 | size = 2, 17 | speedx = 0, 18 | speedy = 0, 19 | } 20 | return m 21 | end 22 | 23 | --食物 24 | function food() 25 | local m = { 26 | id = nil, 27 | x = math.random( 0, 100), 28 | y = math.random( 0, 100), 29 | } 30 | return m 31 | end 32 | 33 | --球列表 34 | local function balllist_msg() 35 | local msg = {"balllist"} 36 | for i, v in pairs(balls) do 37 | table.insert( msg, v.playerid ) 38 | table.insert( msg, v.x ) 39 | table.insert( msg, v.y ) 40 | table.insert( msg, v.size ) 41 | end 42 | return msg 43 | end 44 | 45 | --食物列表 46 | local function foodlist_msg() 47 | local msg = {"foodlist"} 48 | for i, v in pairs(foods) do 49 | table.insert( msg, v.id ) 50 | table.insert( msg, v.x ) 51 | table.insert( msg, v.y ) 52 | end 53 | return msg 54 | end 55 | 56 | --广播 57 | function broadcast(msg) 58 | for i, v in pairs(balls) do 59 | s.send(v.node, v.agent, "send", msg) 60 | end 61 | end 62 | 63 | --进入 64 | s.resp.enter = function(source, playerid, node, agent) 65 | if balls[playerid] then 66 | return false 67 | end 68 | local b = ball() 69 | b.playerid = playerid 70 | b.node = node 71 | b.agent = agent 72 | --广播 73 | local entermsg = {"enter", playerid, b.x, b.y, b.size} 74 | broadcast(entermsg) 75 | --记录 76 | balls[playerid] = b 77 | --回应 78 | local ret_msg = {"enter",0,"进入成功"} 79 | s.send(b.node, b.agent, "send", ret_msg) 80 | --发战场信息 81 | s.send(b.node, b.agent, "send", balllist_msg()) 82 | s.send(b.node, b.agent, "send", foodlist_msg()) 83 | return true 84 | end 85 | 86 | --退出 87 | s.resp.leave = function(source, playerid) 88 | if not balls[playerid] then 89 | return false 90 | end 91 | balls[playerid] = nil 92 | 93 | local leavemsg = {"leave", playerid} 94 | broadcast(leavemsg) 95 | end 96 | 97 | --改变速度 98 | s.resp.shift = function(source, playerid, x, y) 99 | local b = balls[playerid] 100 | if not b then 101 | return false 102 | end 103 | b.speedx = x 104 | b.speedy = y 105 | end 106 | 107 | function food_update() 108 | if food_count > 50 then 109 | return 110 | end 111 | 112 | if math.random( 1,100) < 98 then 113 | return 114 | end 115 | 116 | food_maxid = food_maxid + 1 117 | food_count = food_count + 1 118 | local f = food() 119 | f.id = food_maxid 120 | foods[f.id] = f 121 | 122 | local msg = {"addfood", f.id, f.x, f.y} 123 | broadcast(msg) 124 | end 125 | 126 | function move_update() 127 | for i, v in pairs(balls) do 128 | v.x = v.x + v.speedx * 0.2 129 | v.y = v.y + v.speedy * 0.2 130 | if v.speedx ~= 0 or v.speedy ~= 0 then 131 | local msg = {"move", v.playerid, v.x, v.y} 132 | broadcast(msg) 133 | end 134 | end 135 | end 136 | 137 | function eat_update() 138 | for pid, b in pairs(balls) do 139 | for fid, f in pairs(foods) do 140 | if (b.x-f.x)^2 + (b.y-f.y)^2 < b.size^2 then 141 | b.size = b.size + 1 142 | food_count = food_count - 1 143 | local msg = {"eat", b.playerid, fid, b.size} 144 | broadcast(msg) 145 | foods[fid] = nil --warm 146 | end 147 | end 148 | end 149 | end 150 | 151 | function update(frame) 152 | food_update() 153 | move_update() 154 | eat_update() 155 | --碰撞略 156 | --分裂略 157 | end 158 | 159 | s.init = function() 160 | skynet.fork(function() 161 | --保持帧率执行 162 | local stime = skynet.now() 163 | local frame = 0 164 | while true do 165 | frame = frame + 1 166 | local isok, err = pcall(update, frame) 167 | if not isok then 168 | skynet.error(err) 169 | end 170 | local etime = skynet.now() 171 | local waittime = frame*20 - (etime - stime) 172 | if waittime <= 0 then 173 | waittime = 2 174 | end 175 | skynet.sleep(waittime) 176 | end 177 | end) 178 | end 179 | 180 | s.start(...) -------------------------------------------------------------------------------- /Chapter3/rill4/start.sh: -------------------------------------------------------------------------------- 1 | 2 | ./skynet/skynet ./etc/config.node$1 -------------------------------------------------------------------------------- /Chapter4/1_client.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter4/1_client.lua -------------------------------------------------------------------------------- /Chapter4/1_netpack.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter4/1_netpack.lua -------------------------------------------------------------------------------- /Chapter4/2_json.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local cjson = require "cjson" 3 | 4 | --协议测试 5 | function test3() 6 | local msg = { 7 | _cmd = "playerinfo", 8 | coin = 100, 9 | bag = { 10 | [1] = {1001,1}, --倚天剑*1 11 | [2] = {1005,5} --草药*5 12 | }, 13 | } 14 | --编码 15 | local buff_with_len = json_pack("playerinfo", msg) 16 | local len = string.len(buff_with_len) 17 | print("len:"..len) 18 | print(buff_with_len) 19 | --解码 20 | local format = string.format(">i2 c%d", len-2) 21 | local _, buff = string.unpack(format, buff_with_len) 22 | local cmd, umsg = json_unpack(buff) 23 | print("cmd:"..cmd) 24 | print("coin:"..umsg.coin) 25 | print("sword:"..umsg.bag[1][2]) 26 | end 27 | 28 | function json_pack(cmd, msg) 29 | msg._cmd = cmd 30 | local body = cjson.encode(msg) --协议体字节流 31 | local namelen = string.len(cmd) --协议名长度 32 | local bodylen = string.len(body) --协议体长度 33 | local len = namelen + bodylen + 2 --协议总长度 34 | local format = string.format("> i2 i2 c%d c%d", namelen, bodylen) 35 | local buff = string.pack(format, len, namelen, cmd, body) 36 | return buff 37 | end 38 | 39 | 40 | function json_unpack(buff) 41 | local len = string.len(buff) 42 | local namelen_format = string.format("> i2 c%d", len-2) 43 | local namelen, other = string.unpack(namelen_format, buff) 44 | local bodylen = len-2-namelen 45 | local format = string.format("> c%d c%d", namelen, bodylen) 46 | local cmd, bodybuff = string.unpack(format, other) 47 | 48 | local isok, msg = pcall(cjson.decode, bodybuff) 49 | if not isok or not msg or not msg._cmd or not cmd == msg._cmd then 50 | print("error") 51 | return 52 | end 53 | 54 | return cmd, msg 55 | end 56 | 57 | 58 | --解码测试 59 | function test2() 60 | local buff = [[{"_cmd":"enter","playerid":101,"x":10,"y":20,"size":1}]] 61 | local isok, msg = pcall(cjson.decode, buff) 62 | if isok then 63 | print(msg._cmd) -- enter 64 | print(msg.playerid) -- 101.0 65 | else 66 | print("error") 67 | end 68 | end 69 | 70 | --编码测试 71 | function test1() 72 | local msg = { 73 | _cmd = "balllist", 74 | balls = { 75 | [1] = {id=102, x=10, y=20, size=1}, 76 | [2] = {id=103, x=10, y=30, size=2}, 77 | } 78 | } 79 | local buff = cjson.encode(msg) 80 | print(buff) 81 | end 82 | 83 | skynet.start(function() 84 | test1() 85 | --test2() 86 | --test3() 87 | end) -------------------------------------------------------------------------------- /Chapter4/3_login.proto: -------------------------------------------------------------------------------- 1 | package login; 2 | message Login { 3 | required int32 id = 1; 4 | required string pw = 2; 5 | optional int32 result = 3; 6 | } -------------------------------------------------------------------------------- /Chapter4/3_protobuf.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter4/3_protobuf.lua -------------------------------------------------------------------------------- /Chapter4/4_database.lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter4/4_database.lua -------------------------------------------------------------------------------- /Chapter4/4_playerdata.proto: -------------------------------------------------------------------------------- 1 | package playerdata; 2 | 3 | message BaseInfo { 4 | required int32 playerid = 1; 5 | required int32 coin = 2; 6 | required string name = 3; 7 | required int32 level = 4; 8 | required int32 last_login_time = 5; 9 | } -------------------------------------------------------------------------------- /Chapter4/rill4/etc/config.node1: -------------------------------------------------------------------------------- 1 | --必须配置 2 | thread = 8 --启用多少个工作线程 3 | cpath = "./skynet/cservice/?.so" --用C编写的服务模块的位置 4 | bootstrap = "snlua bootstrap" --启动的第一个服务 5 | 6 | --bootstrap配置项 7 | start = "main" --主程序入口 8 | harbor = 0 --不使用主从节点模式 9 | 10 | --lua配置项 11 | lualoader = "./skynet/lualib/loader.lua" 12 | luaservice = "./service/?.lua;" .."./service/?/init.lua;".. "./skynet/service/?.lua;" 13 | lua_path = "./etc/?.lua;" .. "./lualib/?.lua;" .. "./skynet/lualib/?.lua;" .. "./skynet/lualib/?/init.lua" 14 | lua_cpath = "./luaclib/?.so;" .. "./skynet/luaclib/?.so" 15 | 16 | --后台模式 17 | --daemon = "./skynet.pid" 18 | --logger = "./userlog" 19 | 20 | --节点 21 | node = "node1" -------------------------------------------------------------------------------- /Chapter4/rill4/etc/config.node2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter4/rill4/etc/config.node2 -------------------------------------------------------------------------------- /Chapter4/rill4/etc/runconfig.lua: -------------------------------------------------------------------------------- 1 | return { 2 | --集群 3 | cluster = { 4 | node1 = "127.0.0.1:7771", 5 | node2 = "127.0.0.1:7772", 6 | }, 7 | --agentmgr 8 | agentmgr = { node = "node1" }, 9 | --scene 10 | scene = { 11 | node1 = {1001, 1002}, 12 | --node2 = {1003}, 13 | }, 14 | --节点1 15 | node1 = { 16 | gateway = { 17 | [1] = {port=8001}, 18 | [2] = {port=8002}, 19 | }, 20 | login = { 21 | [1] = {}, 22 | [2] = {}, 23 | }, 24 | }, 25 | 26 | --节点2 27 | node2 = { 28 | gateway = { 29 | [1] = {port=8011}, 30 | [2] = {port=8022}, 31 | }, 32 | login = { 33 | [1] = {}, 34 | [2] = {}, 35 | }, 36 | }, 37 | } -------------------------------------------------------------------------------- /Chapter4/rill4/luaclib/cjson.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter4/rill4/luaclib/cjson.so -------------------------------------------------------------------------------- /Chapter4/rill4/luaclib/protobuf.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter4/rill4/luaclib/protobuf.so -------------------------------------------------------------------------------- /Chapter4/rill4/lualib/cjson.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter4/rill4/lualib/cjson.so -------------------------------------------------------------------------------- /Chapter4/rill4/lualib/service.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local cluster = require "skynet.cluster" 3 | 4 | local M = { 5 | --类型和id 6 | name = "", 7 | id = 0, 8 | --回调函数 9 | exit = nil, 10 | init = nil, 11 | --分发方法 12 | resp = {}, 13 | } 14 | 15 | --[[ 16 | function exit_dispatch() 17 | if M.exit then 18 | M.exit() 19 | end 20 | skynet.ret() 21 | skynet.exit() 22 | end 23 | --]] 24 | 25 | function traceback(err) 26 | skynet.error(tostring(err)) 27 | skynet.error(debug.traceback()) 28 | end 29 | 30 | local dispatch = function(session, address, cmd, ...) 31 | local fun = M.resp[cmd] 32 | if not fun then 33 | skynet.ret() 34 | return 35 | end 36 | 37 | local ret = table.pack(xpcall(fun, traceback, address, ...)) 38 | local isok = ret[1] 39 | 40 | if not isok then 41 | skynet.ret() 42 | return 43 | end 44 | 45 | skynet.retpack(table.unpack(ret,2)) 46 | end 47 | 48 | function init() 49 | skynet.dispatch("lua", dispatch) 50 | if M.init then 51 | M.init() 52 | end 53 | end 54 | 55 | function M.call(node, srv, ...) 56 | local mynode = skynet.getenv("node") 57 | if node == mynode then 58 | return skynet.call(srv, "lua", ...) 59 | else 60 | return cluster.call(node, srv, ...) 61 | end 62 | end 63 | 64 | function M.send(node, srv, ...) 65 | local mynode = skynet.getenv("node") 66 | if node == mynode then 67 | return skynet.send(srv, "lua", ...) 68 | else 69 | return cluster.send(node, srv, ...) 70 | end 71 | end 72 | 73 | function M.start(name, id, ...) 74 | M.name = name 75 | M.id = tonumber(id) 76 | skynet.start(init) 77 | end 78 | 79 | M.resp.exit = function() 80 | if M.exit then 81 | M.exit() 82 | end 83 | skynet.ret() 84 | skynet.exit() 85 | end 86 | 87 | return M -------------------------------------------------------------------------------- /Chapter4/rill4/proto/login.pb: -------------------------------------------------------------------------------- 1 | 2 | E 3 | login.protologin"/ 4 | Login 5 | 6 | id ( 7 | 8 | pw (  9 | result ( -------------------------------------------------------------------------------- /Chapter4/rill4/proto/login.proto: -------------------------------------------------------------------------------- 1 | package login; 2 | 3 | message Login { 4 | required int32 id = 1; 5 | required string pw = 2; 6 | optional int32 result = 3; 7 | } 8 | -------------------------------------------------------------------------------- /Chapter4/rill4/service/admin/init.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local socket = require "skynet.socket" 3 | local s = require "service" 4 | local runconfig = require "runconfig" 5 | require "skynet.manager" 6 | 7 | function shutdown_gate() 8 | for node, _ in pairs(runconfig.cluster) do 9 | local nodecfg = runconfig[node] 10 | for i, v in pairs(nodecfg.gateway or {}) do 11 | local name = "gateway"..i 12 | s.call(node, name, "shutdown") 13 | end 14 | end 15 | end 16 | 17 | function shutdown_agent() 18 | local anode = runconfig.agentmgr.node 19 | while true do 20 | local online_num = s.call(anode, "agentmgr", "shutdown", 1) 21 | if online_num <= 0 then 22 | break 23 | end 24 | skynet.sleep(100) 25 | end 26 | end 27 | 28 | function stop() 29 | shutdown_agent() 30 | --... 31 | skynet.abort() 32 | return "ok" 33 | end 34 | 35 | function connect(fd, addr) 36 | socket.start(fd) 37 | socket.write(fd, "Please enter cmd\r\n") 38 | local cmd = socket.readline(fd, "\r\n") 39 | if cmd == "stop" then 40 | stop() 41 | else 42 | --...... 43 | end 44 | end 45 | 46 | s.init = function() 47 | local listenfd = socket.listen("127.0.0.1", 8888) 48 | socket.start(listenfd , connect) 49 | end 50 | 51 | 52 | s.start(...) -------------------------------------------------------------------------------- /Chapter4/rill4/service/agent/init.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local s = require "service" 3 | 4 | s.client = {} 5 | s.gate = nil 6 | 7 | require "scene" 8 | 9 | 10 | s.resp.client = function(source, cmd, msg) 11 | s.gate = source 12 | if s.client[cmd] then 13 | local ret_msg = s.client[cmd]( msg, source) 14 | if ret_msg then 15 | skynet.send(source, "lua", "send", s.id, ret_msg) 16 | end 17 | else 18 | skynet.error("s.resp.client fail", cmd) 19 | end 20 | end 21 | 22 | s.client.work = function(msg) 23 | s.data.coin = s.data.coin + 1 24 | return {"work", s.data.coin} 25 | end 26 | 27 | s.resp.kick = function(source) 28 | s.leave_scene() 29 | --在此处保存角色数据 30 | skynet.sleep(200) 31 | end 32 | 33 | s.resp.exit = function(source) 34 | skynet.exit() 35 | end 36 | 37 | s.resp.send = function(source, msg) 38 | skynet.send(s.gate, "lua", "send", s.id, msg) 39 | end 40 | 41 | --每天第一次登陆调用 42 | function first_login_day() 43 | skynet.error("first_login_day") 44 | end 45 | 46 | s.init = function( ) 47 | --playerid = s.id 48 | --在此处加载角色数据 49 | skynet.sleep(200) 50 | s.data = { 51 | coin = 100, 52 | hp = 200, 53 | } 54 | 55 | 56 | end 57 | 58 | s.start(...) -------------------------------------------------------------------------------- /Chapter4/rill4/service/agent/scene.lua: -------------------------------------------------------------------------------- 1 | 2 | local skynet = require "skynet" 3 | local s = require "service" 4 | local runconfig = require "runconfig" 5 | local mynode = skynet.getenv("node") 6 | 7 | s.snode = nil --scene_node 8 | s.sname = nil --scene_id 9 | 10 | local function random_scene() 11 | --选择node 12 | local nodes = {} 13 | for i, v in pairs(runconfig.scene) do 14 | table.insert(nodes, i) 15 | if runconfig.scene[mynode] then 16 | table.insert(nodes, mynode) 17 | end 18 | end 19 | local idx = math.random( 1, #nodes) 20 | local scenenode = nodes[idx] 21 | --具体场景 22 | local scenelist = runconfig.scene[scenenode] 23 | local idx = math.random( 1, #scenelist) 24 | local sceneid = scenelist[idx] 25 | return scenenode, sceneid 26 | end 27 | 28 | s.client.enter = function(msg) 29 | if s.sname then 30 | return {"enter",1,"已在场景"} 31 | end 32 | local snode, sid = random_scene() 33 | local sname = "scene"..sid 34 | local isok = s.call(snode, sname, "enter", s.id, mynode, skynet.self()) 35 | if not isok then 36 | return {"enter",1,"进入失败"} 37 | end 38 | s.snode = snode 39 | s.sname = sname 40 | return nil 41 | end 42 | 43 | --改变方向 44 | s.client.shift = function(msg) 45 | if not s.sname then 46 | return 47 | end 48 | local x = msg[2] or 0 49 | local y = msg[3] or 0 50 | s.call(s.snode, s.sname, "shift", s.id, x, y) 51 | end 52 | 53 | s.leave_scene = function() 54 | --不在场景 55 | if not s.sname then 56 | return 57 | end 58 | s.call(s.snode, s.sname, "leave", s.id) 59 | s.snode = nil 60 | s.sname = nil 61 | end -------------------------------------------------------------------------------- /Chapter4/rill4/service/agentmgr/init.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local s = require "service" 3 | 4 | --状态 5 | STATUS = { 6 | LOGIN = 2, 7 | GAME = 3, 8 | LOGOUT = 4, 9 | } 10 | 11 | --玩家列表 12 | local players = {} 13 | 14 | --玩家类 15 | function mgrplayer() 16 | local m = { 17 | playerid = nil, 18 | node = nil, 19 | agent = nil, 20 | status = nil, 21 | gate = nil, 22 | } 23 | return m 24 | end 25 | 26 | s.resp.reqlogin = function(source, playerid, node, gate) 27 | local mplayer = players[playerid] 28 | --登陆过程禁止顶替 29 | if mplayer and mplayer.status == STATUS.LOGOUT then 30 | skynet.error("reqlogin fail, at status LOGOUT " ..playerid ) 31 | return false 32 | end 33 | if mplayer and mplayer.status == STATUS.LOGIN then 34 | skynet.error("reqlogin fail, at status LOGIN " ..playerid) 35 | return false 36 | end 37 | --在线,顶替 38 | if mplayer then 39 | local pnode = mplayer.node 40 | local pagent = mplayer.agent 41 | local pgate = mplayer.gate 42 | mplayer.status = STATUS.LOGOUT, 43 | s.call(pnode, pagent, "kick") 44 | s.send(pnode, pagent, "exit") 45 | s.send(pnode, pgate, "send", playerid, {"kick","顶替下线"}) 46 | s.call(pnode, pgate, "kick", playerid) 47 | end 48 | --上线 49 | local player = mgrplayer() 50 | player.playerid = playerid 51 | player.node = node 52 | player.gate = gate 53 | player.agent = nil 54 | player.status = STATUS.LOGIN 55 | players[playerid] = player 56 | local agent = s.call(node, "nodemgr", "newservice", "agent", "agent", playerid) 57 | player.agent = agent 58 | player.status = STATUS.GAME 59 | return true, agent 60 | end 61 | 62 | s.resp.reqkick = function(source, playerid, reason) 63 | local mplayer = players[playerid] 64 | if not mplayer then 65 | return false 66 | end 67 | 68 | if mplayer.status ~= STATUS.GAME then 69 | return false 70 | end 71 | 72 | local pnode = mplayer.node 73 | local pagent = mplayer.agent 74 | local pgate = mplayer.gate 75 | mplayer.status = STATUS.LOGOUT 76 | 77 | s.call(pnode, pagent, "kick") 78 | s.send(pnode, pagent, "exit") 79 | s.send(pnode, pgate, "kick", playerid) 80 | players[playerid] = nil 81 | 82 | return true 83 | end 84 | 85 | --获取在线人数 86 | function get_online_count() 87 | local count = 0 88 | for playerid, player in pairs(players) do 89 | count = count+1 90 | end 91 | return count 92 | end 93 | 94 | --将num数量的玩家踢下线 95 | s.resp.shutdown = function(source, num) 96 | --当前玩家数 97 | local count = get_online_count() 98 | --踢下线 99 | local n = 0 100 | for playerid, player in pairs(players) do 101 | skynet.fork(s.resp.reqkick, nil, playerid, "close server") 102 | n = n + 1 --计数,总共发num条下线消息 103 | if n >= num then 104 | break 105 | end 106 | end 107 | --等待玩家数下降 108 | while true do 109 | skynet.sleep(200) 110 | local new_count = get_online_count() 111 | skynet.error("shutdown online:"..new_count) 112 | if new_count <= 0 or new_count <= count-num then 113 | return new_count 114 | end 115 | end 116 | end 117 | 118 | 119 | 120 | 121 | 122 | --情况 永不下线 123 | 124 | 125 | 126 | 127 | 128 | s.start(...) 129 | -------------------------------------------------------------------------------- /Chapter4/rill4/service/login/init.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local s = require "service" 3 | 4 | s.client = {} 5 | s.resp.client = function(source, fd, cmd, msg) 6 | if s.client[cmd] then 7 | local ret_msg = s.client[cmd]( fd, msg, source) 8 | skynet.send(source, "lua", "send_by_fd", fd, ret_msg) 9 | else 10 | skynet.error("s.resp.client fail", cmd) 11 | end 12 | end 13 | 14 | s.client.login = function(fd, msg, source) 15 | local playerid = tonumber(msg[2]) 16 | local pw = tonumber(msg[3]) 17 | local gate = source 18 | node = skynet.getenv("node") 19 | --校验用户名密码 20 | if pw ~= 123 then 21 | return {"login", 1, "密码错误"} 22 | end 23 | --发给agentmgr 24 | local isok, agent = skynet.call("agentmgr", "lua", "reqlogin", playerid, node, gate) 25 | if not isok then 26 | return {"login", 1, "请求mgr失败"} 27 | end 28 | --回应gate 29 | local isok = skynet.call(gate, "lua", "sure_agent", fd, playerid, agent) 30 | if not isok then 31 | return {"login", 1, "gate注册失败"} 32 | end 33 | skynet.error("login succ "..playerid) 34 | return {"login", 0, "登陆成功"} 35 | end 36 | 37 | s.start(...) 38 | 39 | -------------------------------------------------------------------------------- /Chapter4/rill4/service/main.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local skynet_manager = require "skynet.manager" 3 | local runconfig = require "runconfig" 4 | local cluster = require "skynet.cluster" 5 | 6 | 7 | 8 | skynet.start(function() 9 | --初始化 10 | local mynode = skynet.getenv("node") 11 | local nodecfg = runconfig[mynode] 12 | --节点管理 13 | local nodemgr = skynet.newservice("nodemgr","nodemgr", 0) 14 | skynet.name("nodemgr", nodemgr) 15 | --集群 16 | cluster.reload(runconfig.cluster) 17 | cluster.open(mynode) 18 | --gate 19 | for i, v in pairs(nodecfg.gateway or {}) do 20 | local srv = skynet.newservice("gateway","gateway", i) 21 | skynet.name("gateway"..i, srv) 22 | end 23 | --login 24 | for i, v in pairs(nodecfg.login or {}) do 25 | local srv = skynet.newservice("login","login", i) 26 | skynet.name("login"..i, srv) 27 | end 28 | --agentmgr 29 | local anode = runconfig.agentmgr.node 30 | if mynode == anode then 31 | local srv = skynet.newservice("agentmgr", "agentmgr", 0) 32 | skynet.name("agentmgr", srv) 33 | else 34 | local proxy = cluster.proxy(anode, "agentmgr") 35 | skynet.name("agentmgr", proxy) 36 | end 37 | --scene (sid->sceneid) 38 | for _, sid in pairs(runconfig.scene[mynode] or {}) do 39 | local srv = skynet.newservice("scene", "scene", sid) 40 | skynet.name("scene"..sid, srv) 41 | end 42 | --admin 43 | local admin_node = "node1" --读runconfig配置 44 | if mynode == anode then 45 | skynet.newservice("admin", "admin", 0) 46 | end 47 | --退出自身 48 | skynet.exit() 49 | end) -------------------------------------------------------------------------------- /Chapter4/rill4/service/nodemgr/init.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local s = require "service" 3 | 4 | s.resp.newservice = function(source, name, ...) 5 | local srv = skynet.newservice(name, ...) 6 | return srv 7 | end 8 | 9 | s.start(...) -------------------------------------------------------------------------------- /Chapter4/rill4/service/scene/init.lua: -------------------------------------------------------------------------------- 1 | local skynet = require "skynet" 2 | local s = require "service" 3 | 4 | local balls = {} --[playerid] = ball 5 | local foods = {} --[id] = food 6 | local food_maxid = 0 7 | local food_count = 0 8 | --球 9 | function ball() 10 | local m = { 11 | playerid = nil, 12 | node = nil, 13 | agent = nil, 14 | x = math.random( 0, 100), 15 | y = math.random( 0, 100), 16 | size = 2, 17 | speedx = 0, 18 | speedy = 0, 19 | } 20 | return m 21 | end 22 | 23 | --食物 24 | function food() 25 | local m = { 26 | id = nil, 27 | x = math.random( 0, 100), 28 | y = math.random( 0, 100), 29 | } 30 | return m 31 | end 32 | 33 | --球列表 34 | local function balllist_msg() 35 | local msg = {"balllist"} 36 | for i, v in pairs(balls) do 37 | table.insert( msg, v.playerid ) 38 | table.insert( msg, v.x ) 39 | table.insert( msg, v.y ) 40 | table.insert( msg, v.size ) 41 | end 42 | return msg 43 | end 44 | 45 | --食物列表 46 | local function foodlist_msg() 47 | local msg = {"foodlist"} 48 | for i, v in pairs(foods) do 49 | table.insert( msg, v.id ) 50 | table.insert( msg, v.x ) 51 | table.insert( msg, v.y ) 52 | end 53 | return msg 54 | end 55 | 56 | --广播 57 | function broadcast(msg) 58 | for i, v in pairs(balls) do 59 | s.send(v.node, v.agent, "send", msg) 60 | end 61 | end 62 | 63 | --进入 64 | s.resp.enter = function(source, playerid, node, agent) 65 | if balls[playerid] then 66 | return false 67 | end 68 | local b = ball() 69 | b.playerid = playerid 70 | b.node = node 71 | b.agent = agent 72 | --广播 73 | local entermsg = {"enter", playerid, b.x, b.y, b.size} 74 | broadcast(entermsg) 75 | --记录 76 | balls[playerid] = b 77 | --回应 78 | local ret_msg = {"enter",0,"进入成功"} 79 | s.send(b.node, b.agent, "send", ret_msg) 80 | --发战场信息 81 | s.send(b.node, b.agent, "send", balllist_msg()) 82 | s.send(b.node, b.agent, "send", foodlist_msg()) 83 | return true 84 | end 85 | 86 | --退出 87 | s.resp.leave = function(source, playerid) 88 | if not balls[playerid] then 89 | return false 90 | end 91 | balls[playerid] = nil 92 | 93 | local leavemsg = {"leave", playerid} 94 | broadcast(leavemsg) 95 | end 96 | 97 | --改变速度 98 | s.resp.shift = function(source, playerid, x, y) 99 | local b = balls[playerid] 100 | if not b then 101 | return false 102 | end 103 | b.speedx = x 104 | b.speedy = y 105 | end 106 | 107 | function food_update() 108 | if food_count > 50 then 109 | return 110 | end 111 | 112 | if math.random( 1,100) < 98 then 113 | return 114 | end 115 | 116 | food_maxid = food_maxid + 1 117 | food_count = food_count + 1 118 | local f = food() 119 | f.id = food_maxid 120 | foods[f.id] = f 121 | 122 | local msg = {"addfood", f.id, f.x, f.y} 123 | broadcast(msg) 124 | end 125 | 126 | function move_update() 127 | for i, v in pairs(balls) do 128 | v.x = v.x + v.speedx * 0.2 129 | v.y = v.y + v.speedy * 0.2 130 | if v.speedx ~= 0 or v.speedy ~= 0 then 131 | local msg = {"move", v.playerid, v.x, v.y} 132 | broadcast(msg) 133 | end 134 | end 135 | end 136 | 137 | function eat_update() 138 | for pid, b in pairs(balls) do 139 | for fid, f in pairs(foods) do 140 | if (b.x-f.x)^2 + (b.y-f.y)^2 < b.size^2 then 141 | b.size = b.size + 1 142 | food_count = food_count - 1 143 | local msg = {"eat", b.playerid, fid, b.size} 144 | broadcast(msg) 145 | foods[fid] = nil --warm 146 | end 147 | end 148 | end 149 | end 150 | 151 | function update(frame) 152 | food_update() 153 | move_update() 154 | eat_update() 155 | --碰撞略 156 | --分裂略 157 | end 158 | 159 | s.init = function() 160 | skynet.fork(function() 161 | --保持帧率执行 162 | local stime = skynet.now() 163 | local frame = 0 164 | while true do 165 | frame = frame + 1 166 | local isok, err = pcall(update, frame) 167 | if not isok then 168 | skynet.error(err) 169 | end 170 | local etime = skynet.now() 171 | local waittime = frame*20 - (etime - stime) 172 | if waittime <= 0 then 173 | waittime = 2 174 | end 175 | skynet.sleep(waittime) 176 | end 177 | end) 178 | end 179 | 180 | s.start(...) -------------------------------------------------------------------------------- /Chapter4/rill4/start.sh: -------------------------------------------------------------------------------- 1 | 2 | ./skynet/skynet ./etc/config.node$1 -------------------------------------------------------------------------------- /Chapter4/rill4/storage/playerdata.pb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter4/rill4/storage/playerdata.pb -------------------------------------------------------------------------------- /Chapter4/rill4/storage/playerdata.proto: -------------------------------------------------------------------------------- 1 | package playerdata; 2 | 3 | message BaseInfo { 4 | required int32 playerid = 1; 5 | required int32 coin = 2; 6 | required string name = 3; 7 | required int32 level = 4; 8 | required int32 last_login_time = 5; 9 | required int32 skin = 6 [default = 10]; 10 | } -------------------------------------------------------------------------------- /Chapter5/sunnet/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 项目名称 2 | project (sunnet) 3 | # CMake最低版本号要求 4 | cmake_minimum_required (VERSION 2.8) 5 | # 头文件目录 6 | include_directories(include) 7 | # 查找./src目录下的所有源文件,保存到DIR_SRCS变量 8 | aux_source_directory(./src DIR_SRCS) 9 | # 用C++11 10 | add_definitions(-std=c++11) 11 | # 指定生成目标文件 12 | add_executable(sunnet ${DIR_SRCS}) 13 | # 库文件 14 | find_package (Threads) 15 | target_link_libraries (sunnet ${CMAKE_THREAD_LIBS_INIT}) -------------------------------------------------------------------------------- /Chapter5/sunnet/build/sunnet: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter5/sunnet/build/sunnet -------------------------------------------------------------------------------- /Chapter5/sunnet/include/Msg.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | using namespace std; 4 | 5 | //消息基类 6 | class BaseMsg { 7 | public: 8 | enum TYPE { //消息类型 9 | SERVICE = 1, 10 | }; 11 | uint8_t type; //消息类型 12 | char load[999999]{}; //用于检测内存泄漏 13 | virtual ~BaseMsg(){}; 14 | }; 15 | 16 | //服务间消息 17 | class ServiceMsg : public BaseMsg { 18 | public: 19 | uint32_t source; //消息发送方 20 | shared_ptr buff; //消息内容 21 | size_t size; //消息内容大小 22 | }; 23 | 24 | -------------------------------------------------------------------------------- /Chapter5/sunnet/include/Service.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "Msg.h" 5 | 6 | using namespace std; 7 | 8 | class Service { 9 | public: 10 | //为效率灵活性放在public 11 | 12 | //唯一id 13 | uint32_t id; 14 | //类型 15 | shared_ptr type; 16 | // 是否正在退出 17 | bool isExiting = false; 18 | //消息列表 19 | queue> msgQueue; 20 | pthread_spinlock_t queueLock; 21 | //标记是否在全局队列 true:在队列中,或正在处理 22 | bool inGlobal = false; 23 | pthread_spinlock_t inGlobalLock; 24 | public: 25 | //构造和析构函数 26 | Service(); 27 | ~Service(); 28 | //回调函数(编写服务逻辑) 29 | void OnInit(); 30 | void OnMsg(shared_ptr msg); 31 | void OnExit(); 32 | //插入消息 33 | void PushMsg(shared_ptr msg); 34 | //执行消息 35 | bool ProcessMsg(); 36 | void ProcessMsgs(int max); 37 | //全局队列 38 | void SetInGlobal(bool isIn); 39 | private: 40 | //取出一条消息 41 | shared_ptr PopMsg(); 42 | }; -------------------------------------------------------------------------------- /Chapter5/sunnet/include/Sunnet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "Worker.h" 4 | #include "Service.h" 5 | #include 6 | 7 | class Worker; 8 | 9 | class Sunnet { 10 | public: 11 | //单例 12 | static Sunnet* inst; 13 | public: 14 | //构造函数 15 | Sunnet(); 16 | //初始化并开始 17 | void Start(); 18 | //等待运行 19 | void Wait(); 20 | //增删服务 21 | uint32_t NewService(shared_ptr type); 22 | void KillService(uint32_t id); //仅限服务自己调用 23 | //发送消息 24 | void Send(uint32_t toId, shared_ptr msg); 25 | //全局队列操作 26 | shared_ptr PopGlobalQueue(); 27 | void PushGlobalQueue(shared_ptr srv); 28 | //让工作线程等待(仅工作线程调用) 29 | void WorkerWait(); 30 | //仅测试 31 | shared_ptr MakeMsg(uint32_t source, char* buff, int len); 32 | private: 33 | //工作线程 34 | int WORKER_NUM = 3; //工作线程数(配置) 35 | vector workers; //worker对象 36 | vector workerThreads; //线程 37 | //服务列表 38 | unordered_map> services; 39 | uint32_t maxId = 0; //最大ID 40 | pthread_rwlock_t servicesLock; //读写锁 41 | //全局队列 42 | queue> globalQueue; 43 | int globalLen = 0; //队列长度 44 | pthread_spinlock_t globalLock; //锁 45 | //休眠和唤醒 46 | pthread_mutex_t sleepMtx; 47 | pthread_cond_t sleepCond; 48 | int sleepCount = 0; //休眠工作线程数 49 | 50 | private: 51 | //开启工作线程 52 | void StartWorker(); 53 | //唤醒工作线程 54 | void CheckAndWeakUp(); 55 | //获取服务 56 | shared_ptr GetService(uint32_t id); 57 | }; -------------------------------------------------------------------------------- /Chapter5/sunnet/include/Worker.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "Sunnet.h" 4 | #include "Service.h" 5 | class Sunnet; 6 | 7 | using namespace std; 8 | 9 | class Worker { 10 | public: 11 | int id; //编号 12 | int eachNum; //每次处理多少条消息 13 | void operator()(); //线程函数 14 | private: 15 | //辅助函数 16 | void CheckAndPutGlobal(shared_ptr srv); 17 | }; -------------------------------------------------------------------------------- /Chapter5/sunnet/src/Service.cpp: -------------------------------------------------------------------------------- 1 | #include "Service.h" 2 | #include "Sunnet.h" 3 | #include 4 | 5 | //构造函数 6 | Service::Service() { 7 | //初始化锁 8 | pthread_spin_init(&queueLock, PTHREAD_PROCESS_PRIVATE);//看看参数有什么区别,Skynet怎么用的 9 | pthread_spin_init(&inGlobalLock, PTHREAD_PROCESS_PRIVATE); 10 | } 11 | 12 | //析构函数 13 | Service::~Service(){ 14 | pthread_spin_destroy(&queueLock); 15 | pthread_spin_destroy(&inGlobalLock); 16 | } 17 | 18 | //插入消息 19 | void Service::PushMsg(shared_ptr msg) { 20 | pthread_spin_lock(&queueLock); 21 | { 22 | msgQueue.push(msg); 23 | } 24 | pthread_spin_unlock(&queueLock); 25 | } 26 | 27 | //取出消息 28 | shared_ptr Service::PopMsg() { 29 | shared_ptr msg = NULL; 30 | //取一条消息 31 | pthread_spin_lock(&queueLock); 32 | { 33 | if (!msgQueue.empty()) { 34 | msg = msgQueue.front(); 35 | msgQueue.pop(); 36 | } 37 | } 38 | pthread_spin_unlock(&queueLock); 39 | return msg; 40 | } 41 | 42 | //处理一条消息,返回值代表是否处理 43 | bool Service::ProcessMsg() { 44 | shared_ptr msg = PopMsg(); 45 | if(msg) { 46 | OnMsg(msg); 47 | return true; 48 | } 49 | else { 50 | return false; 51 | } 52 | } 53 | 54 | //处理N条消息,返回值代表是否处理 55 | void Service::ProcessMsgs(int max) { 56 | for(int i=0; i msg) { 71 | //测试用 72 | if(msg->type == BaseMsg::TYPE::SERVICE) { 73 | auto m = dynamic_pointer_cast(msg); 74 | cout << "[" << id <<"] OnMsg " << m->buff << endl; 75 | 76 | auto msgRet = Sunnet::inst->MakeMsg(id, 77 | new char[9999999] { 'p', 'i', 'n', 'g', '\0' }, 9999999); 78 | 79 | Sunnet::inst->Send(m->source, msgRet); 80 | } 81 | else { 82 | cout << "[" << id <<"] OnMsg" << endl; 83 | } 84 | } 85 | 86 | //退出服务时触发 87 | void Service::OnExit() { 88 | cout << "[" << id <<"] OnExit" << endl; 89 | } 90 | 91 | void Service::SetInGlobal(bool isIn) { 92 | pthread_spin_lock(&inGlobalLock); 93 | { 94 | inGlobal = isIn; 95 | } 96 | pthread_spin_unlock(&inGlobalLock); 97 | } -------------------------------------------------------------------------------- /Chapter5/sunnet/src/Sunnet.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Sunnet.h" 3 | using namespace std; 4 | 5 | //单例 6 | Sunnet* Sunnet::inst; 7 | Sunnet::Sunnet(){ 8 | inst = this; 9 | } 10 | 11 | //开启worker线程 12 | void Sunnet::StartWorker() { 13 | for (int i = 0; i < WORKER_NUM; i++) { 14 | cout << "start worker thread:" << i << endl; 15 | //创建线程对象 16 | Worker* worker = new Worker(); 17 | worker->id = i; 18 | worker->eachNum = 2 << i; 19 | //创建线程 20 | thread* wt = new thread(*worker); 21 | //添加到列表 22 | workers.push_back(worker); 23 | workerThreads.push_back(wt); 24 | } 25 | } 26 | 27 | 28 | //开启系统 29 | void Sunnet::Start() { 30 | cout << "Hello Sunnet" << endl; 31 | //锁 32 | pthread_rwlock_init(&servicesLock, NULL); 33 | pthread_spin_init(&globalLock, PTHREAD_PROCESS_PRIVATE); 34 | pthread_cond_init(&sleepCond, NULL); 35 | pthread_mutex_init(&sleepMtx, NULL); 36 | //开启Worker 37 | StartWorker(); 38 | } 39 | 40 | //等待 41 | void Sunnet::Wait() { 42 | if( workerThreads[0]) { 43 | workerThreads[0]->join(); 44 | } 45 | } 46 | 47 | //新建服务 48 | uint32_t Sunnet::NewService(shared_ptr type) { 49 | auto srv = make_shared(); 50 | srv->type = type; 51 | pthread_rwlock_wrlock(&servicesLock); 52 | { 53 | srv->id = maxId; 54 | maxId++; 55 | services.emplace(srv->id, srv); 56 | } 57 | pthread_rwlock_unlock(&servicesLock); 58 | srv->OnInit(); //初始化 59 | return srv->id; 60 | } 61 | 62 | //由id查找服务 63 | shared_ptr Sunnet::GetService(uint32_t id) { 64 | shared_ptr srv = NULL; 65 | pthread_rwlock_rdlock(&servicesLock); 66 | { 67 | unordered_map>::iterator iter = services.find (id); 68 | if (iter != services.end()){ 69 | srv = iter->second; 70 | } 71 | } 72 | pthread_rwlock_unlock(&servicesLock); 73 | return srv; 74 | } 75 | 76 | //删除服务 77 | //只能service自己调自己,因为srv->OnExit、srv->isExiting不加锁 78 | void Sunnet::KillService(uint32_t id) { 79 | shared_ptr srv = GetService(id); 80 | if(!srv){ 81 | return; 82 | } 83 | //退出前 84 | srv->OnExit(); 85 | srv->isExiting = true; 86 | //删列表 87 | pthread_rwlock_wrlock(&servicesLock); 88 | { 89 | services.erase(id); 90 | } 91 | pthread_rwlock_unlock(&servicesLock); 92 | } 93 | 94 | 95 | //发送消息 96 | void Sunnet::Send(uint32_t toId, shared_ptr msg){ 97 | shared_ptr toSrv = GetService(toId); 98 | if(!toSrv){ 99 | cout << "Send fail, toSrv not exist toId:" << toId << endl; 100 | return; 101 | } 102 | toSrv->PushMsg(msg); 103 | //检查并放入全局队列 104 | //为缩小临界区灵活控制,破坏封装性 105 | bool hasPush = false; 106 | pthread_spin_lock(&toSrv->inGlobalLock); 107 | { 108 | if(!toSrv->inGlobal) { 109 | PushGlobalQueue(toSrv); 110 | toSrv->inGlobal = true; 111 | hasPush = true; 112 | } 113 | } 114 | pthread_spin_unlock(&toSrv->inGlobalLock); 115 | //唤起进程,不放在临界区里面 116 | if(hasPush) { 117 | CheckAndWeakUp(); 118 | } 119 | } 120 | 121 | //弹出全局队列 122 | shared_ptr Sunnet::PopGlobalQueue(){ 123 | shared_ptr srv = NULL; 124 | pthread_spin_lock(&globalLock); 125 | { 126 | if (!globalQueue.empty()) { 127 | srv = globalQueue.front(); 128 | globalQueue.pop(); 129 | globalLen--; 130 | } 131 | } 132 | pthread_spin_unlock(&globalLock); 133 | return srv; 134 | } 135 | 136 | //插入全局队列 137 | void Sunnet::PushGlobalQueue(shared_ptr srv){ 138 | pthread_spin_lock(&globalLock); 139 | { 140 | globalQueue.push(srv); 141 | globalLen++; 142 | } 143 | pthread_spin_unlock(&globalLock); 144 | } 145 | 146 | 147 | //仅测试用,buff须由new产生 148 | shared_ptr Sunnet::MakeMsg(uint32_t source, char* buff, int len) { 149 | auto msg= make_shared(); 150 | msg->type = BaseMsg::TYPE::SERVICE; 151 | msg->source = source; 152 | //基本类型的对象没有析构函数 153 | //所以回收基本类型组成的数组空间用delete 和 delete[]都可以 154 | //无需重新析构方法 155 | msg->buff = shared_ptr(buff); 156 | msg->size = len; 157 | return msg; 158 | } 159 | 160 | //Worker线程调用,进入休眠 161 | void Sunnet::WorkerWait(){ 162 | pthread_mutex_lock(&sleepMtx); 163 | sleepCount++; 164 | pthread_cond_wait(&sleepCond, &sleepMtx); 165 | sleepCount--; 166 | pthread_mutex_unlock(&sleepMtx); 167 | } 168 | 169 | 170 | //检查并唤醒线程 171 | void Sunnet::CheckAndWeakUp(){ 172 | //unsafe 173 | if(sleepCount == 0) { 174 | return; 175 | } 176 | if( WORKER_NUM - sleepCount <= globalLen ) { 177 | cout << "weakup" << endl; 178 | pthread_cond_signal(&sleepCond); 179 | } 180 | } -------------------------------------------------------------------------------- /Chapter5/sunnet/src/Worker.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "Worker.h" 4 | #include "Service.h" 5 | using namespace std; 6 | 7 | //那些调Sunnet的通过传参数解决 8 | //状态是不在队列中,global=true 9 | void Worker::CheckAndPutGlobal(shared_ptr srv) { 10 | //退出中(只能自己调退出,isExiting不会线程冲突) 11 | if(srv->isExiting){ 12 | return; 13 | } 14 | 15 | pthread_spin_lock(&srv->queueLock); 16 | { 17 | //重新放回全局队列 18 | if(!srv->msgQueue.empty()) { 19 | //此时srv->inGlobal一定是true 20 | Sunnet::inst->PushGlobalQueue(srv); 21 | } 22 | //不在队列中,重设inGlobal 23 | else { 24 | srv->SetInGlobal(false); 25 | } 26 | } 27 | pthread_spin_unlock(&srv->queueLock); 28 | } 29 | 30 | 31 | 32 | //线程函数 33 | void Worker::operator()() { 34 | while(true) { 35 | shared_ptr srv = Sunnet::inst->PopGlobalQueue(); 36 | if(!srv){ 37 | Sunnet::inst->WorkerWait(); 38 | } 39 | else{ 40 | srv->ProcessMsgs(eachNum); 41 | CheckAndPutGlobal(srv); 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /Chapter5/sunnet/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "Sunnet.h" 2 | 3 | 4 | int test() { 5 | auto pingType = make_shared("ping"); 6 | 7 | uint32_t ping1 = Sunnet::inst->NewService(pingType); 8 | uint32_t ping2 = Sunnet::inst->NewService(pingType); 9 | uint32_t pong = Sunnet::inst->NewService(pingType); 10 | 11 | auto msg1 = Sunnet::inst->MakeMsg(ping1, 12 | new char[3] { 'h', 'i', '\0' }, 3); 13 | auto msg2= Sunnet::inst->MakeMsg(ping2, 14 | new char[6] { 'h', 'e', 'l', 'l', 'o', '\0' }, 6); 15 | 16 | Sunnet::inst->Send(pong, msg1); 17 | Sunnet::inst->Send(pong, msg2); 18 | } 19 | 20 | int main() { 21 | new Sunnet(); 22 | Sunnet::inst->Start(); 23 | test(); 24 | Sunnet::inst->Wait(); 25 | return 0; 26 | } -------------------------------------------------------------------------------- /Chapter6/sunnet/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 项目名称 2 | project (sunnet) 3 | # CMake最低版本号要求 4 | cmake_minimum_required (VERSION 2.8) 5 | # 头文件目录 6 | include_directories(include) 7 | # 查找./src目录下的所有源文件,保存到DIR_SRCS变量 8 | aux_source_directory(./src DIR_SRCS) 9 | # 用C++11 10 | add_definitions(-std=c++11) 11 | # 指定生成目标文件 12 | add_executable(sunnet ${DIR_SRCS}) 13 | # 库文件 14 | find_package (Threads) 15 | target_link_libraries (sunnet ${CMAKE_THREAD_LIBS_INIT}) -------------------------------------------------------------------------------- /Chapter6/sunnet/include/Conn.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | using namespace std; 3 | 4 | class Conn { 5 | public: 6 | enum TYPE { //消息类型 7 | LISTEN = 1, 8 | CLIENT = 2, 9 | }; 10 | 11 | uint8_t type; 12 | int fd; 13 | uint32_t serviceId; 14 | 15 | }; -------------------------------------------------------------------------------- /Chapter6/sunnet/include/ConnWriter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | class WriteObject { 8 | public: 9 | streamsize start; 10 | streamsize len; 11 | shared_ptr buff; 12 | }; 13 | 14 | class ConnWriter { 15 | public: 16 | int fd; 17 | private: 18 | //是否正在关闭 19 | bool isClosing = false; 20 | list> objs; //双向链表 21 | public: 22 | void EntireWrite(shared_ptr buff, streamsize len); 23 | void LingerClose(); //全部发完完再关闭 24 | void OnWriteable(); 25 | private: 26 | void EntireWriteWhenEmpty(shared_ptr buff, streamsize len); 27 | void EntireWriteWhenNotEmpty(shared_ptr buff, streamsize len); 28 | bool WriteFrontObj(); 29 | }; -------------------------------------------------------------------------------- /Chapter6/sunnet/include/Msg.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | using namespace std; 4 | 5 | //消息基类 6 | class BaseMsg { 7 | public: 8 | enum TYPE { //消息类型 9 | SERVICE = 1, 10 | SOCKET_ACCEPT = 2, 11 | SOCKET_RW = 3, 12 | }; 13 | uint8_t type; //消息类型 14 | char load[999999]{}; //用于检测内存泄漏 15 | virtual ~BaseMsg(){}; 16 | }; 17 | 18 | //服务间消息 19 | class ServiceMsg : public BaseMsg { 20 | public: 21 | uint32_t source; //消息发送方 22 | shared_ptr buff; //消息内容 23 | size_t size; //消息内容大小 24 | }; 25 | 26 | //新连接 27 | class SocketAcceptMsg : public BaseMsg { 28 | public: 29 | int listenFd; 30 | int clientFd; 31 | }; 32 | 33 | //可读可写 34 | class SocketRWMsg : public BaseMsg { 35 | public: 36 | int fd; 37 | bool isRead = false; 38 | bool isWrite = false; 39 | }; -------------------------------------------------------------------------------- /Chapter6/sunnet/include/Service.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "Msg.h" 5 | #include "ConnWriter.h" 6 | #include 7 | 8 | using namespace std; 9 | 10 | class Service { 11 | public: 12 | //为效率灵活性放在public 13 | 14 | //唯一id 15 | uint32_t id; 16 | //类型 17 | shared_ptr type; 18 | // 是否正在退出 19 | bool isExiting = false; 20 | //消息列表 21 | queue> msgQueue; 22 | pthread_spinlock_t queueLock; 23 | //标记是否在全局队列 true:在队列中,或正在处理 24 | bool inGlobal = false; 25 | pthread_spinlock_t inGlobalLock; 26 | //业务逻辑(仅测试使用) 27 | unordered_map> writers; 28 | public: 29 | //构造和析构函数 30 | Service(); 31 | ~Service(); 32 | //回调函数(编写服务逻辑) 33 | void OnInit(); 34 | void OnMsg(shared_ptr msg); 35 | void OnExit(); 36 | //插入消息 37 | void PushMsg(shared_ptr msg); 38 | //执行消息 39 | bool ProcessMsg(); 40 | void ProcessMsgs(int max); 41 | //全局队列 42 | void SetInGlobal(bool isIn); 43 | private: 44 | //取出一条消息 45 | shared_ptr PopMsg(); 46 | //消息处理方法 47 | void OnServiceMsg(shared_ptr msg); 48 | void OnAcceptMsg(shared_ptr msg); 49 | void OnRWMsg(shared_ptr msg); 50 | void OnSocketData(int fd, const char* buff, int len); 51 | void OnSocketWritable(int fd); 52 | void OnSocketClose(int fd); 53 | }; -------------------------------------------------------------------------------- /Chapter6/sunnet/include/SocketWorker.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | using namespace std; 3 | #include 4 | #include 5 | #include "Conn.h" 6 | 7 | class SocketWorker { 8 | private: 9 | //epoll描述符 10 | int epollFd; 11 | public: 12 | void Init(); //初始化 13 | void operator()(); //线程函数 14 | public: 15 | void AddEvent(int fd); 16 | void RemoveEvent(int fd); 17 | void ModifyEvent(int fd, bool epollOut); 18 | private: 19 | void OnEvent(epoll_event ev); 20 | void OnAccept(shared_ptr conn); 21 | void OnRW(shared_ptr conn, bool r, bool w); 22 | }; -------------------------------------------------------------------------------- /Chapter6/sunnet/include/Sunnet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "Worker.h" 4 | #include "Service.h" 5 | #include 6 | #include "SocketWorker.h" 7 | #include "Conn.h" 8 | 9 | class Worker; 10 | 11 | class Sunnet { 12 | public: 13 | //单例 14 | static Sunnet* inst; 15 | public: 16 | //构造函数 17 | Sunnet(); 18 | //初始化并开始 19 | void Start(); 20 | //等待运行 21 | void Wait(); 22 | //增删服务 23 | uint32_t NewService(shared_ptr type); 24 | void KillService(uint32_t id); //仅限服务自己调用 25 | //发送消息 26 | void Send(uint32_t toId, shared_ptr msg); 27 | //全局队列操作 28 | shared_ptr PopGlobalQueue(); 29 | void PushGlobalQueue(shared_ptr srv); 30 | //让工作线程等待(仅工作线程调用) 31 | void WorkerWait(); 32 | //仅测试 33 | shared_ptr MakeMsg(uint32_t source, char* buff, int len); 34 | //增删查Conn 35 | int AddConn(int fd, uint32_t id, Conn::TYPE type); 36 | shared_ptr GetConn(int fd); 37 | bool RemoveConn(int fd); 38 | //网络连接操作接口(用原始read write) 39 | int Listen(uint32_t port, uint32_t serviceId); 40 | void CloseConn(uint32_t fd); 41 | //对外Event接口 42 | void ModifyEvent(int fd, bool epollOut); 43 | private: 44 | //工作线程 45 | int WORKER_NUM = 3; //工作线程数(配置) 46 | vector workers; //worker对象 47 | vector workerThreads; //线程 48 | //Socket线程 49 | SocketWorker* socketWorker; 50 | thread* socketThread; 51 | //服务列表 52 | unordered_map> services; 53 | uint32_t maxId = 0; //最大ID 54 | pthread_rwlock_t servicesLock; //读写锁 55 | //全局队列 56 | queue> globalQueue; 57 | int globalLen = 0; //队列长度 58 | pthread_spinlock_t globalLock; //锁 59 | //休眠和唤醒 60 | pthread_mutex_t sleepMtx; 61 | pthread_cond_t sleepCond; 62 | int sleepCount = 0; //休眠工作线程数 63 | //Conn列表 64 | unordered_map> conns; 65 | pthread_rwlock_t connsLock; //读写锁 66 | 67 | private: 68 | //开启工作线程 69 | void StartWorker(); 70 | //唤醒工作线程 71 | void CheckAndWeakUp(); 72 | //开启Socket线程 73 | void StartSocket(); 74 | //获取服务 75 | shared_ptr GetService(uint32_t id); 76 | }; -------------------------------------------------------------------------------- /Chapter6/sunnet/include/Worker.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "Sunnet.h" 4 | #include "Service.h" 5 | class Sunnet; 6 | 7 | using namespace std; 8 | 9 | class Worker { 10 | public: 11 | int id; //编号 12 | int eachNum; //每次处理多少条消息 13 | void operator()(); //线程函数 14 | private: 15 | //辅助函数 16 | void CheckAndPutGlobal(shared_ptr srv); 17 | }; -------------------------------------------------------------------------------- /Chapter6/sunnet/src/ConnWriter.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "ConnWriter.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | void ConnWriter::EntireWriteWhenEmpty(shared_ptr buff, streamsize len) { 10 | char* s = buff.get() ; 11 | //谨记:>=0, -1&&EAGAIN, -1&&EINTR, -1&&其他 12 | streamsize n = write(fd, s, len); 13 | if(n < 0 && errno == EINTR) { }; //仅提醒你要注意 14 | cout << "EntireWriteWhenEmpty write n=" << n << endl; 15 | //情况1-1:全部写完 16 | if(n >= 0 && n == len) { 17 | return; 18 | } 19 | //情况1-2:写一部分(或没写入) 20 | if( (n > 0 && n < len) || (n < 0 && errno == EAGAIN) ) { 21 | auto obj = make_shared(); 22 | obj->start = n; 23 | obj->buff = buff; 24 | obj->len = len; 25 | objs.push_back(obj); 26 | Sunnet::inst->ModifyEvent(fd, true); 27 | return; 28 | } 29 | //情况1-3:真的发生错误 30 | cout << "EntireWrite write error " << endl; 31 | } 32 | 33 | void ConnWriter::EntireWriteWhenNotEmpty(shared_ptr buff, streamsize len) { 34 | auto obj = make_shared(); 35 | obj->start = 0; 36 | obj->buff = buff; 37 | obj->len = len; 38 | objs.push_back(obj); 39 | } 40 | 41 | void ConnWriter::EntireWrite(shared_ptr buff, streamsize len) { 42 | if(isClosing){ 43 | cout << "EntireWrite fail, because isClosing" << endl; 44 | return; 45 | } 46 | //情况1:没有待写入数据,先尝试写入 47 | if(objs.empty()) { 48 | EntireWriteWhenEmpty(buff, len); 49 | } 50 | //情况2:有待写入数据,添加到末尾 51 | else{ 52 | EntireWriteWhenNotEmpty(buff, len); 53 | } 54 | } 55 | 56 | 57 | //返回值:是否完整的写入了一条 58 | bool ConnWriter::WriteFrontObj() { 59 | //没待写数据 60 | if(objs.empty()) { 61 | return false; 62 | } 63 | //获取第一条 64 | auto obj = objs.front(); 65 | 66 | //谨记:>=0, -1&&EAGAIN, -1&&EINTR, -1&&其他 67 | char* s = obj->buff.get() + obj->start; 68 | int len = obj->len - obj->start; 69 | int n = write(fd, s, len); 70 | cout << "WriteFrontObj write n=" << n << endl; 71 | if(n < 0 && errno == EINTR) { }; //仅提醒你要注意 72 | //情况1-1:全部写完 73 | if(n >= 0 && n == len) { 74 | objs.pop_front(); //出队 75 | return true; 76 | } 77 | //情况1-2:写一部分(或没写入) 78 | if( (n > 0 && n < len) || (n < 0 && errno == EAGAIN) ) { 79 | obj->start += n; 80 | return false; 81 | } 82 | //情况1-3:真的发生错误 83 | cout << "EntireWrite write error " << endl; 84 | } 85 | 86 | void ConnWriter::OnWriteable() { 87 | auto conn = Sunnet::inst->GetConn(fd); 88 | if(conn == NULL){ //连接已关闭 89 | return; 90 | } 91 | 92 | while(WriteFrontObj()){ 93 | //循环 94 | } 95 | 96 | if(objs.empty()) { 97 | Sunnet::inst->ModifyEvent(fd, false); 98 | 99 | if(isClosing) { 100 | //通知服务,此处并不是通用做法 101 | //让read产生 Bad file descriptor报错 102 | cout << "linger close conn" << endl; 103 | shutdown(fd, SHUT_RD); 104 | auto msg= make_shared(); 105 | msg->type = BaseMsg::TYPE::SOCKET_RW; 106 | msg->fd = conn->fd; 107 | msg->isRead = true; 108 | Sunnet::inst->Send(conn->serviceId, msg); 109 | } 110 | } 111 | } 112 | 113 | void ConnWriter::LingerClose(){ 114 | if(isClosing){ 115 | return; 116 | } 117 | isClosing = true; 118 | if(objs.empty()) { 119 | Sunnet::inst->CloseConn(fd); 120 | return; 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /Chapter6/sunnet/src/Service.cpp: -------------------------------------------------------------------------------- 1 | #include "Service.h" 2 | #include "Sunnet.h" 3 | #include 4 | #include 5 | #include 6 | 7 | //构造函数 8 | Service::Service() { 9 | //初始化锁 10 | pthread_spin_init(&queueLock, PTHREAD_PROCESS_PRIVATE);//看看参数有什么区别,Skynet怎么用的 11 | pthread_spin_init(&inGlobalLock, PTHREAD_PROCESS_PRIVATE); 12 | } 13 | 14 | //析构函数 15 | Service::~Service(){ 16 | pthread_spin_destroy(&queueLock); 17 | pthread_spin_destroy(&inGlobalLock); 18 | } 19 | 20 | //插入消息 21 | void Service::PushMsg(shared_ptr msg) { 22 | pthread_spin_lock(&queueLock); 23 | { 24 | msgQueue.push(msg); 25 | } 26 | pthread_spin_unlock(&queueLock); 27 | } 28 | 29 | //取出消息 30 | shared_ptr Service::PopMsg() { 31 | shared_ptr msg = NULL; 32 | //取一条消息 33 | pthread_spin_lock(&queueLock); 34 | { 35 | if (!msgQueue.empty()) { 36 | msg = msgQueue.front(); 37 | msgQueue.pop(); 38 | } 39 | } 40 | pthread_spin_unlock(&queueLock); 41 | return msg; 42 | } 43 | 44 | //处理一条消息,返回值代表是否处理 45 | bool Service::ProcessMsg() { 46 | shared_ptr msg = PopMsg(); 47 | if(msg) { 48 | OnMsg(msg); 49 | return true; 50 | } 51 | else { 52 | return false; 53 | } 54 | } 55 | 56 | //处理N条消息,返回值代表是否处理 57 | void Service::ProcessMsgs(int max) { 58 | for(int i=0; iSunnet::Listen(8002, id); 71 | } 72 | 73 | //收到客户端数据 74 | void Service::OnSocketData(int fd, const char* buff, int len) { 75 | cout << "OnSocketData" << fd << " buff: " << buff << endl; 76 | /* echo 77 | char wirteBuff[3] = {'l','p','y'}; 78 | write(fd, &wirteBuff, 3); 79 | */ 80 | /* 练习题新增行 81 | usleep(15000000); //15秒 82 | char wirteBuff2[3] = {'n','e','t'}; 83 | int r = write(fd, &wirteBuff2, 3); 84 | cout << "write2 r:" << r << " " << strerror(errno) << endl; 85 | */ 86 | /*PIPE实验新增行 87 | usleep(1000000); //1秒 88 | char wirteBuff3[2] = {'n','o'}; 89 | r = write(fd, &wirteBuff3,2); 90 | cout << "write3 r:" << r << " " << strerror(errno) << endl; 91 | */ 92 | /*发送大量数据实验 93 | char* wirteBuff = new char[4200000]; 94 | wirteBuff[4200000-1] = 'e'; 95 | int r = write(fd, wirteBuff, 4200000); 96 | cout << "write r:" << r << " " << strerror(errno) << endl; 97 | */ 98 | //用ConnWriter发送大量数据 99 | char* wirteBuff = new char[4200000]; 100 | wirteBuff[4200000-1] = 'e'; 101 | auto w = writers[fd]; 102 | w->EntireWrite(shared_ptr(wirteBuff), 4200000); 103 | w->LingerClose(); 104 | } 105 | 106 | //套接字可写 107 | void Service::OnSocketWritable(int fd) { 108 | cout << "OnSocketWritable " << fd << endl; 109 | auto w = writers[fd]; 110 | w->OnWriteable(); 111 | } 112 | 113 | //关闭连接前 114 | void Service::OnSocketClose(int fd) { 115 | writers.erase(fd); 116 | cout << "OnSocketClose " << fd << endl; 117 | } 118 | 119 | //收到其他服务发来的消息 120 | void Service::OnServiceMsg(shared_ptr msg) { 121 | cout << "OnServiceMsg " << endl; 122 | } 123 | 124 | //新连接 125 | void Service::OnAcceptMsg(shared_ptr msg) { 126 | cout << "OnAcceptMsg " << msg->clientFd << endl; 127 | auto w = make_shared(); 128 | w->fd = msg->clientFd; 129 | writers.emplace(msg->clientFd, w); 130 | } 131 | 132 | //套接字可读可写 133 | void Service::OnRWMsg(shared_ptr msg) { 134 | int fd = msg->fd; 135 | //可读 136 | if(msg->isRead) { 137 | const int BUFFSIZE = 512; 138 | char buff[BUFFSIZE]; 139 | int len = 0; 140 | do { 141 | len = read(fd, &buff, BUFFSIZE); 142 | if(len > 0){ 143 | OnSocketData(fd, buff, len); 144 | } 145 | }while(len == BUFFSIZE); 146 | 147 | if(len <= 0 && errno != EAGAIN) { 148 | if(Sunnet::inst->GetConn(fd)) { 149 | OnSocketClose(fd); 150 | Sunnet::inst->CloseConn(fd); 151 | } 152 | } 153 | } 154 | //可写(注意没有else) 155 | if(msg->isWrite) { 156 | if(Sunnet::inst->GetConn(fd)){ 157 | OnSocketWritable(fd); 158 | } 159 | } 160 | } 161 | 162 | 163 | 164 | //收到消息时触发 165 | void Service::OnMsg(shared_ptr msg) { 166 | //SERVICE 167 | if(msg->type == BaseMsg::TYPE::SERVICE) { 168 | auto m = dynamic_pointer_cast(msg); 169 | OnServiceMsg(m); 170 | } 171 | //SOCKET_ACCEPT 172 | else if(msg->type == BaseMsg::TYPE::SOCKET_ACCEPT) { 173 | auto m = dynamic_pointer_cast(msg); 174 | OnAcceptMsg(m); 175 | } 176 | //SOCKET_RW 177 | else if(msg->type == BaseMsg::TYPE::SOCKET_RW) { 178 | auto m = dynamic_pointer_cast(msg); 179 | OnRWMsg(m); 180 | } 181 | } 182 | 183 | 184 | //退出服务时触发 185 | void Service::OnExit() { 186 | cout << "[" << id <<"] OnExit" << endl; 187 | } 188 | 189 | void Service::SetInGlobal(bool isIn) { 190 | pthread_spin_lock(&inGlobalLock); 191 | { 192 | inGlobal = isIn; 193 | } 194 | pthread_spin_unlock(&inGlobalLock); 195 | } -------------------------------------------------------------------------------- /Chapter6/sunnet/src/SocketWorker.cpp: -------------------------------------------------------------------------------- 1 | #include "SocketWorker.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | //初始化 12 | void SocketWorker::Init() { 13 | cout << "SocketWorker Init" << endl; 14 | //创建epoll 15 | epollFd = epoll_create(1024); // 返回值:非负数:成功的描述符,-1失败 16 | assert(epollFd > 0); 17 | } 18 | 19 | 20 | void SocketWorker::OnAccept(shared_ptr conn) { 21 | cout << "OnAccept fd:" << conn->fd << endl; 22 | //步骤1:accept 23 | int clientFd = accept(conn->fd, NULL, NULL); 24 | if (clientFd < 0) { 25 | cout << "accept error" << endl; 26 | } 27 | //步骤2:设置非阻塞 28 | fcntl(clientFd, F_SETFL, O_NONBLOCK); 29 | //写缓冲区大小 30 | //unsigned long buffSize = 4294967295; 31 | //if(setsockopt(clientFd, SOL_SOCKET, SO_SNDBUFFORCE , &buffSize, sizeof(buffSize)) < 0){ 32 | // cout << "OnAccept setsockopt Fail " << strerror(errno) << endl; 33 | //} 34 | //步骤3:添加到管理结构 35 | Sunnet::inst->AddConn(clientFd, conn->serviceId, Conn::TYPE::CLIENT); 36 | //步骤4:添加到epoll 37 | struct epoll_event ev; 38 | ev.events = EPOLLIN | EPOLLET; 39 | ev.data.fd = clientFd; 40 | if (epoll_ctl(epollFd, EPOLL_CTL_ADD, clientFd, &ev) == -1) { 41 | cout << "OnAccept epoll_ctl Fail:" << strerror(errno) << endl; 42 | } 43 | //步骤5:通知 44 | auto msg= make_shared(); 45 | msg->type = BaseMsg::TYPE::SOCKET_ACCEPT; 46 | msg->listenFd = conn->fd; 47 | msg->clientFd = clientFd; 48 | Sunnet::inst->Send(conn->serviceId, msg); 49 | } 50 | 51 | void SocketWorker::OnRW(shared_ptr conn, bool r, bool w) { 52 | cout << "OnRW fd:" << conn->fd << endl; 53 | auto msg= make_shared(); 54 | msg->type = BaseMsg::TYPE::SOCKET_RW; 55 | msg->fd = conn->fd; 56 | msg->isRead = r; 57 | msg->isWrite = w; 58 | Sunnet::inst->Send(conn->serviceId, msg); 59 | } 60 | 61 | 62 | 63 | //处理事件 64 | void SocketWorker::OnEvent(epoll_event ev){ 65 | int fd = ev.data.fd; 66 | auto conn = Sunnet::inst->GetConn(fd); 67 | if(conn == NULL){ 68 | cout << "OnEvent error, conn == NULL" << endl; 69 | return; 70 | } 71 | //事件类型 72 | bool isRead = ev.events & EPOLLIN; 73 | bool isWrite = ev.events & EPOLLOUT; 74 | bool isError = ev.events & EPOLLERR; 75 | //监听Socket 76 | if(conn->type == Conn::TYPE::LISTEN){ 77 | if(isRead) { 78 | OnAccept(conn); 79 | } 80 | } 81 | //普通Socket 82 | else { 83 | if(isRead || isWrite) { 84 | OnRW(conn, isRead, isWrite); 85 | } 86 | if(isError){ 87 | cout << "OnError fd:" << conn->fd << endl; 88 | } 89 | } 90 | } 91 | 92 | void SocketWorker::operator()() { 93 | while(true) { 94 | //阻塞等待 95 | const int EVENT_SIZE = 64; 96 | struct epoll_event events[EVENT_SIZE]; 97 | int eventCount = epoll_wait(epollFd , events, EVENT_SIZE, -1); 98 | //取得事件 99 | for (int i=0; i 2 | #include 3 | #include "Worker.h" 4 | #include "Service.h" 5 | using namespace std; 6 | 7 | //那些调Sunnet的通过传参数解决 8 | //状态是不在队列中,global=true 9 | void Worker::CheckAndPutGlobal(shared_ptr srv) { 10 | //退出中(只能自己调退出,isExiting不会线程冲突) 11 | if(srv->isExiting){ 12 | return; 13 | } 14 | 15 | pthread_spin_lock(&srv->queueLock); 16 | { 17 | //重新放回全局队列 18 | if(!srv->msgQueue.empty()) { 19 | //此时srv->inGlobal一定是true 20 | Sunnet::inst->PushGlobalQueue(srv); 21 | } 22 | //不在队列中,重设inGlobal 23 | else { 24 | srv->SetInGlobal(false); 25 | } 26 | } 27 | pthread_spin_unlock(&srv->queueLock); 28 | } 29 | 30 | 31 | 32 | //线程函数 33 | void Worker::operator()() { 34 | while(true) { 35 | shared_ptr srv = Sunnet::inst->PopGlobalQueue(); 36 | if(!srv){ 37 | Sunnet::inst->WorkerWait(); 38 | } 39 | else{ 40 | srv->ProcessMsgs(eachNum); 41 | CheckAndPutGlobal(srv); 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /Chapter6/sunnet/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "Sunnet.h" 2 | #include 3 | #include 4 | 5 | int testConn() { 6 | Sunnet::inst->AddConn(1, 1, Conn::TYPE::LISTEN); 7 | Sunnet::inst->AddConn(2, 1, Conn::TYPE::CLIENT); 8 | Sunnet::inst->RemoveConn(2); 9 | cout << Sunnet::inst->GetConn(1).get() << endl; 10 | cout << Sunnet::inst->GetConn(2).get() << endl; 11 | } 12 | 13 | int testSocketCtrl() { 14 | int fd = Sunnet::inst->Listen(8001, 1); 15 | usleep(30*1000000); 16 | Sunnet::inst->CloseConn(fd); 17 | } 18 | 19 | 20 | int TestEcho() { 21 | auto t = make_shared("gateway"); 22 | uint32_t gateway = Sunnet::inst->NewService(t); 23 | } 24 | 25 | int main() { 26 | new Sunnet(); 27 | Sunnet::inst->Start(); 28 | TestEcho(); 29 | Sunnet::inst->Wait(); 30 | return 0; 31 | } -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for installing Lua 2 | # See doc/readme.html for installation and customization instructions. 3 | 4 | # == CHANGE THE SETTINGS BELOW TO SUIT YOUR ENVIRONMENT ======================= 5 | 6 | # Your platform. See PLATS for possible values. 7 | PLAT= none 8 | 9 | # Where to install. The installation starts in the src and doc directories, 10 | # so take care if INSTALL_TOP is not an absolute path. See the local target. 11 | # You may want to make INSTALL_LMOD and INSTALL_CMOD consistent with 12 | # LUA_ROOT, LUA_LDIR, and LUA_CDIR in luaconf.h. 13 | INSTALL_TOP= /usr/local 14 | INSTALL_BIN= $(INSTALL_TOP)/bin 15 | INSTALL_INC= $(INSTALL_TOP)/include 16 | INSTALL_LIB= $(INSTALL_TOP)/lib 17 | INSTALL_MAN= $(INSTALL_TOP)/man/man1 18 | INSTALL_LMOD= $(INSTALL_TOP)/share/lua/$V 19 | INSTALL_CMOD= $(INSTALL_TOP)/lib/lua/$V 20 | 21 | # How to install. If your install program does not support "-p", then 22 | # you may have to run ranlib on the installed liblua.a. 23 | INSTALL= install -p 24 | INSTALL_EXEC= $(INSTALL) -m 0755 25 | INSTALL_DATA= $(INSTALL) -m 0644 26 | # 27 | # If you don't have "install" you can use "cp" instead. 28 | # INSTALL= cp -p 29 | # INSTALL_EXEC= $(INSTALL) 30 | # INSTALL_DATA= $(INSTALL) 31 | 32 | # Other utilities. 33 | MKDIR= mkdir -p 34 | RM= rm -f 35 | 36 | # == END OF USER SETTINGS -- NO NEED TO CHANGE ANYTHING BELOW THIS LINE ======= 37 | 38 | # Convenience platforms targets. 39 | PLATS= aix bsd c89 freebsd generic linux macosx mingw posix solaris 40 | 41 | # What to install. 42 | TO_BIN= lua luac 43 | TO_INC= lua.h luaconf.h lualib.h lauxlib.h lua.hpp 44 | TO_LIB= liblua.a 45 | TO_MAN= lua.1 luac.1 46 | 47 | # Lua version and release. 48 | V= 5.3 49 | R= $V.4 50 | 51 | # Targets start here. 52 | all: $(PLAT) 53 | 54 | $(PLATS) clean: 55 | cd src && $(MAKE) $@ 56 | 57 | test: dummy 58 | src/lua -v 59 | 60 | install: dummy 61 | cd src && $(MKDIR) $(INSTALL_BIN) $(INSTALL_INC) $(INSTALL_LIB) $(INSTALL_MAN) $(INSTALL_LMOD) $(INSTALL_CMOD) 62 | cd src && $(INSTALL_EXEC) $(TO_BIN) $(INSTALL_BIN) 63 | cd src && $(INSTALL_DATA) $(TO_INC) $(INSTALL_INC) 64 | cd src && $(INSTALL_DATA) $(TO_LIB) $(INSTALL_LIB) 65 | cd doc && $(INSTALL_DATA) $(TO_MAN) $(INSTALL_MAN) 66 | 67 | uninstall: 68 | cd src && cd $(INSTALL_BIN) && $(RM) $(TO_BIN) 69 | cd src && cd $(INSTALL_INC) && $(RM) $(TO_INC) 70 | cd src && cd $(INSTALL_LIB) && $(RM) $(TO_LIB) 71 | cd doc && cd $(INSTALL_MAN) && $(RM) $(TO_MAN) 72 | 73 | local: 74 | $(MAKE) install INSTALL_TOP=../install 75 | 76 | none: 77 | @echo "Please do 'make PLATFORM' where PLATFORM is one of these:" 78 | @echo " $(PLATS)" 79 | @echo "See doc/readme.html for complete instructions." 80 | 81 | # make may get confused with test/ and install/ 82 | dummy: 83 | 84 | # echo config parameters 85 | echo: 86 | @cd src && $(MAKE) -s echo 87 | @echo "PLAT= $(PLAT)" 88 | @echo "V= $V" 89 | @echo "R= $R" 90 | @echo "TO_BIN= $(TO_BIN)" 91 | @echo "TO_INC= $(TO_INC)" 92 | @echo "TO_LIB= $(TO_LIB)" 93 | @echo "TO_MAN= $(TO_MAN)" 94 | @echo "INSTALL_TOP= $(INSTALL_TOP)" 95 | @echo "INSTALL_BIN= $(INSTALL_BIN)" 96 | @echo "INSTALL_INC= $(INSTALL_INC)" 97 | @echo "INSTALL_LIB= $(INSTALL_LIB)" 98 | @echo "INSTALL_MAN= $(INSTALL_MAN)" 99 | @echo "INSTALL_LMOD= $(INSTALL_LMOD)" 100 | @echo "INSTALL_CMOD= $(INSTALL_CMOD)" 101 | @echo "INSTALL_EXEC= $(INSTALL_EXEC)" 102 | @echo "INSTALL_DATA= $(INSTALL_DATA)" 103 | 104 | # echo pkg-config data 105 | pc: 106 | @echo "version=$R" 107 | @echo "prefix=$(INSTALL_TOP)" 108 | @echo "libdir=$(INSTALL_LIB)" 109 | @echo "includedir=$(INSTALL_INC)" 110 | 111 | # list targets that do not create files (but not all makes understand .PHONY) 112 | .PHONY: all $(PLATS) clean test install local none dummy echo pecho lecho 113 | 114 | # (end of Makefile) 115 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/README: -------------------------------------------------------------------------------- 1 | 2 | This is Lua 5.3.5, released on 26 Jun 2018. 3 | 4 | For installation instructions, license details, and 5 | further information about Lua, see doc/readme.html. 6 | 7 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/doc/index.css: -------------------------------------------------------------------------------- 1 | ul { 2 | list-style-type: none ; 3 | } 4 | 5 | ul.contents { 6 | padding: 0 ; 7 | } 8 | 9 | table { 10 | border: none ; 11 | border-spacing: 0 ; 12 | border-collapse: collapse ; 13 | } 14 | 15 | td { 16 | vertical-align: top ; 17 | padding: 0 ; 18 | text-align: left ; 19 | line-height: 1.25 ; 20 | width: 15% ; 21 | } 22 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/doc/logo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/doc/logo.gif -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/doc/lua.1: -------------------------------------------------------------------------------- 1 | .\" $Id: lua.man,v 1.14 2016/10/17 15:43:50 lhf Exp $ 2 | .TH LUA 1 "$Date: 2016/10/17 15:43:50 $" 3 | .SH NAME 4 | lua \- Lua interpreter 5 | .SH SYNOPSIS 6 | .B lua 7 | [ 8 | .I options 9 | ] 10 | [ 11 | .I script 12 | [ 13 | .I args 14 | ] 15 | ] 16 | .SH DESCRIPTION 17 | .B lua 18 | is the standalone Lua interpreter. 19 | It loads and executes Lua programs, 20 | either in textual source form or 21 | in precompiled binary form. 22 | (Precompiled binaries are output by 23 | .BR luac , 24 | the Lua compiler.) 25 | .B lua 26 | can be used as a batch interpreter and also interactively. 27 | .LP 28 | The given 29 | .I options 30 | are handled in order and then 31 | the Lua program in file 32 | .I script 33 | is loaded and executed. 34 | The given 35 | .I args 36 | are available to 37 | .I script 38 | as strings in a global table named 39 | .BR arg . 40 | If no options or arguments are given, 41 | then 42 | .B "\-v \-i" 43 | is assumed when the standard input is a terminal; 44 | otherwise, 45 | .B "\-" 46 | is assumed. 47 | .LP 48 | In interactive mode, 49 | .B lua 50 | prompts the user, 51 | reads lines from the standard input, 52 | and executes them as they are read. 53 | If the line contains an expression or list of expressions, 54 | then the line is evaluated and the results are printed. 55 | If a line does not contain a complete statement, 56 | then a secondary prompt is displayed and 57 | lines are read until a complete statement is formed or 58 | a syntax error is found. 59 | .LP 60 | At the very start, 61 | before even handling the command line, 62 | .B lua 63 | checks the contents of the environment variables 64 | .B LUA_INIT_5_3 65 | or 66 | .BR LUA_INIT , 67 | in that order. 68 | If the contents is of the form 69 | .RI '@ filename ', 70 | then 71 | .I filename 72 | is executed. 73 | Otherwise, the string is assumed to be a Lua statement and is executed. 74 | .SH OPTIONS 75 | .TP 76 | .BI \-e " stat" 77 | execute statement 78 | .IR stat . 79 | .TP 80 | .B \-i 81 | enter interactive mode after executing 82 | .IR script . 83 | .TP 84 | .BI \-l " name" 85 | execute the equivalent of 86 | .IB name =require(' name ') 87 | before executing 88 | .IR script . 89 | .TP 90 | .B \-v 91 | show version information. 92 | .TP 93 | .B \-E 94 | ignore environment variables. 95 | .TP 96 | .B \-\- 97 | stop handling options. 98 | .TP 99 | .B \- 100 | stop handling options and execute the standard input as a file. 101 | .SH "SEE ALSO" 102 | .BR luac (1) 103 | .br 104 | The documentation at lua.org, 105 | especially section 7 of the reference manual. 106 | .SH DIAGNOSTICS 107 | Error messages should be self explanatory. 108 | .SH AUTHORS 109 | R. Ierusalimschy, 110 | L. H. de Figueiredo, 111 | W. Celes 112 | .\" EOF 113 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/doc/lua.css: -------------------------------------------------------------------------------- 1 | html { 2 | background-color: #F8F8F8 ; 3 | } 4 | 5 | body { 6 | background-color: #FFFFFF ; 7 | color: #000000 ; 8 | font-family: Helvetica, Arial, sans-serif ; 9 | text-align: justify ; 10 | line-height: 1.25 ; 11 | margin: 16px auto ; 12 | padding: 32px ; 13 | border: solid #ccc 1px ; 14 | border-radius: 20px ; 15 | max-width: 70em ; 16 | width: 90% ; 17 | } 18 | 19 | h1, h2, h3, h4 { 20 | color: #000080 ; 21 | font-family: Verdana, Geneva, sans-serif ; 22 | font-weight: normal ; 23 | font-style: normal ; 24 | text-align: left ; 25 | } 26 | 27 | h1 { 28 | font-size: 28pt ; 29 | } 30 | 31 | h1 img { 32 | vertical-align: text-bottom ; 33 | } 34 | 35 | h2:before { 36 | content: "\2756" ; 37 | padding-right: 0.5em ; 38 | } 39 | 40 | a { 41 | text-decoration: none ; 42 | } 43 | 44 | a:link { 45 | color: #000080 ; 46 | } 47 | 48 | a:link:hover, a:visited:hover { 49 | background-color: #D0D0FF ; 50 | color: #000080 ; 51 | border-radius: 4px ; 52 | } 53 | 54 | a:link:active, a:visited:active { 55 | color: #FF0000 ; 56 | } 57 | 58 | div.menubar { 59 | padding-bottom: 0.5em ; 60 | } 61 | 62 | p.menubar { 63 | margin-left: 2.5em ; 64 | } 65 | 66 | .menubar a:hover { 67 | margin: -3px -3px -3px -3px ; 68 | padding: 3px 3px 3px 3px ; 69 | border-radius: 4px ; 70 | } 71 | 72 | :target { 73 | background-color: #F0F0F0 ; 74 | margin: -8px ; 75 | padding: 8px ; 76 | border-radius: 8px ; 77 | outline: none ; 78 | } 79 | 80 | hr { 81 | display: none ; 82 | } 83 | 84 | table hr { 85 | background-color: #a0a0a0 ; 86 | color: #a0a0a0 ; 87 | border: 0 ; 88 | height: 1px ; 89 | display: block ; 90 | } 91 | 92 | .footer { 93 | color: gray ; 94 | font-size: x-small ; 95 | text-transform: lowercase ; 96 | } 97 | 98 | input[type=text] { 99 | border: solid #a0a0a0 2px ; 100 | border-radius: 2em ; 101 | background-image: url('images/search.png') ; 102 | background-repeat: no-repeat ; 103 | background-position: 4px center ; 104 | padding-left: 20px ; 105 | height: 2em ; 106 | } 107 | 108 | pre.session { 109 | background-color: #F8F8F8 ; 110 | padding: 1em ; 111 | border-radius: 8px ; 112 | } 113 | 114 | table { 115 | border: none ; 116 | border-spacing: 0 ; 117 | border-collapse: collapse ; 118 | } 119 | 120 | td { 121 | padding: 0 ; 122 | margin: 0 ; 123 | } 124 | 125 | td.gutter { 126 | width: 4% ; 127 | } 128 | 129 | table.columns td { 130 | vertical-align: top ; 131 | padding-bottom: 1em ; 132 | text-align: justify ; 133 | line-height: 1.25 ; 134 | } 135 | 136 | table.book td { 137 | vertical-align: top ; 138 | } 139 | 140 | table.book td.cover { 141 | padding-right: 1em ; 142 | } 143 | 144 | table.book img { 145 | border: solid #000080 1px ; 146 | } 147 | 148 | table.book span { 149 | font-size: small ; 150 | text-align: left ; 151 | display: block ; 152 | margin-top: 0.25em ; 153 | } 154 | 155 | p.logos a:link:hover, p.logos a:visited:hover { 156 | background-color: inherit ; 157 | } 158 | 159 | img { 160 | background-color: white ; 161 | } 162 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/doc/luac.1: -------------------------------------------------------------------------------- 1 | .\" $Id: luac.man,v 1.29 2011/11/16 13:53:40 lhf Exp $ 2 | .TH LUAC 1 "$Date: 2011/11/16 13:53:40 $" 3 | .SH NAME 4 | luac \- Lua compiler 5 | .SH SYNOPSIS 6 | .B luac 7 | [ 8 | .I options 9 | ] [ 10 | .I filenames 11 | ] 12 | .SH DESCRIPTION 13 | .B luac 14 | is the Lua compiler. 15 | It translates programs written in the Lua programming language 16 | into binary files containing precompiled chunks 17 | that can be later loaded and executed. 18 | .LP 19 | The main advantages of precompiling chunks are: 20 | faster loading, 21 | protecting source code from accidental user changes, 22 | and 23 | off-line syntax checking. 24 | Precompiling does not imply faster execution 25 | because in Lua chunks are always compiled into bytecodes before being executed. 26 | .B luac 27 | simply allows those bytecodes to be saved in a file for later execution. 28 | Precompiled chunks are not necessarily smaller than the corresponding source. 29 | The main goal in precompiling is faster loading. 30 | .LP 31 | In the command line, 32 | you can mix 33 | text files containing Lua source and 34 | binary files containing precompiled chunks. 35 | .B luac 36 | produces a single output file containing the combined bytecodes 37 | for all files given. 38 | Executing the combined file is equivalent to executing the given files. 39 | By default, 40 | the output file is named 41 | .BR luac.out , 42 | but you can change this with the 43 | .B \-o 44 | option. 45 | .LP 46 | Precompiled chunks are 47 | .I not 48 | portable across different architectures. 49 | Moreover, 50 | the internal format of precompiled chunks 51 | is likely to change when a new version of Lua is released. 52 | Make sure you save the source files of all Lua programs that you precompile. 53 | .LP 54 | .SH OPTIONS 55 | .TP 56 | .B \-l 57 | produce a listing of the compiled bytecode for Lua's virtual machine. 58 | Listing bytecodes is useful to learn about Lua's virtual machine. 59 | If no files are given, then 60 | .B luac 61 | loads 62 | .B luac.out 63 | and lists its contents. 64 | Use 65 | .B \-l \-l 66 | for a full listing. 67 | .TP 68 | .BI \-o " file" 69 | output to 70 | .IR file , 71 | instead of the default 72 | .BR luac.out . 73 | (You can use 74 | .B "'\-'" 75 | for standard output, 76 | but not on platforms that open standard output in text mode.) 77 | The output file may be one of the given files because 78 | all files are loaded before the output file is written. 79 | Be careful not to overwrite precious files. 80 | .TP 81 | .B \-p 82 | load files but do not generate any output file. 83 | Used mainly for syntax checking and for testing precompiled chunks: 84 | corrupted files will probably generate errors when loaded. 85 | If no files are given, then 86 | .B luac 87 | loads 88 | .B luac.out 89 | and tests its contents. 90 | No messages are displayed if the file loads without errors. 91 | .TP 92 | .B \-s 93 | strip debug information before writing the output file. 94 | This saves some space in very large chunks, 95 | but if errors occur when running a stripped chunk, 96 | then the error messages may not contain the full information they usually do. 97 | In particular, 98 | line numbers and names of local variables are lost. 99 | .TP 100 | .B \-v 101 | show version information. 102 | .TP 103 | .B \-\- 104 | stop handling options. 105 | .TP 106 | .B \- 107 | stop handling options and process standard input. 108 | .SH "SEE ALSO" 109 | .BR lua (1) 110 | .br 111 | The documentation at lua.org. 112 | .SH DIAGNOSTICS 113 | Error messages should be self explanatory. 114 | .SH AUTHORS 115 | R. Ierusalimschy, 116 | L. H. de Figueiredo, 117 | W. Celes 118 | .\" EOF 119 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/doc/manual.css: -------------------------------------------------------------------------------- 1 | h3 code { 2 | font-family: inherit ; 3 | font-size: inherit ; 4 | } 5 | 6 | pre, code { 7 | font-size: 12pt ; 8 | } 9 | 10 | span.apii { 11 | color: gray ; 12 | float: right ; 13 | font-family: inherit ; 14 | font-style: normal ; 15 | font-size: small ; 16 | } 17 | 18 | h2:before { 19 | content: "" ; 20 | padding-right: 0em ; 21 | } 22 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/doc/osi-certified-72x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/doc/osi-certified-72x60.png -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lapi.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lapi.h,v 2.9.1.1 2017/04/19 17:20:42 roberto Exp $ 3 | ** Auxiliary functions from Lua API 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lapi_h 8 | #define lapi_h 9 | 10 | 11 | #include "llimits.h" 12 | #include "lstate.h" 13 | 14 | #define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \ 15 | "stack overflow");} 16 | 17 | #define adjustresults(L,nres) \ 18 | { if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; } 19 | 20 | #define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \ 21 | "not enough elements in the stack") 22 | 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lapi.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/lapi.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lauxlib.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/lauxlib.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lbaselib.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/lbaselib.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lbitlib.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/lbitlib.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lcode.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lcode.h,v 1.64.1.1 2017/04/19 17:20:42 roberto Exp $ 3 | ** Code generator for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lcode_h 8 | #define lcode_h 9 | 10 | #include "llex.h" 11 | #include "lobject.h" 12 | #include "lopcodes.h" 13 | #include "lparser.h" 14 | 15 | 16 | /* 17 | ** Marks the end of a patch list. It is an invalid value both as an absolute 18 | ** address, and as a list link (would link an element to itself). 19 | */ 20 | #define NO_JUMP (-1) 21 | 22 | 23 | /* 24 | ** grep "ORDER OPR" if you change these enums (ORDER OP) 25 | */ 26 | typedef enum BinOpr { 27 | OPR_ADD, OPR_SUB, OPR_MUL, OPR_MOD, OPR_POW, 28 | OPR_DIV, 29 | OPR_IDIV, 30 | OPR_BAND, OPR_BOR, OPR_BXOR, 31 | OPR_SHL, OPR_SHR, 32 | OPR_CONCAT, 33 | OPR_EQ, OPR_LT, OPR_LE, 34 | OPR_NE, OPR_GT, OPR_GE, 35 | OPR_AND, OPR_OR, 36 | OPR_NOBINOPR 37 | } BinOpr; 38 | 39 | 40 | typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; 41 | 42 | 43 | /* get (pointer to) instruction of given 'expdesc' */ 44 | #define getinstruction(fs,e) ((fs)->f->code[(e)->u.info]) 45 | 46 | #define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) 47 | 48 | #define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) 49 | 50 | #define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t) 51 | 52 | LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); 53 | LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); 54 | LUAI_FUNC int luaK_codek (FuncState *fs, int reg, int k); 55 | LUAI_FUNC void luaK_fixline (FuncState *fs, int line); 56 | LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); 57 | LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); 58 | LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); 59 | LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s); 60 | LUAI_FUNC int luaK_intK (FuncState *fs, lua_Integer n); 61 | LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); 62 | LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); 63 | LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e); 64 | LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); 65 | LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); 66 | LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); 67 | LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); 68 | LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); 69 | LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); 70 | LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e); 71 | LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); 72 | LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); 73 | LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); 74 | LUAI_FUNC int luaK_jump (FuncState *fs); 75 | LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); 76 | LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); 77 | LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); 78 | LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level); 79 | LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); 80 | LUAI_FUNC int luaK_getlabel (FuncState *fs); 81 | LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line); 82 | LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); 83 | LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, 84 | expdesc *v2, int line); 85 | LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); 86 | 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lcode.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/lcode.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lcorolib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lcorolib.c,v 1.10.1.1 2017/04/19 17:20:42 roberto Exp $ 3 | ** Coroutine Library 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lcorolib_c 8 | #define LUA_LIB 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "lauxlib.h" 18 | #include "lualib.h" 19 | 20 | 21 | static lua_State *getco (lua_State *L) { 22 | lua_State *co = lua_tothread(L, 1); 23 | luaL_argcheck(L, co, 1, "thread expected"); 24 | return co; 25 | } 26 | 27 | 28 | static int auxresume (lua_State *L, lua_State *co, int narg) { 29 | int status; 30 | if (!lua_checkstack(co, narg)) { 31 | lua_pushliteral(L, "too many arguments to resume"); 32 | return -1; /* error flag */ 33 | } 34 | if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) { 35 | lua_pushliteral(L, "cannot resume dead coroutine"); 36 | return -1; /* error flag */ 37 | } 38 | lua_xmove(L, co, narg); 39 | status = lua_resume(co, L, narg); 40 | if (status == LUA_OK || status == LUA_YIELD) { 41 | int nres = lua_gettop(co); 42 | if (!lua_checkstack(L, nres + 1)) { 43 | lua_pop(co, nres); /* remove results anyway */ 44 | lua_pushliteral(L, "too many results to resume"); 45 | return -1; /* error flag */ 46 | } 47 | lua_xmove(co, L, nres); /* move yielded values */ 48 | return nres; 49 | } 50 | else { 51 | lua_xmove(co, L, 1); /* move error message */ 52 | return -1; /* error flag */ 53 | } 54 | } 55 | 56 | 57 | static int luaB_coresume (lua_State *L) { 58 | lua_State *co = getco(L); 59 | int r; 60 | r = auxresume(L, co, lua_gettop(L) - 1); 61 | if (r < 0) { 62 | lua_pushboolean(L, 0); 63 | lua_insert(L, -2); 64 | return 2; /* return false + error message */ 65 | } 66 | else { 67 | lua_pushboolean(L, 1); 68 | lua_insert(L, -(r + 1)); 69 | return r + 1; /* return true + 'resume' returns */ 70 | } 71 | } 72 | 73 | 74 | static int luaB_auxwrap (lua_State *L) { 75 | lua_State *co = lua_tothread(L, lua_upvalueindex(1)); 76 | int r = auxresume(L, co, lua_gettop(L)); 77 | if (r < 0) { 78 | if (lua_type(L, -1) == LUA_TSTRING) { /* error object is a string? */ 79 | luaL_where(L, 1); /* add extra info */ 80 | lua_insert(L, -2); 81 | lua_concat(L, 2); 82 | } 83 | return lua_error(L); /* propagate error */ 84 | } 85 | return r; 86 | } 87 | 88 | 89 | static int luaB_cocreate (lua_State *L) { 90 | lua_State *NL; 91 | luaL_checktype(L, 1, LUA_TFUNCTION); 92 | NL = lua_newthread(L); 93 | lua_pushvalue(L, 1); /* move function to top */ 94 | lua_xmove(L, NL, 1); /* move function from L to NL */ 95 | return 1; 96 | } 97 | 98 | 99 | static int luaB_cowrap (lua_State *L) { 100 | luaB_cocreate(L); 101 | lua_pushcclosure(L, luaB_auxwrap, 1); 102 | return 1; 103 | } 104 | 105 | 106 | static int luaB_yield (lua_State *L) { 107 | return lua_yield(L, lua_gettop(L)); 108 | } 109 | 110 | 111 | static int luaB_costatus (lua_State *L) { 112 | lua_State *co = getco(L); 113 | if (L == co) lua_pushliteral(L, "running"); 114 | else { 115 | switch (lua_status(co)) { 116 | case LUA_YIELD: 117 | lua_pushliteral(L, "suspended"); 118 | break; 119 | case LUA_OK: { 120 | lua_Debug ar; 121 | if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ 122 | lua_pushliteral(L, "normal"); /* it is running */ 123 | else if (lua_gettop(co) == 0) 124 | lua_pushliteral(L, "dead"); 125 | else 126 | lua_pushliteral(L, "suspended"); /* initial state */ 127 | break; 128 | } 129 | default: /* some error occurred */ 130 | lua_pushliteral(L, "dead"); 131 | break; 132 | } 133 | } 134 | return 1; 135 | } 136 | 137 | 138 | static int luaB_yieldable (lua_State *L) { 139 | lua_pushboolean(L, lua_isyieldable(L)); 140 | return 1; 141 | } 142 | 143 | 144 | static int luaB_corunning (lua_State *L) { 145 | int ismain = lua_pushthread(L); 146 | lua_pushboolean(L, ismain); 147 | return 2; 148 | } 149 | 150 | 151 | static const luaL_Reg co_funcs[] = { 152 | {"create", luaB_cocreate}, 153 | {"resume", luaB_coresume}, 154 | {"running", luaB_corunning}, 155 | {"status", luaB_costatus}, 156 | {"wrap", luaB_cowrap}, 157 | {"yield", luaB_yield}, 158 | {"isyieldable", luaB_yieldable}, 159 | {NULL, NULL} 160 | }; 161 | 162 | 163 | 164 | LUAMOD_API int luaopen_coroutine (lua_State *L) { 165 | luaL_newlib(L, co_funcs); 166 | return 1; 167 | } 168 | 169 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lcorolib.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/lcorolib.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lctype.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lctype.c,v 1.12.1.1 2017/04/19 17:20:42 roberto Exp $ 3 | ** 'ctype' functions for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lctype_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include "lctype.h" 14 | 15 | #if !LUA_USE_CTYPE /* { */ 16 | 17 | #include 18 | 19 | LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = { 20 | 0x00, /* EOZ */ 21 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0. */ 22 | 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 23 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1. */ 24 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 25 | 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 2. */ 26 | 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 27 | 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, /* 3. */ 28 | 0x16, 0x16, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 29 | 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 4. */ 30 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 31 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 5. */ 32 | 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x05, 33 | 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 6. */ 34 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 35 | 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 7. */ 36 | 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, 37 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8. */ 38 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 39 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9. */ 40 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 41 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a. */ 42 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 43 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b. */ 44 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 45 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c. */ 46 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 47 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d. */ 48 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 49 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* e. */ 50 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 51 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* f. */ 52 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 53 | }; 54 | 55 | #endif /* } */ 56 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lctype.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lctype.h,v 1.12.1.1 2013/04/12 18:48:47 roberto Exp $ 3 | ** 'ctype' functions for Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lctype_h 8 | #define lctype_h 9 | 10 | #include "lua.h" 11 | 12 | 13 | /* 14 | ** WARNING: the functions defined here do not necessarily correspond 15 | ** to the similar functions in the standard C ctype.h. They are 16 | ** optimized for the specific needs of Lua 17 | */ 18 | 19 | #if !defined(LUA_USE_CTYPE) 20 | 21 | #if 'A' == 65 && '0' == 48 22 | /* ASCII case: can use its own tables; faster and fixed */ 23 | #define LUA_USE_CTYPE 0 24 | #else 25 | /* must use standard C ctype */ 26 | #define LUA_USE_CTYPE 1 27 | #endif 28 | 29 | #endif 30 | 31 | 32 | #if !LUA_USE_CTYPE /* { */ 33 | 34 | #include 35 | 36 | #include "llimits.h" 37 | 38 | 39 | #define ALPHABIT 0 40 | #define DIGITBIT 1 41 | #define PRINTBIT 2 42 | #define SPACEBIT 3 43 | #define XDIGITBIT 4 44 | 45 | 46 | #define MASK(B) (1 << (B)) 47 | 48 | 49 | /* 50 | ** add 1 to char to allow index -1 (EOZ) 51 | */ 52 | #define testprop(c,p) (luai_ctype_[(c)+1] & (p)) 53 | 54 | /* 55 | ** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_' 56 | */ 57 | #define lislalpha(c) testprop(c, MASK(ALPHABIT)) 58 | #define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT))) 59 | #define lisdigit(c) testprop(c, MASK(DIGITBIT)) 60 | #define lisspace(c) testprop(c, MASK(SPACEBIT)) 61 | #define lisprint(c) testprop(c, MASK(PRINTBIT)) 62 | #define lisxdigit(c) testprop(c, MASK(XDIGITBIT)) 63 | 64 | /* 65 | ** this 'ltolower' only works for alphabetic characters 66 | */ 67 | #define ltolower(c) ((c) | ('A' ^ 'a')) 68 | 69 | 70 | /* two more entries for 0 and -1 (EOZ) */ 71 | LUAI_DDEC const lu_byte luai_ctype_[UCHAR_MAX + 2]; 72 | 73 | 74 | #else /* }{ */ 75 | 76 | /* 77 | ** use standard C ctypes 78 | */ 79 | 80 | #include 81 | 82 | 83 | #define lislalpha(c) (isalpha(c) || (c) == '_') 84 | #define lislalnum(c) (isalnum(c) || (c) == '_') 85 | #define lisdigit(c) (isdigit(c)) 86 | #define lisspace(c) (isspace(c)) 87 | #define lisprint(c) (isprint(c)) 88 | #define lisxdigit(c) (isxdigit(c)) 89 | 90 | #define ltolower(c) (tolower(c)) 91 | 92 | #endif /* } */ 93 | 94 | #endif 95 | 96 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lctype.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/lctype.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/ldblib.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/ldblib.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/ldebug.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldebug.h,v 2.14.1.1 2017/04/19 17:20:42 roberto Exp $ 3 | ** Auxiliary functions from Debug Interface module 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ldebug_h 8 | #define ldebug_h 9 | 10 | 11 | #include "lstate.h" 12 | 13 | 14 | #define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) 15 | 16 | #define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : -1) 17 | 18 | #define resethookcount(L) (L->hookcount = L->basehookcount) 19 | 20 | 21 | LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, 22 | const char *opname); 23 | LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1, 24 | const TValue *p2); 25 | LUAI_FUNC l_noret luaG_opinterror (lua_State *L, const TValue *p1, 26 | const TValue *p2, 27 | const char *msg); 28 | LUAI_FUNC l_noret luaG_tointerror (lua_State *L, const TValue *p1, 29 | const TValue *p2); 30 | LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1, 31 | const TValue *p2); 32 | LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...); 33 | LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg, 34 | TString *src, int line); 35 | LUAI_FUNC l_noret luaG_errormsg (lua_State *L); 36 | LUAI_FUNC void luaG_traceexec (lua_State *L); 37 | 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/ldebug.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/ldebug.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/ldo.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldo.h,v 2.29.1.1 2017/04/19 17:20:42 roberto Exp $ 3 | ** Stack and Call structure of Lua 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ldo_h 8 | #define ldo_h 9 | 10 | 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | #include "lzio.h" 14 | 15 | 16 | /* 17 | ** Macro to check stack size and grow stack if needed. Parameters 18 | ** 'pre'/'pos' allow the macro to preserve a pointer into the 19 | ** stack across reallocations, doing the work only when needed. 20 | ** 'condmovestack' is used in heavy tests to force a stack reallocation 21 | ** at every check. 22 | */ 23 | #define luaD_checkstackaux(L,n,pre,pos) \ 24 | if (L->stack_last - L->top <= (n)) \ 25 | { pre; luaD_growstack(L, n); pos; } else { condmovestack(L,pre,pos); } 26 | 27 | /* In general, 'pre'/'pos' are empty (nothing to save) */ 28 | #define luaD_checkstack(L,n) luaD_checkstackaux(L,n,(void)0,(void)0) 29 | 30 | 31 | 32 | #define savestack(L,p) ((char *)(p) - (char *)L->stack) 33 | #define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) 34 | 35 | 36 | /* type of protected functions, to be ran by 'runprotected' */ 37 | typedef void (*Pfunc) (lua_State *L, void *ud); 38 | 39 | LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, 40 | const char *mode); 41 | LUAI_FUNC void luaD_hook (lua_State *L, int event, int line); 42 | LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults); 43 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); 44 | LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); 45 | LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, 46 | ptrdiff_t oldtop, ptrdiff_t ef); 47 | LUAI_FUNC int luaD_poscall (lua_State *L, CallInfo *ci, StkId firstResult, 48 | int nres); 49 | LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); 50 | LUAI_FUNC void luaD_growstack (lua_State *L, int n); 51 | LUAI_FUNC void luaD_shrinkstack (lua_State *L); 52 | LUAI_FUNC void luaD_inctop (lua_State *L); 53 | 54 | LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode); 55 | LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); 56 | 57 | #endif 58 | 59 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/ldo.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/ldo.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/ldump.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ldump.c,v 2.37.1.1 2017/04/19 17:20:42 roberto Exp $ 3 | ** save precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define ldump_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "lobject.h" 18 | #include "lstate.h" 19 | #include "lundump.h" 20 | 21 | 22 | typedef struct { 23 | lua_State *L; 24 | lua_Writer writer; 25 | void *data; 26 | int strip; 27 | int status; 28 | } DumpState; 29 | 30 | 31 | /* 32 | ** All high-level dumps go through DumpVector; you can change it to 33 | ** change the endianness of the result 34 | */ 35 | #define DumpVector(v,n,D) DumpBlock(v,(n)*sizeof((v)[0]),D) 36 | 37 | #define DumpLiteral(s,D) DumpBlock(s, sizeof(s) - sizeof(char), D) 38 | 39 | 40 | static void DumpBlock (const void *b, size_t size, DumpState *D) { 41 | if (D->status == 0 && size > 0) { 42 | lua_unlock(D->L); 43 | D->status = (*D->writer)(D->L, b, size, D->data); 44 | lua_lock(D->L); 45 | } 46 | } 47 | 48 | 49 | #define DumpVar(x,D) DumpVector(&x,1,D) 50 | 51 | 52 | static void DumpByte (int y, DumpState *D) { 53 | lu_byte x = (lu_byte)y; 54 | DumpVar(x, D); 55 | } 56 | 57 | 58 | static void DumpInt (int x, DumpState *D) { 59 | DumpVar(x, D); 60 | } 61 | 62 | 63 | static void DumpNumber (lua_Number x, DumpState *D) { 64 | DumpVar(x, D); 65 | } 66 | 67 | 68 | static void DumpInteger (lua_Integer x, DumpState *D) { 69 | DumpVar(x, D); 70 | } 71 | 72 | 73 | static void DumpString (const TString *s, DumpState *D) { 74 | if (s == NULL) 75 | DumpByte(0, D); 76 | else { 77 | size_t size = tsslen(s) + 1; /* include trailing '\0' */ 78 | const char *str = getstr(s); 79 | if (size < 0xFF) 80 | DumpByte(cast_int(size), D); 81 | else { 82 | DumpByte(0xFF, D); 83 | DumpVar(size, D); 84 | } 85 | DumpVector(str, size - 1, D); /* no need to save '\0' */ 86 | } 87 | } 88 | 89 | 90 | static void DumpCode (const Proto *f, DumpState *D) { 91 | DumpInt(f->sizecode, D); 92 | DumpVector(f->code, f->sizecode, D); 93 | } 94 | 95 | 96 | static void DumpFunction(const Proto *f, TString *psource, DumpState *D); 97 | 98 | static void DumpConstants (const Proto *f, DumpState *D) { 99 | int i; 100 | int n = f->sizek; 101 | DumpInt(n, D); 102 | for (i = 0; i < n; i++) { 103 | const TValue *o = &f->k[i]; 104 | DumpByte(ttype(o), D); 105 | switch (ttype(o)) { 106 | case LUA_TNIL: 107 | break; 108 | case LUA_TBOOLEAN: 109 | DumpByte(bvalue(o), D); 110 | break; 111 | case LUA_TNUMFLT: 112 | DumpNumber(fltvalue(o), D); 113 | break; 114 | case LUA_TNUMINT: 115 | DumpInteger(ivalue(o), D); 116 | break; 117 | case LUA_TSHRSTR: 118 | case LUA_TLNGSTR: 119 | DumpString(tsvalue(o), D); 120 | break; 121 | default: 122 | lua_assert(0); 123 | } 124 | } 125 | } 126 | 127 | 128 | static void DumpProtos (const Proto *f, DumpState *D) { 129 | int i; 130 | int n = f->sizep; 131 | DumpInt(n, D); 132 | for (i = 0; i < n; i++) 133 | DumpFunction(f->p[i], f->source, D); 134 | } 135 | 136 | 137 | static void DumpUpvalues (const Proto *f, DumpState *D) { 138 | int i, n = f->sizeupvalues; 139 | DumpInt(n, D); 140 | for (i = 0; i < n; i++) { 141 | DumpByte(f->upvalues[i].instack, D); 142 | DumpByte(f->upvalues[i].idx, D); 143 | } 144 | } 145 | 146 | 147 | static void DumpDebug (const Proto *f, DumpState *D) { 148 | int i, n; 149 | n = (D->strip) ? 0 : f->sizelineinfo; 150 | DumpInt(n, D); 151 | DumpVector(f->lineinfo, n, D); 152 | n = (D->strip) ? 0 : f->sizelocvars; 153 | DumpInt(n, D); 154 | for (i = 0; i < n; i++) { 155 | DumpString(f->locvars[i].varname, D); 156 | DumpInt(f->locvars[i].startpc, D); 157 | DumpInt(f->locvars[i].endpc, D); 158 | } 159 | n = (D->strip) ? 0 : f->sizeupvalues; 160 | DumpInt(n, D); 161 | for (i = 0; i < n; i++) 162 | DumpString(f->upvalues[i].name, D); 163 | } 164 | 165 | 166 | static void DumpFunction (const Proto *f, TString *psource, DumpState *D) { 167 | if (D->strip || f->source == psource) 168 | DumpString(NULL, D); /* no debug info or same source as its parent */ 169 | else 170 | DumpString(f->source, D); 171 | DumpInt(f->linedefined, D); 172 | DumpInt(f->lastlinedefined, D); 173 | DumpByte(f->numparams, D); 174 | DumpByte(f->is_vararg, D); 175 | DumpByte(f->maxstacksize, D); 176 | DumpCode(f, D); 177 | DumpConstants(f, D); 178 | DumpUpvalues(f, D); 179 | DumpProtos(f, D); 180 | DumpDebug(f, D); 181 | } 182 | 183 | 184 | static void DumpHeader (DumpState *D) { 185 | DumpLiteral(LUA_SIGNATURE, D); 186 | DumpByte(LUAC_VERSION, D); 187 | DumpByte(LUAC_FORMAT, D); 188 | DumpLiteral(LUAC_DATA, D); 189 | DumpByte(sizeof(int), D); 190 | DumpByte(sizeof(size_t), D); 191 | DumpByte(sizeof(Instruction), D); 192 | DumpByte(sizeof(lua_Integer), D); 193 | DumpByte(sizeof(lua_Number), D); 194 | DumpInteger(LUAC_INT, D); 195 | DumpNumber(LUAC_NUM, D); 196 | } 197 | 198 | 199 | /* 200 | ** dump Lua function as precompiled chunk 201 | */ 202 | int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data, 203 | int strip) { 204 | DumpState D; 205 | D.L = L; 206 | D.writer = w; 207 | D.data = data; 208 | D.strip = strip; 209 | D.status = 0; 210 | DumpHeader(&D); 211 | DumpByte(f->sizeupvalues, &D); 212 | DumpFunction(f, NULL, &D); 213 | return D.status; 214 | } 215 | 216 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/ldump.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/ldump.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lfunc.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lfunc.c,v 2.45.1.1 2017/04/19 17:39:34 roberto Exp $ 3 | ** Auxiliary functions to manipulate prototypes and closures 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lfunc_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "lfunc.h" 18 | #include "lgc.h" 19 | #include "lmem.h" 20 | #include "lobject.h" 21 | #include "lstate.h" 22 | 23 | 24 | 25 | CClosure *luaF_newCclosure (lua_State *L, int n) { 26 | GCObject *o = luaC_newobj(L, LUA_TCCL, sizeCclosure(n)); 27 | CClosure *c = gco2ccl(o); 28 | c->nupvalues = cast_byte(n); 29 | return c; 30 | } 31 | 32 | 33 | LClosure *luaF_newLclosure (lua_State *L, int n) { 34 | GCObject *o = luaC_newobj(L, LUA_TLCL, sizeLclosure(n)); 35 | LClosure *c = gco2lcl(o); 36 | c->p = NULL; 37 | c->nupvalues = cast_byte(n); 38 | while (n--) c->upvals[n] = NULL; 39 | return c; 40 | } 41 | 42 | /* 43 | ** fill a closure with new closed upvalues 44 | */ 45 | void luaF_initupvals (lua_State *L, LClosure *cl) { 46 | int i; 47 | for (i = 0; i < cl->nupvalues; i++) { 48 | UpVal *uv = luaM_new(L, UpVal); 49 | uv->refcount = 1; 50 | uv->v = &uv->u.value; /* make it closed */ 51 | setnilvalue(uv->v); 52 | cl->upvals[i] = uv; 53 | } 54 | } 55 | 56 | 57 | UpVal *luaF_findupval (lua_State *L, StkId level) { 58 | UpVal **pp = &L->openupval; 59 | UpVal *p; 60 | UpVal *uv; 61 | lua_assert(isintwups(L) || L->openupval == NULL); 62 | while (*pp != NULL && (p = *pp)->v >= level) { 63 | lua_assert(upisopen(p)); 64 | if (p->v == level) /* found a corresponding upvalue? */ 65 | return p; /* return it */ 66 | pp = &p->u.open.next; 67 | } 68 | /* not found: create a new upvalue */ 69 | uv = luaM_new(L, UpVal); 70 | uv->refcount = 0; 71 | uv->u.open.next = *pp; /* link it to list of open upvalues */ 72 | uv->u.open.touched = 1; 73 | *pp = uv; 74 | uv->v = level; /* current value lives in the stack */ 75 | if (!isintwups(L)) { /* thread not in list of threads with upvalues? */ 76 | L->twups = G(L)->twups; /* link it to the list */ 77 | G(L)->twups = L; 78 | } 79 | return uv; 80 | } 81 | 82 | 83 | void luaF_close (lua_State *L, StkId level) { 84 | UpVal *uv; 85 | while (L->openupval != NULL && (uv = L->openupval)->v >= level) { 86 | lua_assert(upisopen(uv)); 87 | L->openupval = uv->u.open.next; /* remove from 'open' list */ 88 | if (uv->refcount == 0) /* no references? */ 89 | luaM_free(L, uv); /* free upvalue */ 90 | else { 91 | setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */ 92 | uv->v = &uv->u.value; /* now current value lives here */ 93 | luaC_upvalbarrier(L, uv); 94 | } 95 | } 96 | } 97 | 98 | 99 | Proto *luaF_newproto (lua_State *L) { 100 | GCObject *o = luaC_newobj(L, LUA_TPROTO, sizeof(Proto)); 101 | Proto *f = gco2p(o); 102 | f->k = NULL; 103 | f->sizek = 0; 104 | f->p = NULL; 105 | f->sizep = 0; 106 | f->code = NULL; 107 | f->cache = NULL; 108 | f->sizecode = 0; 109 | f->lineinfo = NULL; 110 | f->sizelineinfo = 0; 111 | f->upvalues = NULL; 112 | f->sizeupvalues = 0; 113 | f->numparams = 0; 114 | f->is_vararg = 0; 115 | f->maxstacksize = 0; 116 | f->locvars = NULL; 117 | f->sizelocvars = 0; 118 | f->linedefined = 0; 119 | f->lastlinedefined = 0; 120 | f->source = NULL; 121 | return f; 122 | } 123 | 124 | 125 | void luaF_freeproto (lua_State *L, Proto *f) { 126 | luaM_freearray(L, f->code, f->sizecode); 127 | luaM_freearray(L, f->p, f->sizep); 128 | luaM_freearray(L, f->k, f->sizek); 129 | luaM_freearray(L, f->lineinfo, f->sizelineinfo); 130 | luaM_freearray(L, f->locvars, f->sizelocvars); 131 | luaM_freearray(L, f->upvalues, f->sizeupvalues); 132 | luaM_free(L, f); 133 | } 134 | 135 | 136 | /* 137 | ** Look for n-th local variable at line 'line' in function 'func'. 138 | ** Returns NULL if not found. 139 | */ 140 | const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { 141 | int i; 142 | for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { 143 | if (pc < f->locvars[i].endpc) { /* is variable active? */ 144 | local_number--; 145 | if (local_number == 0) 146 | return getstr(f->locvars[i].varname); 147 | } 148 | } 149 | return NULL; /* not found */ 150 | } 151 | 152 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lfunc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lfunc.h,v 2.15.1.1 2017/04/19 17:39:34 roberto Exp $ 3 | ** Auxiliary functions to manipulate prototypes and closures 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lfunc_h 8 | #define lfunc_h 9 | 10 | 11 | #include "lobject.h" 12 | 13 | 14 | #define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ 15 | cast(int, sizeof(TValue)*((n)-1))) 16 | 17 | #define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ 18 | cast(int, sizeof(TValue *)*((n)-1))) 19 | 20 | 21 | /* test whether thread is in 'twups' list */ 22 | #define isintwups(L) (L->twups != L) 23 | 24 | 25 | /* 26 | ** maximum number of upvalues in a closure (both C and Lua). (Value 27 | ** must fit in a VM register.) 28 | */ 29 | #define MAXUPVAL 255 30 | 31 | 32 | /* 33 | ** Upvalues for Lua closures 34 | */ 35 | struct UpVal { 36 | TValue *v; /* points to stack or to its own value */ 37 | lu_mem refcount; /* reference counter */ 38 | union { 39 | struct { /* (when open) */ 40 | UpVal *next; /* linked list */ 41 | int touched; /* mark to avoid cycles with dead threads */ 42 | } open; 43 | TValue value; /* the value (when closed) */ 44 | } u; 45 | }; 46 | 47 | #define upisopen(up) ((up)->v != &(up)->u.value) 48 | 49 | 50 | LUAI_FUNC Proto *luaF_newproto (lua_State *L); 51 | LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nelems); 52 | LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nelems); 53 | LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl); 54 | LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); 55 | LUAI_FUNC void luaF_close (lua_State *L, StkId level); 56 | LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); 57 | LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, 58 | int pc); 59 | 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lfunc.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/lfunc.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lgc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lgc.h,v 2.91.1.1 2017/04/19 17:39:34 roberto Exp $ 3 | ** Garbage Collector 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lgc_h 8 | #define lgc_h 9 | 10 | 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | 14 | /* 15 | ** Collectable objects may have one of three colors: white, which 16 | ** means the object is not marked; gray, which means the 17 | ** object is marked, but its references may be not marked; and 18 | ** black, which means that the object and all its references are marked. 19 | ** The main invariant of the garbage collector, while marking objects, 20 | ** is that a black object can never point to a white one. Moreover, 21 | ** any gray object must be in a "gray list" (gray, grayagain, weak, 22 | ** allweak, ephemeron) so that it can be visited again before finishing 23 | ** the collection cycle. These lists have no meaning when the invariant 24 | ** is not being enforced (e.g., sweep phase). 25 | */ 26 | 27 | 28 | 29 | /* how much to allocate before next GC step */ 30 | #if !defined(GCSTEPSIZE) 31 | /* ~100 small strings */ 32 | #define GCSTEPSIZE (cast_int(100 * sizeof(TString))) 33 | #endif 34 | 35 | 36 | /* 37 | ** Possible states of the Garbage Collector 38 | */ 39 | #define GCSpropagate 0 40 | #define GCSatomic 1 41 | #define GCSswpallgc 2 42 | #define GCSswpfinobj 3 43 | #define GCSswptobefnz 4 44 | #define GCSswpend 5 45 | #define GCScallfin 6 46 | #define GCSpause 7 47 | 48 | 49 | #define issweepphase(g) \ 50 | (GCSswpallgc <= (g)->gcstate && (g)->gcstate <= GCSswpend) 51 | 52 | 53 | /* 54 | ** macro to tell when main invariant (white objects cannot point to black 55 | ** ones) must be kept. During a collection, the sweep 56 | ** phase may break the invariant, as objects turned white may point to 57 | ** still-black objects. The invariant is restored when sweep ends and 58 | ** all objects are white again. 59 | */ 60 | 61 | #define keepinvariant(g) ((g)->gcstate <= GCSatomic) 62 | 63 | 64 | /* 65 | ** some useful bit tricks 66 | */ 67 | #define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) 68 | #define setbits(x,m) ((x) |= (m)) 69 | #define testbits(x,m) ((x) & (m)) 70 | #define bitmask(b) (1<<(b)) 71 | #define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) 72 | #define l_setbit(x,b) setbits(x, bitmask(b)) 73 | #define resetbit(x,b) resetbits(x, bitmask(b)) 74 | #define testbit(x,b) testbits(x, bitmask(b)) 75 | 76 | 77 | /* Layout for bit use in 'marked' field: */ 78 | #define WHITE0BIT 0 /* object is white (type 0) */ 79 | #define WHITE1BIT 1 /* object is white (type 1) */ 80 | #define BLACKBIT 2 /* object is black */ 81 | #define FINALIZEDBIT 3 /* object has been marked for finalization */ 82 | /* bit 7 is currently used by tests (luaL_checkmemory) */ 83 | 84 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) 85 | 86 | 87 | #define iswhite(x) testbits((x)->marked, WHITEBITS) 88 | #define isblack(x) testbit((x)->marked, BLACKBIT) 89 | #define isgray(x) /* neither white nor black */ \ 90 | (!testbits((x)->marked, WHITEBITS | bitmask(BLACKBIT))) 91 | 92 | #define tofinalize(x) testbit((x)->marked, FINALIZEDBIT) 93 | 94 | #define otherwhite(g) ((g)->currentwhite ^ WHITEBITS) 95 | #define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow))) 96 | #define isdead(g,v) isdeadm(otherwhite(g), (v)->marked) 97 | 98 | #define changewhite(x) ((x)->marked ^= WHITEBITS) 99 | #define gray2black(x) l_setbit((x)->marked, BLACKBIT) 100 | 101 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) 102 | 103 | 104 | /* 105 | ** Does one step of collection when debt becomes positive. 'pre'/'pos' 106 | ** allows some adjustments to be done only when needed. macro 107 | ** 'condchangemem' is used only for heavy tests (forcing a full 108 | ** GC cycle on every opportunity) 109 | */ 110 | #define luaC_condGC(L,pre,pos) \ 111 | { if (G(L)->GCdebt > 0) { pre; luaC_step(L); pos;}; \ 112 | condchangemem(L,pre,pos); } 113 | 114 | /* more often than not, 'pre'/'pos' are empty */ 115 | #define luaC_checkGC(L) luaC_condGC(L,(void)0,(void)0) 116 | 117 | 118 | #define luaC_barrier(L,p,v) ( \ 119 | (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \ 120 | luaC_barrier_(L,obj2gco(p),gcvalue(v)) : cast_void(0)) 121 | 122 | #define luaC_barrierback(L,p,v) ( \ 123 | (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \ 124 | luaC_barrierback_(L,p) : cast_void(0)) 125 | 126 | #define luaC_objbarrier(L,p,o) ( \ 127 | (isblack(p) && iswhite(o)) ? \ 128 | luaC_barrier_(L,obj2gco(p),obj2gco(o)) : cast_void(0)) 129 | 130 | #define luaC_upvalbarrier(L,uv) ( \ 131 | (iscollectable((uv)->v) && !upisopen(uv)) ? \ 132 | luaC_upvalbarrier_(L,uv) : cast_void(0)) 133 | 134 | LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o); 135 | LUAI_FUNC void luaC_freeallobjects (lua_State *L); 136 | LUAI_FUNC void luaC_step (lua_State *L); 137 | LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); 138 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); 139 | LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz); 140 | LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); 141 | LUAI_FUNC void luaC_barrierback_ (lua_State *L, Table *o); 142 | LUAI_FUNC void luaC_upvalbarrier_ (lua_State *L, UpVal *uv); 143 | LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); 144 | LUAI_FUNC void luaC_upvdeccount (lua_State *L, UpVal *uv); 145 | 146 | 147 | #endif 148 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lgc.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/lgc.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/liblua.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/liblua.a -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/linit.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: linit.c,v 1.39.1.1 2017/04/19 17:20:42 roberto Exp $ 3 | ** Initialization of libraries for lua.c and other clients 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #define linit_c 9 | #define LUA_LIB 10 | 11 | /* 12 | ** If you embed Lua in your program and need to open the standard 13 | ** libraries, call luaL_openlibs in your program. If you need a 14 | ** different set of libraries, copy this file to your project and edit 15 | ** it to suit your needs. 16 | ** 17 | ** You can also *preload* libraries, so that a later 'require' can 18 | ** open the library, which is already linked to the application. 19 | ** For that, do the following code: 20 | ** 21 | ** luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); 22 | ** lua_pushcfunction(L, luaopen_modname); 23 | ** lua_setfield(L, -2, modname); 24 | ** lua_pop(L, 1); // remove PRELOAD table 25 | */ 26 | 27 | #include "lprefix.h" 28 | 29 | 30 | #include 31 | 32 | #include "lua.h" 33 | 34 | #include "lualib.h" 35 | #include "lauxlib.h" 36 | 37 | 38 | /* 39 | ** these libs are loaded by lua.c and are readily available to any Lua 40 | ** program 41 | */ 42 | static const luaL_Reg loadedlibs[] = { 43 | {"_G", luaopen_base}, 44 | {LUA_LOADLIBNAME, luaopen_package}, 45 | {LUA_COLIBNAME, luaopen_coroutine}, 46 | {LUA_TABLIBNAME, luaopen_table}, 47 | {LUA_IOLIBNAME, luaopen_io}, 48 | {LUA_OSLIBNAME, luaopen_os}, 49 | {LUA_STRLIBNAME, luaopen_string}, 50 | {LUA_MATHLIBNAME, luaopen_math}, 51 | {LUA_UTF8LIBNAME, luaopen_utf8}, 52 | {LUA_DBLIBNAME, luaopen_debug}, 53 | #if defined(LUA_COMPAT_BITLIB) 54 | {LUA_BITLIBNAME, luaopen_bit32}, 55 | #endif 56 | {NULL, NULL} 57 | }; 58 | 59 | 60 | LUALIB_API void luaL_openlibs (lua_State *L) { 61 | const luaL_Reg *lib; 62 | /* "require" functions from 'loadedlibs' and set results to global table */ 63 | for (lib = loadedlibs; lib->func; lib++) { 64 | luaL_requiref(L, lib->name, lib->func, 1); 65 | lua_pop(L, 1); /* remove lib */ 66 | } 67 | } 68 | 69 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/linit.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/linit.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/liolib.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/liolib.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/llex.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: llex.h,v 1.79.1.1 2017/04/19 17:20:42 roberto Exp $ 3 | ** Lexical Analyzer 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef llex_h 8 | #define llex_h 9 | 10 | #include "lobject.h" 11 | #include "lzio.h" 12 | 13 | 14 | #define FIRST_RESERVED 257 15 | 16 | 17 | #if !defined(LUA_ENV) 18 | #define LUA_ENV "_ENV" 19 | #endif 20 | 21 | 22 | /* 23 | * WARNING: if you change the order of this enumeration, 24 | * grep "ORDER RESERVED" 25 | */ 26 | enum RESERVED { 27 | /* terminal symbols denoted by reserved words */ 28 | TK_AND = FIRST_RESERVED, TK_BREAK, 29 | TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, 30 | TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, 31 | TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, 32 | /* other terminal symbols */ 33 | TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, 34 | TK_SHL, TK_SHR, 35 | TK_DBCOLON, TK_EOS, 36 | TK_FLT, TK_INT, TK_NAME, TK_STRING 37 | }; 38 | 39 | /* number of reserved words */ 40 | #define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) 41 | 42 | 43 | typedef union { 44 | lua_Number r; 45 | lua_Integer i; 46 | TString *ts; 47 | } SemInfo; /* semantics information */ 48 | 49 | 50 | typedef struct Token { 51 | int token; 52 | SemInfo seminfo; 53 | } Token; 54 | 55 | 56 | /* state of the lexer plus state of the parser when shared by all 57 | functions */ 58 | typedef struct LexState { 59 | int current; /* current character (charint) */ 60 | int linenumber; /* input line counter */ 61 | int lastline; /* line of last token 'consumed' */ 62 | Token t; /* current token */ 63 | Token lookahead; /* look ahead token */ 64 | struct FuncState *fs; /* current function (parser) */ 65 | struct lua_State *L; 66 | ZIO *z; /* input stream */ 67 | Mbuffer *buff; /* buffer for tokens */ 68 | Table *h; /* to avoid collection/reuse strings */ 69 | struct Dyndata *dyd; /* dynamic structures used by the parser */ 70 | TString *source; /* current source name */ 71 | TString *envn; /* environment variable name */ 72 | } LexState; 73 | 74 | 75 | LUAI_FUNC void luaX_init (lua_State *L); 76 | LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, 77 | TString *source, int firstchar); 78 | LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); 79 | LUAI_FUNC void luaX_next (LexState *ls); 80 | LUAI_FUNC int luaX_lookahead (LexState *ls); 81 | LUAI_FUNC l_noret luaX_syntaxerror (LexState *ls, const char *s); 82 | LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); 83 | 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/llex.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/llex.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lmathlib.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/lmathlib.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lmem.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmem.c,v 1.91.1.1 2017/04/19 17:20:42 roberto Exp $ 3 | ** Interface to Memory Manager 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lmem_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "ldebug.h" 18 | #include "ldo.h" 19 | #include "lgc.h" 20 | #include "lmem.h" 21 | #include "lobject.h" 22 | #include "lstate.h" 23 | 24 | 25 | 26 | /* 27 | ** About the realloc function: 28 | ** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); 29 | ** ('osize' is the old size, 'nsize' is the new size) 30 | ** 31 | ** * frealloc(ud, NULL, x, s) creates a new block of size 's' (no 32 | ** matter 'x'). 33 | ** 34 | ** * frealloc(ud, p, x, 0) frees the block 'p' 35 | ** (in this specific case, frealloc must return NULL); 36 | ** particularly, frealloc(ud, NULL, 0, 0) does nothing 37 | ** (which is equivalent to free(NULL) in ISO C) 38 | ** 39 | ** frealloc returns NULL if it cannot create or reallocate the area 40 | ** (any reallocation to an equal or smaller size cannot fail!) 41 | */ 42 | 43 | 44 | 45 | #define MINSIZEARRAY 4 46 | 47 | 48 | void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems, 49 | int limit, const char *what) { 50 | void *newblock; 51 | int newsize; 52 | if (*size >= limit/2) { /* cannot double it? */ 53 | if (*size >= limit) /* cannot grow even a little? */ 54 | luaG_runerror(L, "too many %s (limit is %d)", what, limit); 55 | newsize = limit; /* still have at least one free place */ 56 | } 57 | else { 58 | newsize = (*size)*2; 59 | if (newsize < MINSIZEARRAY) 60 | newsize = MINSIZEARRAY; /* minimum size */ 61 | } 62 | newblock = luaM_reallocv(L, block, *size, newsize, size_elems); 63 | *size = newsize; /* update only when everything else is OK */ 64 | return newblock; 65 | } 66 | 67 | 68 | l_noret luaM_toobig (lua_State *L) { 69 | luaG_runerror(L, "memory allocation error: block too big"); 70 | } 71 | 72 | 73 | 74 | /* 75 | ** generic allocation routine. 76 | */ 77 | void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { 78 | void *newblock; 79 | global_State *g = G(L); 80 | size_t realosize = (block) ? osize : 0; 81 | lua_assert((realosize == 0) == (block == NULL)); 82 | #if defined(HARDMEMTESTS) 83 | if (nsize > realosize && g->gcrunning) 84 | luaC_fullgc(L, 1); /* force a GC whenever possible */ 85 | #endif 86 | newblock = (*g->frealloc)(g->ud, block, osize, nsize); 87 | if (newblock == NULL && nsize > 0) { 88 | lua_assert(nsize > realosize); /* cannot fail when shrinking a block */ 89 | if (g->version) { /* is state fully built? */ 90 | luaC_fullgc(L, 1); /* try to free some memory... */ 91 | newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ 92 | } 93 | if (newblock == NULL) 94 | luaD_throw(L, LUA_ERRMEM); 95 | } 96 | lua_assert((nsize == 0) == (newblock == NULL)); 97 | g->GCdebt = (g->GCdebt + nsize) - realosize; 98 | return newblock; 99 | } 100 | 101 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lmem.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lmem.h,v 1.43.1.1 2017/04/19 17:20:42 roberto Exp $ 3 | ** Interface to Memory Manager 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lmem_h 8 | #define lmem_h 9 | 10 | 11 | #include 12 | 13 | #include "llimits.h" 14 | #include "lua.h" 15 | 16 | 17 | /* 18 | ** This macro reallocs a vector 'b' from 'on' to 'n' elements, where 19 | ** each element has size 'e'. In case of arithmetic overflow of the 20 | ** product 'n'*'e', it raises an error (calling 'luaM_toobig'). Because 21 | ** 'e' is always constant, it avoids the runtime division MAX_SIZET/(e). 22 | ** 23 | ** (The macro is somewhat complex to avoid warnings: The 'sizeof' 24 | ** comparison avoids a runtime comparison when overflow cannot occur. 25 | ** The compiler should be able to optimize the real test by itself, but 26 | ** when it does it, it may give a warning about "comparison is always 27 | ** false due to limited range of data type"; the +1 tricks the compiler, 28 | ** avoiding this warning but also this optimization.) 29 | */ 30 | #define luaM_reallocv(L,b,on,n,e) \ 31 | (((sizeof(n) >= sizeof(size_t) && cast(size_t, (n)) + 1 > MAX_SIZET/(e)) \ 32 | ? luaM_toobig(L) : cast_void(0)) , \ 33 | luaM_realloc_(L, (b), (on)*(e), (n)*(e))) 34 | 35 | /* 36 | ** Arrays of chars do not need any test 37 | */ 38 | #define luaM_reallocvchar(L,b,on,n) \ 39 | cast(char *, luaM_realloc_(L, (b), (on)*sizeof(char), (n)*sizeof(char))) 40 | 41 | #define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) 42 | #define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) 43 | #define luaM_freearray(L, b, n) luaM_realloc_(L, (b), (n)*sizeof(*(b)), 0) 44 | 45 | #define luaM_malloc(L,s) luaM_realloc_(L, NULL, 0, (s)) 46 | #define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) 47 | #define luaM_newvector(L,n,t) \ 48 | cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) 49 | 50 | #define luaM_newobject(L,tag,s) luaM_realloc_(L, NULL, tag, (s)) 51 | 52 | #define luaM_growvector(L,v,nelems,size,t,limit,e) \ 53 | if ((nelems)+1 > (size)) \ 54 | ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e))) 55 | 56 | #define luaM_reallocvector(L, v,oldn,n,t) \ 57 | ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) 58 | 59 | LUAI_FUNC l_noret luaM_toobig (lua_State *L); 60 | 61 | /* not to be called directly */ 62 | LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, 63 | size_t size); 64 | LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size, 65 | size_t size_elem, int limit, 66 | const char *what); 67 | 68 | #endif 69 | 70 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lmem.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/lmem.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/loadlib.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/loadlib.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lobject.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/lobject.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lopcodes.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lopcodes.c,v 1.55.1.1 2017/04/19 17:20:42 roberto Exp $ 3 | ** Opcodes for Lua virtual machine 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lopcodes_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lopcodes.h" 16 | 17 | 18 | /* ORDER OP */ 19 | 20 | LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { 21 | "MOVE", 22 | "LOADK", 23 | "LOADKX", 24 | "LOADBOOL", 25 | "LOADNIL", 26 | "GETUPVAL", 27 | "GETTABUP", 28 | "GETTABLE", 29 | "SETTABUP", 30 | "SETUPVAL", 31 | "SETTABLE", 32 | "NEWTABLE", 33 | "SELF", 34 | "ADD", 35 | "SUB", 36 | "MUL", 37 | "MOD", 38 | "POW", 39 | "DIV", 40 | "IDIV", 41 | "BAND", 42 | "BOR", 43 | "BXOR", 44 | "SHL", 45 | "SHR", 46 | "UNM", 47 | "BNOT", 48 | "NOT", 49 | "LEN", 50 | "CONCAT", 51 | "JMP", 52 | "EQ", 53 | "LT", 54 | "LE", 55 | "TEST", 56 | "TESTSET", 57 | "CALL", 58 | "TAILCALL", 59 | "RETURN", 60 | "FORLOOP", 61 | "FORPREP", 62 | "TFORCALL", 63 | "TFORLOOP", 64 | "SETLIST", 65 | "CLOSURE", 66 | "VARARG", 67 | "EXTRAARG", 68 | NULL 69 | }; 70 | 71 | 72 | #define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m)) 73 | 74 | LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { 75 | /* T A B C mode opcode */ 76 | opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ 77 | ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ 78 | ,opmode(0, 1, OpArgN, OpArgN, iABx) /* OP_LOADKX */ 79 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ 80 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_LOADNIL */ 81 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ 82 | ,opmode(0, 1, OpArgU, OpArgK, iABC) /* OP_GETTABUP */ 83 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ 84 | ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABUP */ 85 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ 86 | ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ 87 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ 88 | ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */ 89 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ 90 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ 91 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ 92 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ 93 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ 94 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ 95 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_IDIV */ 96 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BAND */ 97 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BOR */ 98 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BXOR */ 99 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHL */ 100 | ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHR */ 101 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ 102 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_BNOT */ 103 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ 104 | ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ 105 | ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ 106 | ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */ 107 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ 108 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ 109 | ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ 110 | ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TEST */ 111 | ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ 112 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ 113 | ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ 114 | ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ 115 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ 116 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ 117 | ,opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */ 118 | ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */ 119 | ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ 120 | ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ 121 | ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ 122 | ,opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */ 123 | }; 124 | 125 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lopcodes.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/lopcodes.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/loslib.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/loslib.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lparser.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lparser.h,v 1.76.1.1 2017/04/19 17:20:42 roberto Exp $ 3 | ** Lua Parser 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lparser_h 8 | #define lparser_h 9 | 10 | #include "llimits.h" 11 | #include "lobject.h" 12 | #include "lzio.h" 13 | 14 | 15 | /* 16 | ** Expression and variable descriptor. 17 | ** Code generation for variables and expressions can be delayed to allow 18 | ** optimizations; An 'expdesc' structure describes a potentially-delayed 19 | ** variable/expression. It has a description of its "main" value plus a 20 | ** list of conditional jumps that can also produce its value (generated 21 | ** by short-circuit operators 'and'/'or'). 22 | */ 23 | 24 | /* kinds of variables/expressions */ 25 | typedef enum { 26 | VVOID, /* when 'expdesc' describes the last expression a list, 27 | this kind means an empty list (so, no expression) */ 28 | VNIL, /* constant nil */ 29 | VTRUE, /* constant true */ 30 | VFALSE, /* constant false */ 31 | VK, /* constant in 'k'; info = index of constant in 'k' */ 32 | VKFLT, /* floating constant; nval = numerical float value */ 33 | VKINT, /* integer constant; nval = numerical integer value */ 34 | VNONRELOC, /* expression has its value in a fixed register; 35 | info = result register */ 36 | VLOCAL, /* local variable; info = local register */ 37 | VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */ 38 | VINDEXED, /* indexed variable; 39 | ind.vt = whether 't' is register or upvalue; 40 | ind.t = table register or upvalue; 41 | ind.idx = key's R/K index */ 42 | VJMP, /* expression is a test/comparison; 43 | info = pc of corresponding jump instruction */ 44 | VRELOCABLE, /* expression can put result in any register; 45 | info = instruction pc */ 46 | VCALL, /* expression is a function call; info = instruction pc */ 47 | VVARARG /* vararg expression; info = instruction pc */ 48 | } expkind; 49 | 50 | 51 | #define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXED) 52 | #define vkisinreg(k) ((k) == VNONRELOC || (k) == VLOCAL) 53 | 54 | typedef struct expdesc { 55 | expkind k; 56 | union { 57 | lua_Integer ival; /* for VKINT */ 58 | lua_Number nval; /* for VKFLT */ 59 | int info; /* for generic use */ 60 | struct { /* for indexed variables (VINDEXED) */ 61 | short idx; /* index (R/K) */ 62 | lu_byte t; /* table (register or upvalue) */ 63 | lu_byte vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */ 64 | } ind; 65 | } u; 66 | int t; /* patch list of 'exit when true' */ 67 | int f; /* patch list of 'exit when false' */ 68 | } expdesc; 69 | 70 | 71 | /* description of active local variable */ 72 | typedef struct Vardesc { 73 | short idx; /* variable index in stack */ 74 | } Vardesc; 75 | 76 | 77 | /* description of pending goto statements and label statements */ 78 | typedef struct Labeldesc { 79 | TString *name; /* label identifier */ 80 | int pc; /* position in code */ 81 | int line; /* line where it appeared */ 82 | lu_byte nactvar; /* local level where it appears in current block */ 83 | } Labeldesc; 84 | 85 | 86 | /* list of labels or gotos */ 87 | typedef struct Labellist { 88 | Labeldesc *arr; /* array */ 89 | int n; /* number of entries in use */ 90 | int size; /* array size */ 91 | } Labellist; 92 | 93 | 94 | /* dynamic structures used by the parser */ 95 | typedef struct Dyndata { 96 | struct { /* list of active local variables */ 97 | Vardesc *arr; 98 | int n; 99 | int size; 100 | } actvar; 101 | Labellist gt; /* list of pending gotos */ 102 | Labellist label; /* list of active labels */ 103 | } Dyndata; 104 | 105 | 106 | /* control of blocks */ 107 | struct BlockCnt; /* defined in lparser.c */ 108 | 109 | 110 | /* state needed to generate code for a given function */ 111 | typedef struct FuncState { 112 | Proto *f; /* current function header */ 113 | struct FuncState *prev; /* enclosing function */ 114 | struct LexState *ls; /* lexical state */ 115 | struct BlockCnt *bl; /* chain of current blocks */ 116 | int pc; /* next position to code (equivalent to 'ncode') */ 117 | int lasttarget; /* 'label' of last 'jump label' */ 118 | int jpc; /* list of pending jumps to 'pc' */ 119 | int nk; /* number of elements in 'k' */ 120 | int np; /* number of elements in 'p' */ 121 | int firstlocal; /* index of first local var (in Dyndata array) */ 122 | short nlocvars; /* number of elements in 'f->locvars' */ 123 | lu_byte nactvar; /* number of active local variables */ 124 | lu_byte nups; /* number of upvalues */ 125 | lu_byte freereg; /* first free register */ 126 | } FuncState; 127 | 128 | 129 | LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, 130 | Dyndata *dyd, const char *name, int firstchar); 131 | 132 | 133 | #endif 134 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lparser.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/lparser.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lprefix.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lprefix.h,v 1.2.1.1 2017/04/19 17:20:42 roberto Exp $ 3 | ** Definitions for Lua code that must come before any other header file 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lprefix_h 8 | #define lprefix_h 9 | 10 | 11 | /* 12 | ** Allows POSIX/XSI stuff 13 | */ 14 | #if !defined(LUA_USE_C89) /* { */ 15 | 16 | #if !defined(_XOPEN_SOURCE) 17 | #define _XOPEN_SOURCE 600 18 | #elif _XOPEN_SOURCE == 0 19 | #undef _XOPEN_SOURCE /* use -D_XOPEN_SOURCE=0 to undefine it */ 20 | #endif 21 | 22 | /* 23 | ** Allows manipulation of large files in gcc and some other compilers 24 | */ 25 | #if !defined(LUA_32BITS) && !defined(_FILE_OFFSET_BITS) 26 | #define _LARGEFILE_SOURCE 1 27 | #define _FILE_OFFSET_BITS 64 28 | #endif 29 | 30 | #endif /* } */ 31 | 32 | 33 | /* 34 | ** Windows stuff 35 | */ 36 | #if defined(_WIN32) /* { */ 37 | 38 | #if !defined(_CRT_SECURE_NO_WARNINGS) 39 | #define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ISO C functions */ 40 | #endif 41 | 42 | #endif /* } */ 43 | 44 | #endif 45 | 46 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lstate.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/lstate.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lstring.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lstring.h,v 1.61.1.1 2017/04/19 17:20:42 roberto Exp $ 3 | ** String table (keep all strings handled by Lua) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lstring_h 8 | #define lstring_h 9 | 10 | #include "lgc.h" 11 | #include "lobject.h" 12 | #include "lstate.h" 13 | 14 | 15 | #define sizelstring(l) (sizeof(union UTString) + ((l) + 1) * sizeof(char)) 16 | 17 | #define sizeludata(l) (sizeof(union UUdata) + (l)) 18 | #define sizeudata(u) sizeludata((u)->len) 19 | 20 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ 21 | (sizeof(s)/sizeof(char))-1)) 22 | 23 | 24 | /* 25 | ** test whether a string is a reserved word 26 | */ 27 | #define isreserved(s) ((s)->tt == LUA_TSHRSTR && (s)->extra > 0) 28 | 29 | 30 | /* 31 | ** equality for short strings, which are always internalized 32 | */ 33 | #define eqshrstr(a,b) check_exp((a)->tt == LUA_TSHRSTR, (a) == (b)) 34 | 35 | 36 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); 37 | LUAI_FUNC unsigned int luaS_hashlongstr (TString *ts); 38 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); 39 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); 40 | LUAI_FUNC void luaS_clearcache (global_State *g); 41 | LUAI_FUNC void luaS_init (lua_State *L); 42 | LUAI_FUNC void luaS_remove (lua_State *L, TString *ts); 43 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s); 44 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); 45 | LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); 46 | LUAI_FUNC TString *luaS_createlngstrobj (lua_State *L, size_t l); 47 | 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lstring.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/lstring.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lstrlib.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/lstrlib.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/ltable.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltable.h,v 2.23.1.2 2018/05/24 19:39:05 roberto Exp $ 3 | ** Lua tables (hash) 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ltable_h 8 | #define ltable_h 9 | 10 | #include "lobject.h" 11 | 12 | 13 | #define gnode(t,i) (&(t)->node[i]) 14 | #define gval(n) (&(n)->i_val) 15 | #define gnext(n) ((n)->i_key.nk.next) 16 | 17 | 18 | /* 'const' to avoid wrong writings that can mess up field 'next' */ 19 | #define gkey(n) cast(const TValue*, (&(n)->i_key.tvk)) 20 | 21 | /* 22 | ** writable version of 'gkey'; allows updates to individual fields, 23 | ** but not to the whole (which has incompatible type) 24 | */ 25 | #define wgkey(n) (&(n)->i_key.nk) 26 | 27 | #define invalidateTMcache(t) ((t)->flags = 0) 28 | 29 | 30 | /* true when 't' is using 'dummynode' as its hash part */ 31 | #define isdummy(t) ((t)->lastfree == NULL) 32 | 33 | 34 | /* allocated size for hash nodes */ 35 | #define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t)) 36 | 37 | 38 | /* returns the key, given the value of a table entry */ 39 | #define keyfromval(v) \ 40 | (gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val)))) 41 | 42 | 43 | LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); 44 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, 45 | TValue *value); 46 | LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key); 47 | LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); 48 | LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); 49 | LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key); 50 | LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); 51 | LUAI_FUNC Table *luaH_new (lua_State *L); 52 | LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize, 53 | unsigned int nhsize); 54 | LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize); 55 | LUAI_FUNC void luaH_free (lua_State *L, Table *t); 56 | LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); 57 | LUAI_FUNC lua_Unsigned luaH_getn (Table *t); 58 | 59 | 60 | #if defined(LUA_DEBUG) 61 | LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); 62 | LUAI_FUNC int luaH_isdummy (const Table *t); 63 | #endif 64 | 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/ltable.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/ltable.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/ltablib.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/ltablib.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/ltm.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltm.c,v 2.38.1.1 2017/04/19 17:39:34 roberto Exp $ 3 | ** Tag methods 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define ltm_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "ldebug.h" 18 | #include "ldo.h" 19 | #include "lobject.h" 20 | #include "lstate.h" 21 | #include "lstring.h" 22 | #include "ltable.h" 23 | #include "ltm.h" 24 | #include "lvm.h" 25 | 26 | 27 | static const char udatatypename[] = "userdata"; 28 | 29 | LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTAGS] = { 30 | "no value", 31 | "nil", "boolean", udatatypename, "number", 32 | "string", "table", "function", udatatypename, "thread", 33 | "proto" /* this last case is used for tests only */ 34 | }; 35 | 36 | 37 | void luaT_init (lua_State *L) { 38 | static const char *const luaT_eventname[] = { /* ORDER TM */ 39 | "__index", "__newindex", 40 | "__gc", "__mode", "__len", "__eq", 41 | "__add", "__sub", "__mul", "__mod", "__pow", 42 | "__div", "__idiv", 43 | "__band", "__bor", "__bxor", "__shl", "__shr", 44 | "__unm", "__bnot", "__lt", "__le", 45 | "__concat", "__call" 46 | }; 47 | int i; 48 | for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]); 50 | luaC_fix(L, obj2gco(G(L)->tmname[i])); /* never collect these names */ 51 | } 52 | } 53 | 54 | 55 | /* 56 | ** function to be used with macro "fasttm": optimized for absence of 57 | ** tag methods 58 | */ 59 | const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { 60 | const TValue *tm = luaH_getshortstr(events, ename); 61 | lua_assert(event <= TM_EQ); 62 | if (ttisnil(tm)) { /* no tag method? */ 63 | events->flags |= cast_byte(1u<metatable; 75 | break; 76 | case LUA_TUSERDATA: 77 | mt = uvalue(o)->metatable; 78 | break; 79 | default: 80 | mt = G(L)->mt[ttnov(o)]; 81 | } 82 | return (mt ? luaH_getshortstr(mt, G(L)->tmname[event]) : luaO_nilobject); 83 | } 84 | 85 | 86 | /* 87 | ** Return the name of the type of an object. For tables and userdata 88 | ** with metatable, use their '__name' metafield, if present. 89 | */ 90 | const char *luaT_objtypename (lua_State *L, const TValue *o) { 91 | Table *mt; 92 | if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) || 93 | (ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL)) { 94 | const TValue *name = luaH_getshortstr(mt, luaS_new(L, "__name")); 95 | if (ttisstring(name)) /* is '__name' a string? */ 96 | return getstr(tsvalue(name)); /* use it as type name */ 97 | } 98 | return ttypename(ttnov(o)); /* else use standard type name */ 99 | } 100 | 101 | 102 | void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, 103 | const TValue *p2, TValue *p3, int hasres) { 104 | ptrdiff_t result = savestack(L, p3); 105 | StkId func = L->top; 106 | setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */ 107 | setobj2s(L, func + 1, p1); /* 1st argument */ 108 | setobj2s(L, func + 2, p2); /* 2nd argument */ 109 | L->top += 3; 110 | if (!hasres) /* no result? 'p3' is third argument */ 111 | setobj2s(L, L->top++, p3); /* 3rd argument */ 112 | /* metamethod may yield only when called from Lua code */ 113 | if (isLua(L->ci)) 114 | luaD_call(L, func, hasres); 115 | else 116 | luaD_callnoyield(L, func, hasres); 117 | if (hasres) { /* if has result, move it to its place */ 118 | p3 = restorestack(L, result); 119 | setobjs2s(L, p3, --L->top); 120 | } 121 | } 122 | 123 | 124 | int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2, 125 | StkId res, TMS event) { 126 | const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ 127 | if (ttisnil(tm)) 128 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ 129 | if (ttisnil(tm)) return 0; 130 | luaT_callTM(L, tm, p1, p2, res, 1); 131 | return 1; 132 | } 133 | 134 | 135 | void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, 136 | StkId res, TMS event) { 137 | if (!luaT_callbinTM(L, p1, p2, res, event)) { 138 | switch (event) { 139 | case TM_CONCAT: 140 | luaG_concaterror(L, p1, p2); 141 | /* call never returns, but to avoid warnings: *//* FALLTHROUGH */ 142 | case TM_BAND: case TM_BOR: case TM_BXOR: 143 | case TM_SHL: case TM_SHR: case TM_BNOT: { 144 | lua_Number dummy; 145 | if (tonumber(p1, &dummy) && tonumber(p2, &dummy)) 146 | luaG_tointerror(L, p1, p2); 147 | else 148 | luaG_opinterror(L, p1, p2, "perform bitwise operation on"); 149 | } 150 | /* calls never return, but to avoid warnings: *//* FALLTHROUGH */ 151 | default: 152 | luaG_opinterror(L, p1, p2, "perform arithmetic on"); 153 | } 154 | } 155 | } 156 | 157 | 158 | int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2, 159 | TMS event) { 160 | if (!luaT_callbinTM(L, p1, p2, L->top, event)) 161 | return -1; /* no metamethod */ 162 | else 163 | return !l_isfalse(L->top); 164 | } 165 | 166 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/ltm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltm.h,v 2.22.1.1 2017/04/19 17:20:42 roberto Exp $ 3 | ** Tag methods 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef ltm_h 8 | #define ltm_h 9 | 10 | 11 | #include "lobject.h" 12 | 13 | 14 | /* 15 | * WARNING: if you change the order of this enumeration, 16 | * grep "ORDER TM" and "ORDER OP" 17 | */ 18 | typedef enum { 19 | TM_INDEX, 20 | TM_NEWINDEX, 21 | TM_GC, 22 | TM_MODE, 23 | TM_LEN, 24 | TM_EQ, /* last tag method with fast access */ 25 | TM_ADD, 26 | TM_SUB, 27 | TM_MUL, 28 | TM_MOD, 29 | TM_POW, 30 | TM_DIV, 31 | TM_IDIV, 32 | TM_BAND, 33 | TM_BOR, 34 | TM_BXOR, 35 | TM_SHL, 36 | TM_SHR, 37 | TM_UNM, 38 | TM_BNOT, 39 | TM_LT, 40 | TM_LE, 41 | TM_CONCAT, 42 | TM_CALL, 43 | TM_N /* number of elements in the enum */ 44 | } TMS; 45 | 46 | 47 | 48 | #define gfasttm(g,et,e) ((et) == NULL ? NULL : \ 49 | ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) 50 | 51 | #define fasttm(l,et,e) gfasttm(G(l), et, e) 52 | 53 | #define ttypename(x) luaT_typenames_[(x) + 1] 54 | 55 | LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS]; 56 | 57 | 58 | LUAI_FUNC const char *luaT_objtypename (lua_State *L, const TValue *o); 59 | 60 | LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); 61 | LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, 62 | TMS event); 63 | LUAI_FUNC void luaT_init (lua_State *L); 64 | 65 | LUAI_FUNC void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, 66 | const TValue *p2, TValue *p3, int hasres); 67 | LUAI_FUNC int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2, 68 | StkId res, TMS event); 69 | LUAI_FUNC void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, 70 | StkId res, TMS event); 71 | LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1, 72 | const TValue *p2, TMS event); 73 | 74 | 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/ltm.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/ltm.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lua: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/lua -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lua.hpp: -------------------------------------------------------------------------------- 1 | // lua.hpp 2 | // Lua header files for C++ 3 | // <> not supplied automatically because Lua also compiles as C++ 4 | 5 | extern "C" { 6 | #include "lua.h" 7 | #include "lualib.h" 8 | #include "lauxlib.h" 9 | } 10 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lua.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/lua.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/luac: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/luac -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/luac.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/luac.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lualib.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lualib.h,v 1.45.1.1 2017/04/19 17:20:42 roberto Exp $ 3 | ** Lua standard libraries 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lualib_h 9 | #define lualib_h 10 | 11 | #include "lua.h" 12 | 13 | 14 | /* version suffix for environment variable names */ 15 | #define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR 16 | 17 | 18 | LUAMOD_API int (luaopen_base) (lua_State *L); 19 | 20 | #define LUA_COLIBNAME "coroutine" 21 | LUAMOD_API int (luaopen_coroutine) (lua_State *L); 22 | 23 | #define LUA_TABLIBNAME "table" 24 | LUAMOD_API int (luaopen_table) (lua_State *L); 25 | 26 | #define LUA_IOLIBNAME "io" 27 | LUAMOD_API int (luaopen_io) (lua_State *L); 28 | 29 | #define LUA_OSLIBNAME "os" 30 | LUAMOD_API int (luaopen_os) (lua_State *L); 31 | 32 | #define LUA_STRLIBNAME "string" 33 | LUAMOD_API int (luaopen_string) (lua_State *L); 34 | 35 | #define LUA_UTF8LIBNAME "utf8" 36 | LUAMOD_API int (luaopen_utf8) (lua_State *L); 37 | 38 | #define LUA_BITLIBNAME "bit32" 39 | LUAMOD_API int (luaopen_bit32) (lua_State *L); 40 | 41 | #define LUA_MATHLIBNAME "math" 42 | LUAMOD_API int (luaopen_math) (lua_State *L); 43 | 44 | #define LUA_DBLIBNAME "debug" 45 | LUAMOD_API int (luaopen_debug) (lua_State *L); 46 | 47 | #define LUA_LOADLIBNAME "package" 48 | LUAMOD_API int (luaopen_package) (lua_State *L); 49 | 50 | 51 | /* open all previous libraries */ 52 | LUALIB_API void (luaL_openlibs) (lua_State *L); 53 | 54 | 55 | 56 | #if !defined(lua_assert) 57 | #define lua_assert(x) ((void)0) 58 | #endif 59 | 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lundump.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lundump.h,v 1.45.1.1 2017/04/19 17:20:42 roberto Exp $ 3 | ** load precompiled Lua chunks 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lundump_h 8 | #define lundump_h 9 | 10 | #include "llimits.h" 11 | #include "lobject.h" 12 | #include "lzio.h" 13 | 14 | 15 | /* data to catch conversion errors */ 16 | #define LUAC_DATA "\x19\x93\r\n\x1a\n" 17 | 18 | #define LUAC_INT 0x5678 19 | #define LUAC_NUM cast_num(370.5) 20 | 21 | #define MYINT(s) (s[0]-'0') 22 | #define LUAC_VERSION (MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR)) 23 | #define LUAC_FORMAT 0 /* this is the official format */ 24 | 25 | /* load one chunk; from lundump.c */ 26 | LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name); 27 | 28 | /* dump one chunk; from ldump.c */ 29 | LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, 30 | void* data, int strip); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lundump.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/lundump.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lutf8lib.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/lutf8lib.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lvm.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lvm.h,v 2.41.1.1 2017/04/19 17:20:42 roberto Exp $ 3 | ** Lua virtual machine 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lvm_h 8 | #define lvm_h 9 | 10 | 11 | #include "ldo.h" 12 | #include "lobject.h" 13 | #include "ltm.h" 14 | 15 | 16 | #if !defined(LUA_NOCVTN2S) 17 | #define cvt2str(o) ttisnumber(o) 18 | #else 19 | #define cvt2str(o) 0 /* no conversion from numbers to strings */ 20 | #endif 21 | 22 | 23 | #if !defined(LUA_NOCVTS2N) 24 | #define cvt2num(o) ttisstring(o) 25 | #else 26 | #define cvt2num(o) 0 /* no conversion from strings to numbers */ 27 | #endif 28 | 29 | 30 | /* 31 | ** You can define LUA_FLOORN2I if you want to convert floats to integers 32 | ** by flooring them (instead of raising an error if they are not 33 | ** integral values) 34 | */ 35 | #if !defined(LUA_FLOORN2I) 36 | #define LUA_FLOORN2I 0 37 | #endif 38 | 39 | 40 | #define tonumber(o,n) \ 41 | (ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n)) 42 | 43 | #define tointeger(o,i) \ 44 | (ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointeger(o,i,LUA_FLOORN2I)) 45 | 46 | #define intop(op,v1,v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2)) 47 | 48 | #define luaV_rawequalobj(t1,t2) luaV_equalobj(NULL,t1,t2) 49 | 50 | 51 | /* 52 | ** fast track for 'gettable': if 't' is a table and 't[k]' is not nil, 53 | ** return 1 with 'slot' pointing to 't[k]' (final result). Otherwise, 54 | ** return 0 (meaning it will have to check metamethod) with 'slot' 55 | ** pointing to a nil 't[k]' (if 't' is a table) or NULL (otherwise). 56 | ** 'f' is the raw get function to use. 57 | */ 58 | #define luaV_fastget(L,t,k,slot,f) \ 59 | (!ttistable(t) \ 60 | ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \ 61 | : (slot = f(hvalue(t), k), /* else, do raw access */ \ 62 | !ttisnil(slot))) /* result not nil? */ 63 | 64 | /* 65 | ** standard implementation for 'gettable' 66 | */ 67 | #define luaV_gettable(L,t,k,v) { const TValue *slot; \ 68 | if (luaV_fastget(L,t,k,slot,luaH_get)) { setobj2s(L, v, slot); } \ 69 | else luaV_finishget(L,t,k,v,slot); } 70 | 71 | 72 | /* 73 | ** Fast track for set table. If 't' is a table and 't[k]' is not nil, 74 | ** call GC barrier, do a raw 't[k]=v', and return true; otherwise, 75 | ** return false with 'slot' equal to NULL (if 't' is not a table) or 76 | ** 'nil'. (This is needed by 'luaV_finishget'.) Note that, if the macro 77 | ** returns true, there is no need to 'invalidateTMcache', because the 78 | ** call is not creating a new entry. 79 | */ 80 | #define luaV_fastset(L,t,k,slot,f,v) \ 81 | (!ttistable(t) \ 82 | ? (slot = NULL, 0) \ 83 | : (slot = f(hvalue(t), k), \ 84 | ttisnil(slot) ? 0 \ 85 | : (luaC_barrierback(L, hvalue(t), v), \ 86 | setobj2t(L, cast(TValue *,slot), v), \ 87 | 1))) 88 | 89 | 90 | #define luaV_settable(L,t,k,v) { const TValue *slot; \ 91 | if (!luaV_fastset(L,t,k,slot,luaH_get,v)) \ 92 | luaV_finishset(L,t,k,v,slot); } 93 | 94 | 95 | 96 | LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2); 97 | LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); 98 | LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); 99 | LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n); 100 | LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode); 101 | LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key, 102 | StkId val, const TValue *slot); 103 | LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key, 104 | StkId val, const TValue *slot); 105 | LUAI_FUNC void luaV_finishOp (lua_State *L); 106 | LUAI_FUNC void luaV_execute (lua_State *L); 107 | LUAI_FUNC void luaV_concat (lua_State *L, int total); 108 | LUAI_FUNC lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y); 109 | LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y); 110 | LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y); 111 | LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb); 112 | 113 | #endif 114 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lvm.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/lvm.o -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lzio.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.c,v 1.37.1.1 2017/04/19 17:20:42 roberto Exp $ 3 | ** Buffered streams 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lzio_c 8 | #define LUA_CORE 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | 15 | #include "lua.h" 16 | 17 | #include "llimits.h" 18 | #include "lmem.h" 19 | #include "lstate.h" 20 | #include "lzio.h" 21 | 22 | 23 | int luaZ_fill (ZIO *z) { 24 | size_t size; 25 | lua_State *L = z->L; 26 | const char *buff; 27 | lua_unlock(L); 28 | buff = z->reader(L, z->data, &size); 29 | lua_lock(L); 30 | if (buff == NULL || size == 0) 31 | return EOZ; 32 | z->n = size - 1; /* discount char being returned */ 33 | z->p = buff; 34 | return cast_uchar(*(z->p++)); 35 | } 36 | 37 | 38 | void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { 39 | z->L = L; 40 | z->reader = reader; 41 | z->data = data; 42 | z->n = 0; 43 | z->p = NULL; 44 | } 45 | 46 | 47 | /* --------------------------------------------------------------- read --- */ 48 | size_t luaZ_read (ZIO *z, void *b, size_t n) { 49 | while (n) { 50 | size_t m; 51 | if (z->n == 0) { /* no bytes in buffer? */ 52 | if (luaZ_fill(z) == EOZ) /* try to read more */ 53 | return n; /* no more input; return number of missing bytes */ 54 | else { 55 | z->n++; /* luaZ_fill consumed first byte; put it back */ 56 | z->p--; 57 | } 58 | } 59 | m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ 60 | memcpy(b, z->p, m); 61 | z->n -= m; 62 | z->p += m; 63 | b = (char *)b + m; 64 | n -= m; 65 | } 66 | return 0; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lzio.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lzio.h,v 1.31.1.1 2017/04/19 17:20:42 roberto Exp $ 3 | ** Buffered streams 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | 8 | #ifndef lzio_h 9 | #define lzio_h 10 | 11 | #include "lua.h" 12 | 13 | #include "lmem.h" 14 | 15 | 16 | #define EOZ (-1) /* end of stream */ 17 | 18 | typedef struct Zio ZIO; 19 | 20 | #define zgetc(z) (((z)->n--)>0 ? cast_uchar(*(z)->p++) : luaZ_fill(z)) 21 | 22 | 23 | typedef struct Mbuffer { 24 | char *buffer; 25 | size_t n; 26 | size_t buffsize; 27 | } Mbuffer; 28 | 29 | #define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) 30 | 31 | #define luaZ_buffer(buff) ((buff)->buffer) 32 | #define luaZ_sizebuffer(buff) ((buff)->buffsize) 33 | #define luaZ_bufflen(buff) ((buff)->n) 34 | 35 | #define luaZ_buffremove(buff,i) ((buff)->n -= (i)) 36 | #define luaZ_resetbuffer(buff) ((buff)->n = 0) 37 | 38 | 39 | #define luaZ_resizebuffer(L, buff, size) \ 40 | ((buff)->buffer = luaM_reallocvchar(L, (buff)->buffer, \ 41 | (buff)->buffsize, size), \ 42 | (buff)->buffsize = size) 43 | 44 | #define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) 45 | 46 | 47 | LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, 48 | void *data); 49 | LUAI_FUNC size_t luaZ_read (ZIO* z, void *b, size_t n); /* read next n bytes */ 50 | 51 | 52 | 53 | /* --------- Private Part ------------------ */ 54 | 55 | struct Zio { 56 | size_t n; /* bytes still unread */ 57 | const char *p; /* current position in buffer */ 58 | lua_Reader reader; /* reader function */ 59 | void *data; /* additional data */ 60 | lua_State *L; /* Lua state (for reader) */ 61 | }; 62 | 63 | 64 | LUAI_FUNC int luaZ_fill (ZIO *z); 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /Chapter7/sunnet/3rd/lua-5.3.5/src/lzio.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/Chapter7/sunnet/3rd/lua-5.3.5/src/lzio.o -------------------------------------------------------------------------------- /Chapter7/sunnet/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 项目名称 2 | project (sunnet) 3 | # CMake最低版本号要求 4 | cmake_minimum_required (VERSION 2.8) 5 | # 头文件目录 6 | include_directories(include) 7 | # 查找./src目录下的所有源文件,保存到DIR_SRCS变量 8 | aux_source_directory(./src DIR_SRCS) 9 | # 添加库文件路径 10 | link_directories(${CMAKE_CURRENT_SOURCE_DIR}/3rd/lua-5.3.5/src/) 11 | # 用C++11 12 | add_definitions(-std=c++11) 13 | # 指定生成目标文件 14 | add_executable(sunnet ${DIR_SRCS}) 15 | # 库文件 16 | find_package (Threads) 17 | target_link_libraries (sunnet ${CMAKE_THREAD_LIBS_INIT}) 18 | #lua头文件、库 19 | include_directories(./3rd/lua-5.3.5/src) 20 | target_link_libraries(sunnet liblua.a) 21 | target_link_libraries(sunnet dl) -------------------------------------------------------------------------------- /Chapter7/sunnet/include/Conn.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | using namespace std; 3 | 4 | class Conn { 5 | public: 6 | enum TYPE { //消息类型 7 | LISTEN = 1, 8 | CLIENT = 2, 9 | }; 10 | 11 | uint8_t type; 12 | int fd; 13 | uint32_t serviceId; 14 | 15 | }; -------------------------------------------------------------------------------- /Chapter7/sunnet/include/ConnWriter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | class WriteObject { 8 | public: 9 | streamsize start; 10 | streamsize len; 11 | shared_ptr buff; 12 | }; 13 | 14 | class ConnWriter { 15 | public: 16 | int fd; 17 | private: 18 | //是否正在关闭 19 | bool isClosing = false; 20 | list> objs; //双向链表 21 | public: 22 | void EntireWrite(shared_ptr buff, streamsize len); 23 | void LingerClose(); //全部发完完再关闭 24 | void OnWriteable(); 25 | private: 26 | void EntireWriteWhenEmpty(shared_ptr buff, streamsize len); 27 | void EntireWriteWhenNotEmpty(shared_ptr buff, streamsize len); 28 | bool WriteFrontObj(); 29 | }; -------------------------------------------------------------------------------- /Chapter7/sunnet/include/LuaAPI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | extern "C" { 4 | #include "lua.h" 5 | } 6 | 7 | using namespace std; 8 | 9 | class LuaAPI { 10 | public: 11 | static void Register(lua_State *luaState); 12 | 13 | static int NewService(lua_State *luaState); 14 | static int KillService(lua_State *luaState); 15 | static int Send(lua_State *luaState); 16 | 17 | static int Listen(lua_State *luaState); 18 | static int CloseConn(lua_State *luaState); 19 | static int Write(lua_State *luaState); 20 | }; 21 | -------------------------------------------------------------------------------- /Chapter7/sunnet/include/Msg.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | using namespace std; 4 | 5 | //消息基类 6 | class BaseMsg { 7 | public: 8 | enum TYPE { //消息类型 9 | SERVICE = 1, 10 | SOCKET_ACCEPT = 2, 11 | SOCKET_RW = 3, 12 | }; 13 | uint8_t type; //消息类型 14 | char load[999999]{}; //用于检测内存泄漏 15 | virtual ~BaseMsg(){}; 16 | }; 17 | 18 | //服务间消息 19 | class ServiceMsg : public BaseMsg { 20 | public: 21 | uint32_t source; //消息发送方 22 | shared_ptr buff; //消息内容 23 | size_t size; //消息内容大小 24 | }; 25 | 26 | //新连接 27 | class SocketAcceptMsg : public BaseMsg { 28 | public: 29 | int listenFd; 30 | int clientFd; 31 | }; 32 | 33 | //可读可写 34 | class SocketRWMsg : public BaseMsg { 35 | public: 36 | int fd; 37 | bool isRead = false; 38 | bool isWrite = false; 39 | }; -------------------------------------------------------------------------------- /Chapter7/sunnet/include/Service.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "Msg.h" 5 | #include "ConnWriter.h" 6 | #include 7 | 8 | extern "C" { 9 | #include "lua.h" 10 | #include "lauxlib.h" 11 | #include "lualib.h" 12 | } 13 | 14 | using namespace std; 15 | 16 | class Service { 17 | public: 18 | //为效率灵活性放在public 19 | 20 | //唯一id 21 | uint32_t id; 22 | //类型 23 | shared_ptr type; 24 | // 是否正在退出 25 | bool isExiting = false; 26 | //消息列表 27 | queue> msgQueue; 28 | pthread_spinlock_t queueLock; 29 | //标记是否在全局队列 true:在队列中,或正在处理 30 | bool inGlobal = false; 31 | pthread_spinlock_t inGlobalLock; 32 | //业务逻辑(仅测试使用) 33 | unordered_map> writers; 34 | public: 35 | //构造和析构函数 36 | Service(); 37 | ~Service(); 38 | //回调函数(编写服务逻辑) 39 | void OnInit(); 40 | void OnMsg(shared_ptr msg); 41 | void OnExit(); 42 | //插入消息 43 | void PushMsg(shared_ptr msg); 44 | //执行消息 45 | bool ProcessMsg(); 46 | void ProcessMsgs(int max); 47 | //全局队列 48 | void SetInGlobal(bool isIn); 49 | private: 50 | //Lua虚拟机 51 | lua_State *luaState; 52 | private: 53 | //取出一条消息 54 | shared_ptr PopMsg(); 55 | //消息处理方法 56 | void OnServiceMsg(shared_ptr msg); 57 | void OnAcceptMsg(shared_ptr msg); 58 | void OnRWMsg(shared_ptr msg); 59 | void OnSocketData(int fd, const char* buff, int len); 60 | void OnSocketWritable(int fd); 61 | void OnSocketClose(int fd); 62 | }; -------------------------------------------------------------------------------- /Chapter7/sunnet/include/SocketWorker.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | using namespace std; 3 | #include 4 | #include 5 | #include "Conn.h" 6 | 7 | class SocketWorker { 8 | private: 9 | //epoll描述符 10 | int epollFd; 11 | public: 12 | void Init(); //初始化 13 | void operator()(); //线程函数 14 | public: 15 | void AddEvent(int fd); 16 | void RemoveEvent(int fd); 17 | void ModifyEvent(int fd, bool epollOut); 18 | private: 19 | void OnEvent(epoll_event ev); 20 | void OnAccept(shared_ptr conn); 21 | void OnRW(shared_ptr conn, bool r, bool w); 22 | }; -------------------------------------------------------------------------------- /Chapter7/sunnet/include/Sunnet.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "Worker.h" 4 | #include "Service.h" 5 | #include 6 | #include "SocketWorker.h" 7 | #include "Conn.h" 8 | 9 | class Worker; 10 | 11 | class Sunnet { 12 | public: 13 | //单例 14 | static Sunnet* inst; 15 | public: 16 | //构造函数 17 | Sunnet(); 18 | //初始化并开始 19 | void Start(); 20 | //等待运行 21 | void Wait(); 22 | //增删服务 23 | uint32_t NewService(shared_ptr type); 24 | void KillService(uint32_t id); //仅限服务自己调用 25 | //发送消息 26 | void Send(uint32_t toId, shared_ptr msg); 27 | //全局队列操作 28 | shared_ptr PopGlobalQueue(); 29 | void PushGlobalQueue(shared_ptr srv); 30 | //让工作线程等待(仅工作线程调用) 31 | void WorkerWait(); 32 | //仅测试 33 | shared_ptr MakeMsg(uint32_t source, char* buff, int len); 34 | //增删查Conn 35 | int AddConn(int fd, uint32_t id, Conn::TYPE type); 36 | shared_ptr GetConn(int fd); 37 | bool RemoveConn(int fd); 38 | //网络连接操作接口(用原始read write) 39 | int Listen(uint32_t port, uint32_t serviceId); 40 | void CloseConn(uint32_t fd); 41 | //对外Event接口 42 | void ModifyEvent(int fd, bool epollOut); 43 | private: 44 | //工作线程 45 | int WORKER_NUM = 3; //工作线程数(配置) 46 | vector workers; //worker对象 47 | vector workerThreads; //线程 48 | //Socket线程 49 | SocketWorker* socketWorker; 50 | thread* socketThread; 51 | //服务列表 52 | unordered_map> services; 53 | uint32_t maxId = 0; //最大ID 54 | pthread_rwlock_t servicesLock; //读写锁 55 | //全局队列 56 | queue> globalQueue; 57 | int globalLen = 0; //队列长度 58 | pthread_spinlock_t globalLock; //锁 59 | //休眠和唤醒 60 | pthread_mutex_t sleepMtx; 61 | pthread_cond_t sleepCond; 62 | int sleepCount = 0; //休眠工作线程数 63 | //Conn列表 64 | unordered_map> conns; 65 | pthread_rwlock_t connsLock; //读写锁 66 | 67 | private: 68 | //开启工作线程 69 | void StartWorker(); 70 | //唤醒工作线程 71 | void CheckAndWeakUp(); 72 | //开启Socket线程 73 | void StartSocket(); 74 | //获取服务 75 | shared_ptr GetService(uint32_t id); 76 | }; -------------------------------------------------------------------------------- /Chapter7/sunnet/include/Worker.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "Sunnet.h" 4 | #include "Service.h" 5 | class Sunnet; 6 | 7 | using namespace std; 8 | 9 | class Worker { 10 | public: 11 | int id; //编号 12 | int eachNum; //每次处理多少条消息 13 | void operator()(); //线程函数 14 | private: 15 | //辅助函数 16 | void CheckAndPutGlobal(shared_ptr srv); 17 | }; -------------------------------------------------------------------------------- /Chapter7/sunnet/service/chat/init.lua: -------------------------------------------------------------------------------- 1 | 2 | local serviceId 3 | local conns = {} 4 | 5 | function OnInit(id) 6 | serviceId = id 7 | print("[lua] chat OnInit id:"..id) 8 | sunnet.Listen(8002, id) 9 | end 10 | 11 | 12 | function OnAcceptMsg(listenfd, clientfd) 13 | print("[lua] chat OnAcceptMsg "..clientfd) 14 | conns[clientfd] = true 15 | end 16 | 17 | 18 | function OnSocketData(fd, buff) 19 | print("[lua] chat OnSocketData "..fd) 20 | for fd, _ in pairs(conns) do 21 | sunnet.Write(fd, buff) 22 | end 23 | end 24 | 25 | function OnSocketClose(fd) 26 | print("[lua] chat OnSocketClose "..fd) 27 | conns[fd] = nil 28 | end -------------------------------------------------------------------------------- /Chapter7/sunnet/service/main/init.lua: -------------------------------------------------------------------------------- 1 | print("run lua init.lua") 2 | 3 | function OnInit(id) 4 | sunnet.NewService("chat") 5 | end 6 | 7 | function OnExit() 8 | print("[lua] main OnExit") 9 | end -------------------------------------------------------------------------------- /Chapter7/sunnet/service/ping/init.lua: -------------------------------------------------------------------------------- 1 | local serviceId 2 | 3 | function OnInit(id) 4 | print("[lua] ping OnInit id:"..id) 5 | serviceId = id 6 | end 7 | 8 | 9 | function OnServiceMsg(source, buff) 10 | local n1 = 0 11 | local n2 = 0 12 | --解码 13 | if buff ~= "start" then 14 | n1, n2 = string.unpack("i4 i4", buff) 15 | end 16 | --处理 17 | print("[lua] ping OnServiceMsg n1:"..n1.." n2:"..n2) 18 | n1 = n1 + 1 19 | n2 = n2 + 2 20 | --编码 21 | buff = string.pack("i4 i4", n1, n2) 22 | sunnet.Send(serviceId, source, buff) 23 | end 24 | 25 | function OnExit() 26 | print("[lua] ping OnExit") 27 | end -------------------------------------------------------------------------------- /Chapter7/sunnet/src/ConnWriter.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "ConnWriter.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | void ConnWriter::EntireWriteWhenEmpty(shared_ptr buff, streamsize len) { 10 | char* s = buff.get() ; 11 | //谨记:>=0, -1&&EAGAIN, -1&&EINTR, -1&&其他 12 | streamsize n = write(fd, s, len); 13 | if(n < 0 && errno == EINTR) { }; //仅提醒你要注意 14 | cout << "EntireWriteWhenEmpty write n=" << n << endl; 15 | //情况1-1:全部写完 16 | if(n >= 0 && n == len) { 17 | return; 18 | } 19 | //情况1-2:写一部分(或没写入) 20 | if( (n > 0 && n < len) || (n < 0 && errno == EAGAIN) ) { 21 | auto obj = make_shared(); 22 | obj->start = n; 23 | obj->buff = buff; 24 | obj->len = len; 25 | objs.push_back(obj); 26 | Sunnet::inst->ModifyEvent(fd, true); 27 | return; 28 | } 29 | //情况1-3:真的发生错误 30 | cout << "EntireWrite write error " << endl; 31 | } 32 | 33 | void ConnWriter::EntireWriteWhenNotEmpty(shared_ptr buff, streamsize len) { 34 | auto obj = make_shared(); 35 | obj->start = 0; 36 | obj->buff = buff; 37 | obj->len = len; 38 | objs.push_back(obj); 39 | } 40 | 41 | void ConnWriter::EntireWrite(shared_ptr buff, streamsize len) { 42 | if(isClosing){ 43 | cout << "EntireWrite fail, because isClosing" << endl; 44 | return; 45 | } 46 | //情况1:没有待写入数据,先尝试写入 47 | if(objs.empty()) { 48 | EntireWriteWhenEmpty(buff, len); 49 | } 50 | //情况2:有待写入数据,添加到末尾 51 | else{ 52 | EntireWriteWhenNotEmpty(buff, len); 53 | } 54 | } 55 | 56 | 57 | //返回值:是否完整的写入了一条 58 | bool ConnWriter::WriteFrontObj() { 59 | //没待写数据 60 | if(objs.empty()) { 61 | return false; 62 | } 63 | //获取第一条 64 | auto obj = objs.front(); 65 | 66 | //谨记:>=0, -1&&EAGAIN, -1&&EINTR, -1&&其他 67 | char* s = obj->buff.get() + obj->start; 68 | int len = obj->len - obj->start; 69 | int n = write(fd, s, len); 70 | cout << "WriteFrontObj write n=" << n << endl; 71 | if(n < 0 && errno == EINTR) { }; //仅提醒你要注意 72 | //情况1-1:全部写完 73 | if(n >= 0 && n == len) { 74 | objs.pop_front(); //出队 75 | return true; 76 | } 77 | //情况1-2:写一部分(或没写入) 78 | if( (n > 0 && n < len) || (n < 0 && errno == EAGAIN) ) { 79 | obj->start += n; 80 | return false; 81 | } 82 | //情况1-3:真的发生错误 83 | cout << "EntireWrite write error " << endl; 84 | } 85 | 86 | void ConnWriter::OnWriteable() { 87 | auto conn = Sunnet::inst->GetConn(fd); 88 | if(conn == NULL){ //连接已关闭 89 | return; 90 | } 91 | 92 | while(WriteFrontObj()){ 93 | //循环 94 | } 95 | 96 | if(objs.empty()) { 97 | Sunnet::inst->ModifyEvent(fd, false); 98 | 99 | if(isClosing) { 100 | //通知服务,此处并不是通用做法 101 | //让read产生 Bad file descriptor报错 102 | cout << "linger close conn" << endl; 103 | shutdown(fd, SHUT_RD); 104 | auto msg= make_shared(); 105 | msg->type = BaseMsg::TYPE::SOCKET_RW; 106 | msg->fd = conn->fd; 107 | msg->isRead = true; 108 | Sunnet::inst->Send(conn->serviceId, msg); 109 | } 110 | } 111 | } 112 | 113 | void ConnWriter::LingerClose(){ 114 | if(isClosing){ 115 | return; 116 | } 117 | isClosing = true; 118 | if(objs.empty()) { 119 | Sunnet::inst->CloseConn(fd); 120 | return; 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /Chapter7/sunnet/src/LuaAPI.cpp: -------------------------------------------------------------------------------- 1 | #include "LuaAPI.h" 2 | #include "stdint.h" 3 | #include "Sunnet.h" 4 | #include 5 | #include 6 | #include 7 | 8 | //注册Lua模块 9 | void LuaAPI::Register(lua_State *luaState) { 10 | 11 | static luaL_Reg lualibs[] = { 12 | { "NewService", NewService }, 13 | { "KillService", KillService }, 14 | { "Send", Send }, 15 | 16 | { "Listen", Listen }, 17 | { "CloseConn", CloseConn }, 18 | { "Write", Write }, 19 | { NULL, NULL } 20 | }; 21 | 22 | luaL_newlib (luaState, lualibs); 23 | lua_setglobal(luaState, "sunnet"); 24 | } 25 | 26 | 27 | //开启新服务 28 | int LuaAPI::NewService(lua_State *luaState) { 29 | //参数个数 30 | int num = lua_gettop(luaState);//获取参数的个数 31 | //参数1:服务类型 32 | if(lua_isstring(luaState, 1) == 0){ //1:是 0:不是 33 | lua_pushinteger(luaState, -1); 34 | return 1; 35 | } 36 | size_t len = 0; 37 | const char *type = lua_tolstring(luaState, 1, &len); 38 | char * newstr = new char[len+1]; //后面加\0 39 | newstr[len] = '\0'; 40 | memcpy(newstr, type, len); 41 | auto t = make_shared(newstr); 42 | //处理 43 | uint32_t id = Sunnet::inst->NewService(t); 44 | //返回值 45 | lua_pushinteger(luaState, id); 46 | return 1; 47 | } 48 | 49 | int LuaAPI::KillService(lua_State *luaState) { 50 | //参数 51 | int num = lua_gettop(luaState);//获取参数的个数 52 | if(lua_isinteger(luaState, 1) == 0) { 53 | return 0; 54 | } 55 | int id = lua_tointeger(luaState, 1); 56 | //处理 57 | Sunnet::inst->KillService(id); 58 | //返回值 59 | //(无) 60 | return 0; 61 | } 62 | 63 | //发送消息 64 | int LuaAPI::Send(lua_State *luaState) { 65 | //参数总数 66 | int num = lua_gettop(luaState); 67 | if(num != 3) { 68 | cout << "Send fail, num err" << endl; 69 | return 0; 70 | } 71 | //参数1:我是谁 72 | if(lua_isinteger(luaState, 1) == 0) { 73 | cout << "Send fail, arg1 err" << endl; 74 | return 0; 75 | } 76 | int source = lua_tointeger(luaState, 1); 77 | //参数2:发送给谁 78 | if(lua_isinteger(luaState, 2) == 0) { 79 | cout << "Send fail, arg2 err" << endl; 80 | return 0; 81 | } 82 | int toId = lua_tointeger(luaState, 2); 83 | //参数3:发送的内容 84 | if(lua_isstring(luaState, 3) == 0){ 85 | cout << "Send fail, arg3 err" << endl; 86 | return 0; 87 | } 88 | size_t len = 0; 89 | const char *buff = lua_tolstring(luaState, 3, &len); 90 | char * newstr = new char[len]; 91 | memcpy(newstr, buff, len); 92 | //处理 93 | auto msg= make_shared(); 94 | msg->type = BaseMsg::TYPE::SERVICE; 95 | msg->source = source; 96 | msg->buff = shared_ptr(newstr); 97 | msg->size = len; 98 | Sunnet::inst->Send(toId, msg); 99 | //返回值 100 | //(无) 101 | return 0; 102 | } 103 | 104 | //开启网络监听 105 | int LuaAPI::Listen(lua_State *luaState){ 106 | //参数个数 107 | int num = lua_gettop(luaState); 108 | //参数1:端口 109 | if(lua_isinteger(luaState, 1) == 0) { 110 | lua_pushinteger(luaState, -1); 111 | return 1; 112 | } 113 | int port = lua_tointeger(luaState, 1); 114 | //参数2:服务Id 115 | if(lua_isinteger(luaState, 2) == 0) { 116 | lua_pushinteger(luaState, -1); 117 | return 1; 118 | } 119 | int id = lua_tointeger(luaState, 2); 120 | //处理 121 | int fd = Sunnet::inst->Listen(port, id); 122 | //返回值 123 | lua_pushinteger(luaState, fd); 124 | return 1; 125 | } 126 | 127 | //关闭连接 128 | int LuaAPI::CloseConn(lua_State *luaState){ 129 | //参数个数 130 | int num = lua_gettop(luaState); 131 | //参数1:fd 132 | if(lua_isinteger(luaState, 1) == 0) { 133 | return 0; 134 | } 135 | int fd = lua_tointeger(luaState, 1); 136 | //处理 137 | Sunnet::inst->CloseConn(fd); 138 | //返回值 139 | //(无) 140 | return 0; 141 | } 142 | 143 | //写套接字 144 | int LuaAPI::Write(lua_State *luaState){ 145 | //参数个数 146 | int num = lua_gettop(luaState); 147 | //参数1:fd 148 | if(lua_isinteger(luaState, 1) == 0) { 149 | lua_pushinteger(luaState, -1); 150 | return 1; 151 | } 152 | int fd = lua_tointeger(luaState, 1); 153 | //参数2:buff 154 | if(lua_isstring(luaState, 2) == 0){ 155 | lua_pushinteger(luaState, -1); 156 | return 1; 157 | } 158 | size_t len = 0; 159 | const char *buff = lua_tolstring(luaState, 2, &len); 160 | //处理 161 | int r = write(fd, buff, len); 162 | //返回值 163 | lua_pushinteger(luaState, r); 164 | return 1; 165 | } -------------------------------------------------------------------------------- /Chapter7/sunnet/src/SocketWorker.cpp: -------------------------------------------------------------------------------- 1 | #include "SocketWorker.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | //初始化 12 | void SocketWorker::Init() { 13 | cout << "SocketWorker Init" << endl; 14 | //创建epoll 15 | epollFd = epoll_create(1024); // 返回值:非负数:成功的描述符,-1失败 16 | assert(epollFd > 0); 17 | } 18 | 19 | 20 | void SocketWorker::OnAccept(shared_ptr conn) { 21 | cout << "OnAccept fd:" << conn->fd << endl; 22 | //步骤1:accept 23 | int clientFd = accept(conn->fd, NULL, NULL); 24 | if (clientFd < 0) { 25 | cout << "accept error" << endl; 26 | } 27 | //步骤2:设置非阻塞 28 | fcntl(clientFd, F_SETFL, O_NONBLOCK); 29 | //写缓冲区大小 30 | //unsigned long buffSize = 4294967295; 31 | //if(setsockopt(clientFd, SOL_SOCKET, SO_SNDBUFFORCE , &buffSize, sizeof(buffSize)) < 0){ 32 | // cout << "OnAccept setsockopt Fail " << strerror(errno) << endl; 33 | //} 34 | //步骤3:添加到管理结构 35 | Sunnet::inst->AddConn(clientFd, conn->serviceId, Conn::TYPE::CLIENT); 36 | //步骤4:添加到epoll 37 | struct epoll_event ev; 38 | ev.events = EPOLLIN | EPOLLET; 39 | ev.data.fd = clientFd; 40 | if (epoll_ctl(epollFd, EPOLL_CTL_ADD, clientFd, &ev) == -1) { 41 | cout << "OnAccept epoll_ctl Fail:" << strerror(errno) << endl; 42 | } 43 | //步骤5:通知 44 | auto msg= make_shared(); 45 | msg->type = BaseMsg::TYPE::SOCKET_ACCEPT; 46 | msg->listenFd = conn->fd; 47 | msg->clientFd = clientFd; 48 | Sunnet::inst->Send(conn->serviceId, msg); 49 | } 50 | 51 | void SocketWorker::OnRW(shared_ptr conn, bool r, bool w) { 52 | cout << "OnRW fd:" << conn->fd << endl; 53 | auto msg= make_shared(); 54 | msg->type = BaseMsg::TYPE::SOCKET_RW; 55 | msg->fd = conn->fd; 56 | msg->isRead = r; 57 | msg->isWrite = w; 58 | Sunnet::inst->Send(conn->serviceId, msg); 59 | } 60 | 61 | 62 | 63 | //处理事件 64 | void SocketWorker::OnEvent(epoll_event ev){ 65 | int fd = ev.data.fd; 66 | auto conn = Sunnet::inst->GetConn(fd); 67 | if(conn == NULL){ 68 | cout << "OnEvent error, conn == NULL" << endl; 69 | return; 70 | } 71 | //事件类型 72 | bool isRead = ev.events & EPOLLIN; 73 | bool isWrite = ev.events & EPOLLOUT; 74 | bool isError = ev.events & EPOLLERR; 75 | //监听Socket 76 | if(conn->type == Conn::TYPE::LISTEN){ 77 | if(isRead) { 78 | OnAccept(conn); 79 | } 80 | } 81 | //普通Socket 82 | else { 83 | if(isRead || isWrite) { 84 | OnRW(conn, isRead, isWrite); 85 | } 86 | if(isError){ 87 | cout << "OnError fd:" << conn->fd << endl; 88 | } 89 | } 90 | } 91 | 92 | void SocketWorker::operator()() { 93 | while(true) { 94 | //阻塞等待 95 | const int EVENT_SIZE = 64; 96 | struct epoll_event events[EVENT_SIZE]; 97 | int eventCount = epoll_wait(epollFd , events, EVENT_SIZE, -1); 98 | //取得事件 99 | for (int i=0; i 2 | #include 3 | #include "Worker.h" 4 | #include "Service.h" 5 | using namespace std; 6 | 7 | //那些调Sunnet的通过传参数解决 8 | //状态是不在队列中,global=true 9 | void Worker::CheckAndPutGlobal(shared_ptr srv) { 10 | //退出中(只能自己调退出,isExiting不会线程冲突) 11 | if(srv->isExiting){ 12 | return; 13 | } 14 | 15 | pthread_spin_lock(&srv->queueLock); 16 | { 17 | //重新放回全局队列 18 | if(!srv->msgQueue.empty()) { 19 | //此时srv->inGlobal一定是true 20 | Sunnet::inst->PushGlobalQueue(srv); 21 | } 22 | //不在队列中,重设inGlobal 23 | else { 24 | srv->SetInGlobal(false); 25 | } 26 | } 27 | pthread_spin_unlock(&srv->queueLock); 28 | } 29 | 30 | 31 | 32 | //线程函数 33 | void Worker::operator()() { 34 | while(true) { 35 | shared_ptr srv = Sunnet::inst->PopGlobalQueue(); 36 | if(!srv){ 37 | Sunnet::inst->WorkerWait(); 38 | } 39 | else{ 40 | srv->ProcessMsgs(eachNum); 41 | CheckAndPutGlobal(srv); 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /Chapter7/sunnet/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "Sunnet.h" 2 | #include 3 | #include 4 | 5 | int testConn() { 6 | Sunnet::inst->AddConn(1, 1, Conn::TYPE::LISTEN); 7 | Sunnet::inst->AddConn(2, 1, Conn::TYPE::CLIENT); 8 | Sunnet::inst->RemoveConn(2); 9 | cout << Sunnet::inst->GetConn(1).get() << endl; 10 | cout << Sunnet::inst->GetConn(2).get() << endl; 11 | } 12 | 13 | int testSocketCtrl() { 14 | int fd = Sunnet::inst->Listen(8001, 1); 15 | usleep(30*1000000); 16 | Sunnet::inst->CloseConn(fd); 17 | } 18 | 19 | 20 | int TestEcho() { 21 | auto t = make_shared("gateway"); 22 | uint32_t gateway = Sunnet::inst->NewService(t); 23 | } 24 | 25 | int main() { 26 | new Sunnet(); 27 | Sunnet::inst->Start(); 28 | //启动main服务 29 | auto t = make_shared("main"); 30 | Sunnet::inst->NewService(t); 31 | //wait 32 | Sunnet::inst->Wait(); 33 | return 0; 34 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # million_game_server 2 | the book of million online game server development 3 | 《百万在线:大型游戏服务端开发》 4 | ![百万在线](https://github.com/luopeiyu/million_game_server/blob/master/web/zcover.jpg) 5 | 6 | 7 | 京东连接 [https://item.jd.com/12931061.html](https://item.jd.com/12931061.html) 8 | 9 | 更多介绍请见WIKI 10 | [首页](https://github.com/luopeiyu/million_game_server/wiki) 11 | [1、这本书讲什么](https://github.com/luopeiyu/million_game_server/wiki/%E8%BF%99%E6%9C%AC%E4%B9%A6%E8%AE%B2%E4%BB%80%E4%B9%88) 12 | [2、服务端成长路线](https://github.com/luopeiyu/million_game_server/wiki/%E6%9C%8D%E5%8A%A1%E7%AB%AF%E6%88%90%E9%95%BF%E8%B7%AF%E7%BA%BF) 13 | [3、案例:球球大作战](https://github.com/luopeiyu/million_game_server/wiki/%E6%A1%88%E4%BE%8B%EF%BC%9A%E7%90%83%E7%90%83%E5%A4%A7%E4%BD%9C%E6%88%98) 14 | [4、案例:C++版Skynet](https://github.com/luopeiyu/million_game_server/wiki/%E6%A1%88%E4%BE%8B%EF%BC%9ACpp%E7%89%88Skynet) 15 | [5、作者是谁](https://github.com/luopeiyu/million_game_server/wiki/%E4%BD%9C%E8%80%85%E6%98%AF%E8%B0%81) 16 | [6、勘误](https://github.com/luopeiyu/million_game_server/wiki/%E5%8B%98%E8%AF%AF) 17 | [7、一些宣传图](https://github.com/luopeiyu/million_game_server/wiki/%E4%B8%80%E4%BA%9B%E5%AE%A3%E4%BC%A0%E5%9B%BE) 18 | 19 | 20 | ## 做个大作战游戏 21 | 书籍第三章将用一个完整游戏案例——球球大作战,介绍分布式游戏服务端的实现。 22 | Skynet的使用方法、服务端拓扑结构设计、如何编写服务端逻辑、如何实现跨服逻辑、如何对网络数据编码解码、如何设计游戏数据库、如何正确关闭服务器、怎样做断线重连 23 | ![球球大作战战斗界面](https://github.com/luopeiyu/million_game_server/blob/master/web/qqdzz2.jpg) 24 | 25 | 26 | 27 | 28 | ## 亲手用C++仿写Skynet 29 | 书中第五部分会以C++仿写Skynet为主线,一方面说明Skynet的调度原理,另一方面介绍C++开发服务端的方法。 30 | 用cmake构建工程、操作系统如何调度进程、栈堆的区别、如何创建线程、智能指针创建C++对象、对象的内存分布、读写锁自旋锁互斥锁的区别、哈希表的使用和性能、锁的临界区控制、如何使用条件变量、半小时学会Epoll、C++嵌入Lua 31 | ![程序的内存示意图](https://github.com/luopeiyu/million_game_server/blob/master/web/sunnet1.jpg) 32 | 33 | 34 | 35 | 36 | ## 同步算法 热更新 防外挂 37 | 状态同步、帧同步、卡顿的原因? 书中第八章探索同步问题 38 | 服务端怎么做热更新?热更新技术的来龙去脉?书中第九章探索热更新问题 39 | 服务端怎么做防外挂?防外挂的常见技巧?书中第十章探索外挂问题 40 | -------------------------------------------------------------------------------- /web/gg1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/web/gg1.jpg -------------------------------------------------------------------------------- /web/gg2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/web/gg2.jpg -------------------------------------------------------------------------------- /web/gg3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/web/gg3.jpg -------------------------------------------------------------------------------- /web/gg4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/web/gg4.jpg -------------------------------------------------------------------------------- /web/qqdzz1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/web/qqdzz1.jpg -------------------------------------------------------------------------------- /web/qqdzz2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/web/qqdzz2.jpg -------------------------------------------------------------------------------- /web/qqdzz3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/web/qqdzz3.jpg -------------------------------------------------------------------------------- /web/readme.md: -------------------------------------------------------------------------------- 1 | 存放一些wiki相关,图片,介绍等内容 2 | -------------------------------------------------------------------------------- /web/sunnet1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/web/sunnet1.jpg -------------------------------------------------------------------------------- /web/zcover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/web/zcover.jpg -------------------------------------------------------------------------------- /web/zcover_big.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/web/zcover_big.jpg -------------------------------------------------------------------------------- /web/zsx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luopeiyu/million_game_server/1d50d1b550baf624770e0fcb8807cda0c3208ab2/web/zsx.jpg --------------------------------------------------------------------------------