Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added Moai Pubnub Api

  • Loading branch information...
commit d4e39310fc9bce53cc5a44c84f8054335f6485db 1 parent 56e0c15
@lattejed lattejed authored
View
516 lua-moai/BinDecHex.lua
@@ -0,0 +1,516 @@
+--[[
+/*
+ * Copyright (c) 2007 Tim Kelly/Dialectronics
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to permit
+ * persons to whom the Software is furnished to do so, subject to the
+ * following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
+ * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+--]]
+
+module(..., package.seeall);
+
+local hex2bin = {
+ ["0"] = "0000",
+ ["1"] = "0001",
+ ["2"] = "0010",
+ ["3"] = "0011",
+ ["4"] = "0100",
+ ["5"] = "0101",
+ ["6"] = "0110",
+ ["7"] = "0111",
+ ["8"] = "1000",
+ ["9"] = "1001",
+ ["a"] = "1010",
+ ["b"] = "1011",
+ ["c"] = "1100",
+ ["d"] = "1101",
+ ["e"] = "1110",
+ ["f"] = "1111"
+ }
+
+
+
+local bin2hex = {
+ ["0000"] = "0",
+ ["0001"] = "1",
+ ["0010"] = "2",
+ ["0011"] = "3",
+ ["0100"] = "4",
+ ["0101"] = "5",
+ ["0110"] = "6",
+ ["0111"] = "7",
+ ["1000"] = "8",
+ ["1001"] = "9",
+ ["1010"] = "A",
+ ["1011"] = "B",
+ ["1100"] = "C",
+ ["1101"] = "D",
+ ["1110"] = "E",
+ ["1111"] = "F"
+ }
+
+--[[
+local dec2hex = {
+ ["0"] = "0",
+ ["1"] = "1",
+ ["2"] = "2",
+ ["3"] = "3",
+ ["4"] = "4",
+ ["5"] = "5",
+ ["6"] = "6",
+ ["7"] = "7",
+ ["8"] = "8",
+ ["9"] = "9",
+ ["10"] = "A",
+ ["11"] = "B",
+ ["12"] = "C",
+ ["13"] = "D",
+ ["14"] = "E",
+ ["15"] = "F"
+ }
+--]]
+
+
+-- These functions are big-endian and take up to 32 bits
+
+-- Hex2Bin
+-- Bin2Hex
+-- Hex2Dec
+-- Dec2Hex
+-- Bin2Dec
+-- Dec2Bin
+
+
+function Hex2Bin(s)
+
+-- s -> hexadecimal string
+
+local ret = ""
+local i = 0
+
+
+ for i in string.gfind(s, ".") do
+ i = string.lower(i)
+
+ ret = ret..hex2bin[i]
+
+ end
+
+ return ret
+end
+
+
+function Bin2Hex(s)
+
+-- s -> binary string
+
+local l = 0
+local h = ""
+local b = ""
+local rem
+
+l = string.len(s)
+rem = l % 4
+l = l-1
+h = ""
+
+ -- need to prepend zeros to eliminate mod 4
+ if (rem > 0) then
+ s = string.rep("0", 4 - rem)..s
+ end
+
+ for i = 1, l, 4 do
+ b = string.sub(s, i, i+3)
+ h = h..bin2hex[b]
+ end
+
+ return h
+
+end
+
+
+function Bin2Dec(s)
+
+-- s -> binary string
+
+local num = 0
+local ex = string.len(s) - 1
+local l = 0
+
+ l = ex + 1
+ for i = 1, l do
+ b = string.sub(s, i, i)
+ if b == "1" then
+ num = num + 2^ex
+ end
+ ex = ex - 1
+ end
+
+ return string.format("%u", num)
+
+end
+
+
+
+function Dec2Bin(s, num)
+
+-- s -> Base10 string
+-- num -> string length to extend to
+
+local n
+
+ if (num == nil) then
+ n = 0
+ else
+ n = num
+ end
+
+ s = string.format("%x", s)
+
+ s = Hex2Bin(s)
+
+ while string.len(s) < n do
+ s = "0"..s
+ end
+
+ return s
+
+end
+
+
+
+
+function Hex2Dec(s)
+
+-- s -> hexadecimal string
+
+local s = Hex2Bin(s)
+
+ return Bin2Dec(s)
+
+end
+
+
+
+function Dec2Hex(s)
+
+-- s -> Base10 string
+
+ s = string.format("%x", s)
+
+ return s
+
+end
+
+
+
+
+-- These functions are big-endian and will extend to 32 bits
+
+-- BMAnd
+-- BMNAnd
+-- BMOr
+-- BMXOr
+-- BMNot
+
+
+function BMAnd(v, m)
+
+-- v -> hex string to be masked
+-- m -> hex string mask
+
+-- s -> hex string as masked
+
+-- bv -> binary string of v
+-- bm -> binary string mask
+
+local bv = Hex2Bin(v)
+local bm = Hex2Bin(m)
+
+local i = 0
+local s = ""
+
+ while (string.len(bv) < 32) do
+ bv = "0000"..bv
+ end
+
+ while (string.len(bm) < 32) do
+ bm = "0000"..bm
+ end
+
+
+ for i = 1, 32 do
+ cv = string.sub(bv, i, i)
+ cm = string.sub(bm, i, i)
+ if cv == cm then
+ if cv == "1" then
+ s = s.."1"
+ else
+ s = s.."0"
+ end
+ else
+ s = s.."0"
+
+ end
+ end
+
+ return Bin2Hex(s)
+
+end
+
+
+function BMNAnd(v, m)
+
+-- v -> hex string to be masked
+-- m -> hex string mask
+
+-- s -> hex string as masked
+
+-- bv -> binary string of v
+-- bm -> binary string mask
+
+local bv = Hex2Bin(v)
+local bm = Hex2Bin(m)
+
+local i = 0
+local s = ""
+
+ while (string.len(bv) < 32) do
+ bv = "0000"..bv
+ end
+
+ while (string.len(bm) < 32) do
+ bm = "0000"..bm
+ end
+
+
+ for i = 1, 32 do
+ cv = string.sub(bv, i, i)
+ cm = string.sub(bm, i, i)
+ if cv == cm then
+ if cv == "1" then
+ s = s.."0"
+ else
+ s = s.."1"
+ end
+ else
+ s = s.."1"
+
+ end
+ end
+
+ return Bin2Hex(s)
+
+end
+
+
+
+function BMOr(v, m)
+
+-- v -> hex string to be masked
+-- m -> hex string mask
+
+-- s -> hex string as masked
+
+-- bv -> binary string of v
+-- bm -> binary string mask
+
+local bv = Hex2Bin(v)
+local bm = Hex2Bin(m)
+
+local i = 0
+local s = ""
+
+ while (string.len(bv) < 32) do
+ bv = "0000"..bv
+ end
+
+ while (string.len(bm) < 32) do
+ bm = "0000"..bm
+ end
+
+
+ for i = 1, 32 do
+ cv = string.sub(bv, i, i)
+ cm = string.sub(bm, i, i)
+ if cv == "1" then
+ s = s.."1"
+ elseif cm == "1" then
+ s = s.."1"
+ else
+ s = s.."0"
+ end
+ end
+
+ return Bin2Hex(s)
+
+end
+
+function BMXOr(v, m)
+
+-- v -> hex string to be masked
+-- m -> hex string mask
+
+-- s -> hex string as masked
+
+-- bv -> binary string of v
+-- bm -> binary string mask
+
+local bv = Hex2Bin(v)
+local bm = Hex2Bin(m)
+
+local i = 0
+local s = ""
+
+ while (string.len(bv) < 32) do
+ bv = "0000"..bv
+ end
+
+ while (string.len(bm) < 32) do
+ bm = "0000"..bm
+ end
+
+
+ for i = 1, 32 do
+ cv = string.sub(bv, i, i)
+ cm = string.sub(bm, i, i)
+ if cv == "1" then
+ if cm == "0" then
+ s = s.."1"
+ else
+ s = s.."0"
+ end
+ elseif cm == "1" then
+ if cv == "0" then
+ s = s.."1"
+ else
+ s = s.."0"
+ end
+ else
+ -- cv and cm == "0"
+ s = s.."0"
+ end
+ end
+
+ return Bin2Hex(s)
+
+end
+
+
+function BMNot(v, m)
+
+-- v -> hex string to be masked
+-- m -> hex string mask
+
+-- s -> hex string as masked
+
+-- bv -> binary string of v
+-- bm -> binary string mask
+
+local bv = Hex2Bin(v)
+local bm = Hex2Bin(m)
+
+local i = 0
+local s = ""
+
+ while (string.len(bv) < 32) do
+ bv = "0000"..bv
+ end
+
+ while (string.len(bm) < 32) do
+ bm = "0000"..bm
+ end
+
+
+ for i = 1, 32 do
+ cv = string.sub(bv, i, i)
+ cm = string.sub(bm, i, i)
+ if cm == "1" then
+ if cv == "1" then
+ -- turn off
+ s = s.."0"
+ else
+ -- turn on
+ s = s.."1"
+ end
+ else
+ -- leave untouched
+ s = s..cv
+
+ end
+ end
+
+ return Bin2Hex(s)
+
+end
+
+
+-- these functions shift right and left, adding zeros to lost or gained bits
+-- returned values are 32 bits long
+
+-- BShRight(v, nb)
+-- BShLeft(v, nb)
+
+
+function BShRight(v, nb)
+
+-- v -> hexstring value to be shifted
+-- nb -> number of bits to shift to the right
+
+-- s -> binary string of v
+
+local s = Hex2Bin(v)
+
+ while (string.len(s) < 32) do
+ s = "0000"..s
+ end
+
+ s = string.sub(s, 1, 32 - nb)
+
+ while (string.len(s) < 32) do
+ s = "0"..s
+ end
+
+ return Bin2Hex(s)
+
+end
+
+function BShLeft(v, nb)
+
+-- v -> hexstring value to be shifted
+-- nb -> number of bits to shift to the right
+
+-- s -> binary string of v
+
+local s = Hex2Bin(v)
+
+ while (string.len(s) < 32) do
+ s = "0000"..s
+ end
+
+ s = string.sub(s, nb + 1, 32)
+
+ while (string.len(s) < 32) do
+ s = s.."0"
+ end
+
+ return Bin2Hex(s)
+
+end
View
24 lua-moai/README
@@ -0,0 +1,24 @@
+## ------------------------------------------------------
+## PubNub 3.1 Real-time Cloud Push API - Moai
+## ------------------------------------------------------
+##
+## www.pubnub.com - PubNub Real-time Push Service in the Cloud.
+##
+## PubNub is a Massively Scalable Real-time Service for Web and Mobile Games.
+## This is a cloud-based service for broadcasting Real-time messages
+## to thousands of web and mobile clients simultaneously.
+
+## ------------------------------------------------------
+## Moai Push API
+## ------------------------------------------------------
+##
+## Moai Multiplayer Networking and Push Notifications
+## Moai is the mobile platform for pro game developers
+## More information and free SDK at http://getmoai.com
+##
+## Copy "pubnub.lua" and "BinDecHex.lua" into your Project Directory.
+##
+## To try the example run the following from your terminal:
+## >> /<path to your moai host> ./main.lua
+##
+## Usage examples are provided in "main.lua"
View
121 lua-moai/main.lua
@@ -0,0 +1,121 @@
+--[[
+* The MIT License
+* Copyright (C) 2012 Matthew Smith <matthew@rapidfirestudio.com>.
+* All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining
+* a copy of this software and associated documentation files (the
+* "Software"), to deal in the Software without restriction, including
+* without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to
+* permit persons to whom the Software is furnished to do so, subject to
+* the following conditions:
+*
+* The above copyright notice and this permission notice shall be
+* included in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+--]]
+
+require "pubnub"
+
+MOAISim.openWindow ( "pubnub-test", 320, 480 )
+
+MOAIGfxDevice.setClearColor ( 1, 1, 1, 1 )
+
+--
+-- GET YOUR PUBNUB KEYS HERE:
+-- http://www.pubnub.com/account#api-keys
+--
+pn = pubnub.new ( {
+ publish_key = "demo", -- YOUR PUBLISH KEY
+ subscribe_key = "demo", -- YOUR SUBSCRIBE KEY
+ secret_key = nil, -- YOUR SECRET KEY
+ ssl = nil, -- ENABLE SSL?
+ origin = "pubsub.pubnub.com" -- PUBNUB CLOUD ORIGIN
+} )
+
+--
+-- PUBNUB PUBLISH MESSAGE (SEND A MESSAGE)
+--
+pn:publish ( {
+ channel = "lua-moai-demo-channel",
+ message = { "1234", 2, 3, 4 },
+ callback = function ( info )
+
+ -- WAS MESSAGE DELIVERED?
+ if info[1] then
+ print ( "MESSAGE DELIVERED SUCCESSFULLY!" )
+ else
+ print ( "MESSAGE FAILED BECAUSE -> " .. info[2] )
+ end
+
+ end
+} )
+
+--
+-- PUBNUB SUBSCRIBE CHANNEL (RECEIVE MESSAGES)
+--
+pn:subscribe ( {
+ channel = "lua-moai-demo-channel",
+ callback = function ( message )
+ -- MESSAGE RECEIVED!!!
+ print ( MOAIJsonParser.encode ( message ) )
+ end,
+ errorback = function()
+ print ( "Network Connection Lost" )
+ end
+} )
+
+--
+-- PUBNUB UN-SUBSCRIBE CHANNEL (STOP RECEIVING MESSAGES)
+--
+pn:unsubscribe ( {
+ channel = "lua-moai-demo-channel"
+} )
+
+--
+-- PUBNUB LOAD MESSAGE HISTORY
+--
+pn:history ( {
+ channel = "lua-moai-demo-channel",
+ limit = 10,
+ callback = function ( messages )
+ if not messages then
+ return print ( "ERROR LOADING HISTORY" )
+ end
+
+ -- NO HISTORY?
+ if not ( #messages > 0 ) then
+ return print ( "NO HISTORY YET" )
+ end
+
+ -- LOOP THROUGH MESSAGE HISTORY
+ for i, message in ipairs ( messages ) do
+ print ( MOAIJsonParser.encode ( message ) )
+ end
+ end
+} )
+
+
+--
+-- PUBNUB SERVER TIME
+--
+pn:time ( {
+ callback = function ( time )
+ -- PRINT TIME
+ print ( "PUBNUB SERVER TIME: " .. time )
+ end
+} )
+
+--
+-- PUBNUB UUID
+--
+uuid = pn:UUID ()
+print ( "PUBNUB UUID: ", uuid )
View
287 lua-moai/pubnub.lua
@@ -0,0 +1,287 @@
+-- www.pubnub.com - PubNub realtime push service in the cloud.
+
+-- PubNub Real Time Push APIs and Notifications Framework
+-- Copyright (c) 2010 Stephen Blum
+-- http://www.pubnub.com/
+
+-- -----------------------------------
+-- PubNub 3.1 Real-time Push Cloud API
+-- -----------------------------------
+
+module ( "pubnub", package.seeall )
+
+require "BinDecHex"
+
+pubnub = {}
+
+function new ( init )
+
+ local self = init
+ local subscriptions = {}
+
+ -- SSL ENABLED?
+ if self.ssl then
+ self.origin = "https://" .. self.origin
+ else
+ self.origin = "http://" .. self.origin
+ end
+
+ function self:performWithDelay ( delay, func, ... )
+ local t = MOAITimer.new()
+ t:setSpan ( delay )
+ t:setListener ( MOAITimer.EVENT_TIMER_END_SPAN, function ()
+ t:stop ()
+ t = nil
+ func ( unpack ( arg ) )
+ end )
+ t:start ()
+ end
+
+ function self:publish ( args )
+ local callback = args.callback or function() end
+
+ if not ( args.channel and args.message ) then
+ return callback ( { nil, "Missing Channel and/or Message" } )
+ end
+
+ local channel = args.channel
+ local message = MOAIJsonParser.encode ( args.message )
+ local signature = "0"
+
+ -- SIGN PUBLISHED MESSAGE?
+ if self.secret_key then
+ signature = crypto.hmac.digest ( "sha256", self.secret_key, table.concat( {
+ self.publish_key,
+ self.subscribe_key,
+ self.secret_key,
+ channel,
+ message
+ }, "/" ) )
+ end
+
+ -- PUBLISH MESSAGE
+ self:_request ( {
+ callback = function ( response )
+ if not response then
+ return callback ( { nil, "Connection Lost" } )
+ end
+ callback ( response )
+ end,
+ request = {
+ "publish",
+ self.publish_key,
+ self.subscribe_key,
+ signature,
+ self:_encode ( channel ),
+ "0",
+ self:_encode ( message )
+ }
+ })
+ end
+
+ function self:subscribe ( args )
+
+ local channel = args.channel
+ local callback = callback or args.callback
+ local errorback = args [ 'errorback' ] or function () end
+ local connectcb = args [ 'connect' ] or function () end
+ local timetoken = 0
+
+ if not channel then return print ( "Missing Channel" ) end
+ if not callback then return print ( "Missing Callback" ) end
+
+ -- NEW CHANNEL?
+ if not subscriptions [ channel ] then
+ subscriptions [ channel ] = {}
+ end
+
+ -- ENSURE SINGLE CONNECTION
+ if ( subscriptions [ channel ].connected ) then
+ return print ( "Already Connected" )
+ end
+
+ subscriptions [ channel ].connected = 1
+ subscriptions [ channel ].first = nil
+
+ -- SUBSCRIPTION RECURSION
+ local function substabizel ()
+
+ -- STOP CONNECTION?
+ if not subscriptions [ channel ].connected then return end
+
+ -- CONNECT TO PUBNUB SUBSCRIBE SERVERS
+ self:_request ( {
+ callback = function ( response )
+ -- STOP CONNECTION?
+ if not subscriptions [ channel ].connected then return end
+
+ -- CONNECTED CALLBACK
+ if not subscriptions [ channel ].first then
+ subscriptions [ channel ].first = true
+ connectcb ()
+ end
+
+ -- PROBLEM?
+ if not response then
+ -- ENSURE CONNECTED
+ return self:time ( {
+ callback = function ( time )
+ if not time then
+ self:performWithDelay ( 1, substabizel )
+ return errorback ( "Lost Network Connection" )
+ end
+ self:performWithDelay ( 0.01, substabizel )
+ end
+ })
+ end
+
+ timetoken = response [ 2 ]
+ self:performWithDelay( 0.001, substabizel )
+
+ for i, message in ipairs ( response [ 1 ] ) do
+ callback ( message )
+ end
+ end,
+ request = {
+ "subscribe",
+ self.subscribe_key,
+ self:_encode ( channel ),
+ "0",
+ timetoken
+ }
+ })
+ end
+
+ -- BEGIN SUBSCRIPTION (LISTEN FOR MESSAGES)
+ substabizel ()
+
+ end
+
+ function self:unsubscribe ( args )
+ local channel = args.channel
+ if not subscriptions [ channel ] then return nil end
+
+ -- DISCONNECT
+ subscriptions [ channel ].connected = nil
+ subscriptions [ channel ].first = nil
+ end
+
+ function self:history ( args )
+ if not ( args.callback and args.channel ) then
+ return print ( "Missing History Callback and/or Channel" )
+ end
+
+ local limit = args.limit
+ local channel = args.channel
+ local callback = args.callback
+
+ if not limit then limit = 10 end
+
+ self:_request ( {
+ callback = callback,
+ request = {
+ 'history',
+ self.subscribe_key,
+ self:_encode ( channel ),
+ '0',
+ limit
+ }
+ })
+ end
+
+ function self:time ( args )
+ if not args.callback then
+ return print ( "Missing Time Callback" )
+ end
+
+ self:_request ( {
+ request = { "time", "0" },
+ callback = function ( response )
+
+ if response then
+ return args.callback ( response [ 1 ] )
+ end
+ args.callback ( nil )
+ end
+ })
+ end
+
+ function self:_request ( args )
+
+ -- APPEND PUBNUB CLOUD ORIGIN
+ table.insert ( args.request, 1, self.origin )
+
+ local url = table.concat ( args.request, "/" )
+
+ print ( url )
+
+ local task = MOAIHttpTask.new ()
+ task:setHeader ( "V", "3.1" )
+ task:setHeader ( "User-Agent", "Moai" )
+ task:setUrl ( url )
+ task:setCallback ( function ( response )
+
+ if response.code then -- this appears to return no code if no error, need to check more
+ return args.callback ( nil )
+ end
+ status, message = pcall ( MOAIJsonParser.decode, response:getString () )
+
+ if status then
+ return args.callback ( message )
+ else
+ return args.callback ( nil )
+ end
+
+ end )
+
+ task:performAsync ()
+ end
+
+ function self:_encode ( str )
+ str = string.gsub ( str, "([^%w])", function ( c )
+ return string.format ( "%%%02X", string.byte ( c ) )
+ end )
+ return str
+ end
+
+ function self:_map ( func, array )
+ local new_array = {}
+ for i,v in ipairs(array) do
+ new_array [ i ] = func ( v )
+ end
+ return new_array
+ end
+
+ function self:UUID()
+ local chars = {"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"}
+ local uuid = {[9]="-",[14]="-",[15]="4",[19]="-",[24]="-"}
+ local r, index
+
+ local Hex2Dec, BMOr, BMAnd, Dec2Hex
+ if(BinDecHex)then
+ Hex2Dec, BMOr, BMAnd, Dec2Hex = BinDecHex.Hex2Dec, BinDecHex.BMOr, BinDecHex.BMAnd, BinDecHex.Dec2Hex
+ end
+
+ for i = 1,36 do
+ if(uuid[i]==nil)then
+ -- r = 0 | Math.random()*16;
+ r = math.random (36)
+ if(i == 20 and BinDecHex)then
+ -- (r & 0x3) | 0x8
+ index = tonumber(Hex2Dec(BMOr(BMAnd(Dec2Hex(r), Dec2Hex(3)), Dec2Hex(8))))
+ if(index < 1 or index > 36)then
+ print("WARNING Index-19:",index)
+ return UUID() -- should never happen - just try again if it does ;-)
+ end
+ else
+ index = r
+ end
+ uuid[i] = chars[index]
+ end
+ end
+ return table.concat(uuid)
+ end
+
+ -- RETURN NEW PUBNUB OBJECT
+ return self
+end

0 comments on commit d4e3931

Please sign in to comment.
Something went wrong with that request. Please try again.