---------------------------------------------------------------redis--------------------------------------------------------------
EVALSHA
EVALSHA sha1 numkeys key [key ...] arg [arg ...]
根据给定的 sha1 校验码,对缓存在服务器中的脚本进行求值。
将脚本缓存到服务器的操作可以通过 SCRIPT LOAD 命令进行。
这个命令的其他地方,比如参数的传入方式,都和 EVAL 命令一样。
可用版本:
>= 2.6.0
时间复杂度:
根据脚本的复杂度而定。
EVAL
EVAL script numkeys key [key ...] arg [arg ...]
从 Redis 2.6.0 版本开始,通过内置的 Lua 解释器,可以使用 EVAL 命令对 Lua 脚本进行求值。
script 参数是一段 Lua 5.1 脚本程序,它会被运行在 Redis 服务器上下文中,这段脚本不必(也不应该)定义为一个 Lua 函数。
numkeys 参数用于指定键名参数的个数。
键名参数 key [key ...] 从 EVAL 的第三个参数开始算起,表示在脚本中所用到的那些 Redis 键(key),这些键名参数可以在 Lua 中通过全局变量 KEYS 数组,用 1 为基址的形式访问( KEYS[1] , KEYS[2] ,以此类推)。
在命令的最后,那些不是键名参数的附加参数 arg [arg ...] ,可以在 Lua 中通过全局变量 ARGV 数组访问,访问的形式和 KEYS 变量类似( ARGV[1] 、 ARGV[2] ,诸如此类)。
上面这几段长长的说明可以用一个简单的例子来概括:
> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
1) "key1"
2) "key2"
3) "first"
4) "second"
其中 "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 是被求值的 Lua 脚本,数字 2 指定了键名参数的数量, key1 和 key2 是键名参数,分别使用 KEYS[1] 和 KEYS[2] 访问,而最后的 first 和 second 则是附加参数,可以通过 ARGV[1] 和 ARGV[2] 访问它们。
HMGET key field [field ...]
返回哈希表 key 中,一个或多个给定域的值。
如果给定的域不存在于哈希表,那么返回一个 nil 值。
eg:
redis> HMSET pet dog "doudou" cat "nounou" # 一次设置多个域
OK
redis> HMGET pet dog cat fake_pet # 返回值的顺序和传入参数的顺序一样
1) "doudou"
2) "nounou"
3) (nil) # 不存在的域返回nil值
HGET
HGET key field
返回哈希表 key 中给定域 field 的值。
可用版本:
>= 2.0.0
时间复杂度:
O(1)
返回值:
给定域的值。
当给定域不存在或是给定 key 不存在时,返回 nil 。
# 域存在
redis> HSET site redis redis.com
(integer) 1
redis> HGET site redis
"redis.com"
# 域不存在
redis> HGET site mysql
(nil)
SMEMBERS
SMEMBERS key
返回集合 key 中的所有成员。
不存在的 key 被视为空集合。
可用版本:
>= 1.0.0
时间复杂度:
O(N), N 为集合的基数。
返回值:
集合中的所有成员。
# key 不存在或集合为空
redis> EXISTS not_exists_key
(integer) 0
redis> SMEMBERS not_exists_key
(empty list or set)
# 非空集合
redis> SADD language Ruby Python Clojure
(integer) 3
redis> SMEMBERS language
1) "Python"
2) "Ruby"
3) "Clojure"
HINCRBY
HINCRBY key field increment
为哈希表 key 中的域 field 的值加上增量 increment 。
增量也可以为负数,相当于对给定域进行减法操作。
如果 key 不存在,一个新的哈希表被创建并执行 HINCRBY 命令。
如果域 field 不存在,那么在执行命令前,域的值被初始化为 0 。
对一个储存字符串值的域 field 执行 HINCRBY 命令将造成一个错误。
本操作的值被限制在 64 位(bit)有符号数字表示之内。
可用版本:
>= 2.0.0
时间复杂度:
O(1)
返回值:
执行 HINCRBY 命令之后,哈希表 key 中域 field 的值。
# increment 为正数
redis> HEXISTS counter page_view # 对空域进行设置
(integer) 0
redis> HINCRBY counter page_view 200
(integer) 200
redis> HGET counter page_view
"200"
# increment 为负数
redis> HGET counter page_view
"200"
redis> HINCRBY counter page_view -50
(integer) 150
redis> HGET counter page_view
"150"
# 尝试对字符串值的域执行HINCRBY命令
redis> HSET myhash string hello,world # 设定一个字符串值
(integer) 1
redis> HGET myhash string
"hello,world"
redis> HINCRBY myhash string 1 # 命令执行失败,错误。
(error) ERR hash value is not an integer
redis> HGET myhash string # 原值不变
LRANGE
LRANGE key start stop
返回列表 key 中指定区间内的元素,区间以偏移量 start 和 stop 指定。
下标(index)参数 start 和 stop 都以 0 为底,也就是说,以 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。
HLEN
HLEN key
返回哈希表 key 中域的数量。
时间复杂度:
O(1)
返回值:
哈希表中域的数量。
当 key 不存在时,返回 0 。
HKEYS
HKEYS key
返回哈希表 key 中的所有域。
DEL
DEL key [key ...]
删除给定的一个或多个 key 。
不存在的 key 会被忽略。
LTRIM
LTRIM key start stop
对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。
举个例子,执行命令 LTRIM list 0 2 ,表示只保留列表 list 的前三个元素,其余元素全部删除。
下标(index)参数 start 和 stop 都以 0 为底,也就是说,以 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。
你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
当 key 不是列表类型时,返回一个错误。
LTRIM 命令通常和 LPUSH 命令或 RPUSH 命令配合使用,举个例子:
RPUSH
RPUSH key value [value ...]
将一个或多个值 value 插入到列表 key 的表尾(最右边)。
如果有多个 value 值,那么各个 value 值按从左到右的顺序依次插入到表尾:比如对一个空列表 mylist 执行 RPUSH mylist a b c ,得出的结果列表为 a b c ,等同于执行命令 RPUSH mylist a 、 RPUSH mylist b 、 RPUSH mylist c 。
如果 key 不存在,一个空列表会被创建并执行 RPUSH 操作。
当 key 存在但不是列表类型时,返回一个错误。
-----------------------------------------------------------------------------------------------------------------------------
redisproxy:smembers 对应数据库中只有一个value如carbon ids
redisproxy:hgetall 对应数据库中有key和value如equipFragme
-----------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------
redisproxy.lua注册了两个redis调用方法:
其中runScripts会加载相应的redis_scripts目录下的对应lua(根据redis_scripts.RedisScripts.lua的映射)
-----------------------------------------------------------------------------------------------------------------------------
数据库中的hero的delete字段表示该英雄是否为已点将
--------------------------------------------------lua---------------------------------------------------------------------------
lua 自带的 unpack 可以把一直数组(只有连续数字下标的 table)展开成一串返回值,但是对用字符串或别的东西做 key 的 table 无能为力。
- print(unpack{10,20,30}) --> 10 20 30
- a,b = unpack{10,20,30} -- a=10, b=20, 30 is discarded
-----------------------------------------------------------------------------------------------------------------------------
local nowTime = skynet.time()
local nowDate = os.date("*t", nowTime)
-----------------------------------------------------------------------------------------------------------------------------
删除记录:
redisproxy:del(string.format("gift:%d:%d", self.owner:getProperty("id"), self:getProperty("id")))
redisproxy:srem(string.format("role:%d:giftIds", self.owner:getProperty("id")), self:getProperty("id"))
-----------------------------------------------------------------------------------------------------------------------------
redisproxy:XXX调用的是redisproxy.lua,这里封装了调用redis方法:
local redisproxy = {}
-----------------------------------------------------------------------------------------------------------------------------
setmetatable(redisproxy, { __index = function(t, k)
local cmd = string.upper(k)
local f = function (self, ...)
local ok, result = pcall(skynet.call, "REDIS", "lua", cmd, ...)
if ok then
return result
end
end
t[k] = f
return f
end})
-----------------------------------------------------------------------------------------------------------------------------
--如果当前体力超过上限,重新计时
local healthLimit = self:getHealthLimit()
if origHealth >= healthLimit and origHealth - deltaPoint < healthLimit then
self.timestamps:updateProperty({field = "lastHealthTime", newValue = skynet.time()})
end
local currentHealth = origHealth - deltaPoint
self:setProperty("health", currentHealth);
--通知客户端
self:notifyUpdateProperty("health", currentHealth, origHealth)
-----------------------------------------------------------------------------------------------------------------------------
git:
ignore:可以忽略要更新的文件
stash暂存,更新完后再点左边stash生成的暂存文件apply应用到当前分支上
-----------------------------------------------------------------------------------------------------------------------------
战斗流程:
各类型战斗继承BaseBattleLayer,执行流程:
BattleLoadingLayer->
BaseBattleLayer:initCommonUI(初始化战场UI,武将等)->
具体XXXBattleLayer:initBattleField(初始化战斗数据)->隐藏/显示一些UI->BaseBattleLayer:savePveFormation(保存阵型数据)->
logical.battle.Battle:init(初始化战斗逻辑)
等开始战斗后调用self.battleLogic:schedule()开始计算战斗
发送消息到服务端:
local bin = pb.encode("SimpleEvent", {roleId = game.role.id, param1 = self.equip.id, param2 = flag})
game:sendData(actionCodes.EquipIntensifyRequest, bin)
这里actionCodes.EquipIntensifyRequest="Equip.intensify"
服务端会执行gamescripts/actions/EquipAction.lua中的intensify方法(上面的Equip对应下面的EquipAction)
-----------------------------------------------------------------------------------------------------------------------------
红点提示:9999
self.evolutionBtn:removeChildByTag(9999)
if self.curHero and self.curHero:canEvolution() then
uihelper.newMsgTag(self.evolutionBtn, ccp(-10, -10))
end
newMainLayer中每一秒检查一次红点的提示
game.role:updateNewMsgTag()
self.newMsgUpdate = scheduler.scheduleGlobal(function()
game.role:updateNewMsgTag()
end, 1)
-----------------------------------------------------------------------------------------------------------------------------
事件侦听:
self.updateHealthHandler = game.role:addEventListener("updateHealth", handler(self, self.onUpdateHealth))
退出时删除事件侦听
function CarbonLayer:onExit()
game.role:removeEventListener("updateHealth", self.updateHealthHandler)
end
game侦听:
game:addEventListener(actionModules[actionCodes.StoreDrawCardResponse], function(event)
。。。
return "__REMOVE__" --删除这个侦听
end)
-----------------------------------------------------------------------------------------------------------------------------
tableView:
local function createCellNode(parentNode, cellIndex)
parentNode:removeAllChildren()
parentNode:setContentSize(CCSizeMake(contentSize.width, cellSize.height + 10))
local xBegin = 25
local xInterval = (contentSize.width - 2 * xBegin - columns * cellSize.width) / (columns - 1)
local rows = math.ceil( #self.heroFilter:getResult() / columns )
for index = (rows - cellIndex - 1) * columns + 1, columns * (rows - cellIndex) do
local hero = self.heroFilter:getResult()[index]
local nativeIndex = index - (rows - cellIndex - 1) * columns
local cellNode = display.newNode()
cellNode:size(cellSize)
local unitData = unitCsv:getUnitByType(hero and hero.type or 0)
if unitData then
local heroBtn = HeroListCell.new(
{
priority = self.priority - 1,
type = hero.type,
level = hero.level,
wakeLevel = hero.wakeLevel,
evolutionCount = hero.evolutionCount,
callback = function()
self.parent.mainHeroId = hero.id
self.parent:reloadHeroData()
self.parent.fodderHeroIds = {}
self.parent:initContentLeft()
self.parent:initContentRight()
self:getLayer():removeSelf()
end,
})
heroBtn:getLayer():addTo(cellNode)
-- if hero.choose == 1 then
-- display.newSprite(HeroRes .. "choose_tag.png"):anch(1, 1):pos(cellSize.width - 10, cellSize.height)
-- :addTo(cellNode, 10)
-- end
-- 选择
local blueBtn = DGBtn:new( GlobalRes, {"middle_normal.png", "middle_selected.png"}, {
callback = function ()
self.parent.mainHeroId = hero.id
self.parent:reloadHeroData()
self.parent.fodderHeroIds = {}
self.parent:initContentLeft()
self.parent:initContentRight()
self:getLayer():removeSelf()
end,
priority = self.priority -2,
text = { text = "选择", size = 26, font = ChineseFont, color=display.COLOR_WHITE, strokeColor = display.COLOR_FONT, strokeSize = 2}
})
blueBtn:getLayer():anch(0.5,0.5):pos(cellSize.width - 100, cellSize.height / 2 - 15):addTo(cellNode)
end
cellNode:anch(0, 0):pos(xBegin + (cellSize.width + xInterval) * (nativeIndex - 1), 0)
:addTo(parentNode)
end
end
local viewHandler = LuaEventHandler:create(function(fn, table, a1, a2)
local result
if fn == "cellSize" then
result = CCSizeMake(contentSize.width, cellSize.height + 10)
elseif fn == "cellAtIndex" then
if not a2 then
a2 = CCTableViewCell:new()
local cell = display.newNode()
a2:addChild(cell, 0, 1)
end
-- 更新cell
local cell = tolua.cast(a2:getChildByTag(1), "CCNode")
createCellNode(cell, a1)
result = a2
elseif fn == "numberOfCells" then
result = math.ceil( #self.heroFilter:getResult() / columns )
end
return result
end)
local tableSize = CCSizeMake(contentSize.width, contentSize.height - filterBar:getContentSize().height - 40)
self.heroTableView = LuaTableView:createWithHandler(viewHandler, tableSize)
self.heroTableView:setBounceable(true)
self.heroTableView:setTouchPriority(self.priority -2)
self.heroTableView:setPosition(0, 20)
self.contentLayer:addChild(self.heroTableView)
-----------------------------------------------------------------------------------------------------------------------------
启动 终端 应用程序, 运行命令:
$ touch ~/.bash_profile
$ open ~/.bash_profile -a TextEdit
添加下列代码:
export ANDROID_NDK_ROOT=<PATH_TO>/android/android-ndk-r8e
export ANDROID_SDK_ROOT=<PATH_TO>/android/android-sdk-macosx
export QUICK_COCOS2DX_ROOT=<PATH_TO>/quick-cocos2d-x
export COCOS2DX_ROOT=${QUICK_COCOS2DX_ROOT}/lib/cocos2d-x
export ANDROID_HOME=${ANDROID_SDK_ROOT}
-----------------------------------------------------------------------------------------------------------------------------
ftp: 192.168.1.193 用户名:ftp 密码: dangge