...
This commit is contained in:
parent
4b1bb8d079
commit
3620fdae36
@ -124,7 +124,7 @@ public class LoginGUI : MonoBehaviour {
|
||||
|
||||
public void Login()
|
||||
{
|
||||
string host = "127.0.0.1";
|
||||
string host = "bee.local";
|
||||
int port = 3999;
|
||||
// if (pc != null)
|
||||
// {
|
||||
|
856
docs/cs_friend_proto.proto
Normal file
856
docs/cs_friend_proto.proto
Normal file
@ -0,0 +1,856 @@
|
||||
package cs;
|
||||
|
||||
//常量
|
||||
enum Constant_e
|
||||
{
|
||||
ProtoVersion = 2020061101; //协议版本
|
||||
}
|
||||
|
||||
//心跳(每60秒上报)
|
||||
message CMPing
|
||||
{
|
||||
}
|
||||
message SMPing
|
||||
{
|
||||
optional int32 param1 = 1;
|
||||
}
|
||||
|
||||
//string元组
|
||||
message MFStringTuple
|
||||
{
|
||||
repeated string values = 1; //values
|
||||
}
|
||||
|
||||
//int32 pair
|
||||
message MFPairInt32
|
||||
{
|
||||
optional int32 key = 1; //key
|
||||
optional int32 val = 2; //val
|
||||
}
|
||||
|
||||
//int64 pair
|
||||
message MFPairInt64
|
||||
{
|
||||
optional int64 key = 1; //key
|
||||
optional int64 val = 2; //val
|
||||
}
|
||||
|
||||
//分页信息
|
||||
message MFPaging
|
||||
{
|
||||
optional int32 curr_page = 1; //当前页(第一页是0)
|
||||
optional int32 page_size = 2; //每页记录数
|
||||
optional int32 _total_page = 3; //总页数(服务器填充该字段)
|
||||
optional int32 _total_count = 4; //总记录数(服务器填充该字段)
|
||||
}
|
||||
|
||||
//用户基础数据(可用于缓存,除下划线开头的字段会存储到db)
|
||||
message MFBaseUserData
|
||||
{
|
||||
optional string account_id = 1; //账号id
|
||||
optional string nickname = 2; //昵称
|
||||
optional string avatar_url = 3; //头像
|
||||
optional int32 sex = 4; //性别 1:男 2:女 0:未知
|
||||
optional int32 last_login_time = 5; //最后登录时间
|
||||
optional int64 guild_id = 6; //工会id(没有公会的话为0)
|
||||
optional int32 guild_job = 7; //公会职位 1:公会长 2:副公会长 3:精英成员 其他(0):普通会员
|
||||
optional int32 vip_lv = 8 [default = 0]; //性别
|
||||
optional int32 head = 9 [default = 0]; //头像框
|
||||
optional int32 contribute = 10 [default = 0]; //贡献度
|
||||
|
||||
optional int64 user_value1 = 50; //用户字段1
|
||||
optional int64 user_value2 = 51; //用户字段2
|
||||
optional int64 user_value3 = 52; //用户字段3
|
||||
optional int64 base_data_version = 100; //数据版本号
|
||||
|
||||
optional int32 _online = 101; //是否在线
|
||||
}
|
||||
|
||||
//临时用户自定义数据(不会存储每次上/下线时时都重置为0)
|
||||
message MFUserTempCustomData
|
||||
{
|
||||
optional int64 value1 = 1 [default = 0]; //自定义字段1
|
||||
optional int64 value2 = 2 [default = 0]; //自定义字段2
|
||||
optional int64 value3 = 3 [default = 0]; //自定义字段3
|
||||
}
|
||||
|
||||
//账号信息(自己)
|
||||
message MFAccountInfo
|
||||
{
|
||||
optional MFUserInfo user_info = 1; //用户数据
|
||||
optional string user_sign = 2; //用户签名用于接口确权
|
||||
}
|
||||
|
||||
//用户信息
|
||||
message MFUserInfo
|
||||
{
|
||||
optional MFBaseUserData base_data = 1; //基础数据
|
||||
optional MFUserTempCustomData temp_custom_data = 2; //临时用户自定义数据
|
||||
optional int32 is_sys_user = 3; //是否系统用户(主要在聊天时判断)
|
||||
}
|
||||
|
||||
//用户状态
|
||||
message MFUserStatus
|
||||
{
|
||||
optional string account_id = 1; //账号id
|
||||
optional int32 _online = 2; //是否在线
|
||||
optional MFUserTempCustomData temp_custom_data = 3; //临时用户自定义数据
|
||||
}
|
||||
|
||||
//好友申请
|
||||
message MFFriendApply
|
||||
{
|
||||
optional int64 idx = 1; //唯一索引id
|
||||
optional int64 applyid = 2; //applyid
|
||||
optional string target_id = 3; //target_id
|
||||
optional MFBaseUserData base_data = 4; //基础数据
|
||||
}
|
||||
|
||||
//公会申请
|
||||
message MFGuildApply
|
||||
{
|
||||
optional int64 idx = 1; //唯一索引id
|
||||
optional int64 applyid = 2; //applyid
|
||||
optional int64 guild_id = 3; //guild_id
|
||||
optional MFBaseUserData base_data = 4; //基础数据
|
||||
}
|
||||
|
||||
//公会基本信息
|
||||
message MFGuildBasic
|
||||
{
|
||||
optional int64 guild_id = 1; //公会id
|
||||
optional string guild_name = 2; //公会名
|
||||
optional int32 guild_lv = 3; //公会等级
|
||||
optional double guild_exp = 4; //公会经验
|
||||
optional int32 guild_badge = 5; //公会徽章
|
||||
optional int32 member_num = 6; //公会成员数
|
||||
optional string guild_declaration = 7; //公会宣言
|
||||
optional string owner_id = 8; //公会队长id
|
||||
optional string owner_name = 9; //公会队长名字
|
||||
optional string owner_avatar_url = 10; //公会队长头像
|
||||
optional int32 owner_sex = 23; //公会队长性别
|
||||
optional int32 owner_vip_lv = 12 [default = 0]; //vip等级
|
||||
optional int32 owner_head = 13 [default = 0]; //头像框
|
||||
optional int32 join_unlimited = 11; //不限制加入
|
||||
optional int32 join_cond1 = 20; //加入条件1
|
||||
optional int32 join_cond2 = 21; //加入条件2
|
||||
optional int32 applyed = 22; //是否已申请
|
||||
|
||||
optional int32 _gameid = 100; //gameid
|
||||
optional int32 _channel = 101; //channel
|
||||
optional int32 _createtime = 102; //createtime
|
||||
optional int32 _modifytime = 103; //modifytime
|
||||
optional int64 _name_ext1 = 104; //name_ext1
|
||||
optional int64 _name_ext2 = 105; //name_ext2
|
||||
optional int64 _guild_status = 106; //guild_status
|
||||
}
|
||||
|
||||
|
||||
//聊天消息
|
||||
message MFChatMsg
|
||||
{
|
||||
/*
|
||||
消息唯一id,递增序列,客户端可以用chat_channel + msg_uuid作为主键
|
||||
!!!不同的频道msg_uuid可能重复
|
||||
*/
|
||||
optional int64 msg_uuid = 1;
|
||||
optional MFUserInfo sender = 2; //发送者
|
||||
optional MFUserInfo receiver = 3; //接收者
|
||||
optional int32 chat_channel = 4; //聊天频道
|
||||
optional int32 msg_type = 5; //消息类型 0:文本消息(json) 1:自定义协议 (json) 2:纯文本(但是任会做屏蔽字替换)
|
||||
optional string msg_body = 6; //消息内容(json类型里的字段!开头的会做屏蔽替换)
|
||||
optional int32 send_time = 7; //消息发送时间
|
||||
}
|
||||
|
||||
//登录好友服
|
||||
message CMLoginCommonHead
|
||||
{
|
||||
optional int32 server_id = 1; //保留
|
||||
}
|
||||
message CMLoginOld
|
||||
{
|
||||
optional string account_id = 3; //账号id
|
||||
optional string session_id = 20; //sessionid
|
||||
optional string nickname = 4; //昵称
|
||||
optional string avatar_url = 5; //头像
|
||||
optional int32 sex = 6; //性别
|
||||
}
|
||||
message CMLogin
|
||||
{
|
||||
optional int32 server_id = 1; //保留(定死传1)
|
||||
optional string reserved2 = 2; //保留
|
||||
optional string account_id = 3; //账号id
|
||||
optional string session_id = 20; //sessionid
|
||||
optional string nickname = 4; //昵称
|
||||
optional int32 proto_version = 5; //协议版本号Constant_e.ProtoVersion
|
||||
optional int32 sex = 6; //性别
|
||||
optional string avatar_url = 7; //头像
|
||||
optional int32 vip_lv = 8; //性别
|
||||
optional int32 head = 9; //头像框
|
||||
}
|
||||
|
||||
//登录回复
|
||||
message SMLogin
|
||||
{
|
||||
optional int32 errcode = 1; //错误码
|
||||
optional string errmsg = 2; //错误信息
|
||||
optional MFAccountInfo account_info = 3; //账号信息
|
||||
}
|
||||
|
||||
//更新用户信息(增量更新,不需更新的字段不传即可)
|
||||
message CMUpdateUserInfo
|
||||
{
|
||||
optional string nickname = 2; //昵称
|
||||
optional string avatar_url = 3; //头像
|
||||
optional int32 sex = 4; //性别 1:男 2:女 0:未知
|
||||
optional int32 vip_lv = 8; //性别
|
||||
optional int32 head = 9; //头像框
|
||||
optional int32 contribute = 10; //贡献度
|
||||
|
||||
optional int64 user_value1 = 50; //用户字段1
|
||||
optional int64 user_value2 = 51; //用户字段2
|
||||
optional int64 user_value3 = 52; //用户字段3
|
||||
|
||||
optional int32 delay_time = 100; //延迟更新(单位毫秒)
|
||||
optional int32 delay_flag = 101; //延迟更新标志(只能为1-16),相同的flag定时器覆盖
|
||||
}
|
||||
|
||||
//屏蔽字检查
|
||||
message CMDirtyWordCheck
|
||||
{
|
||||
optional string text = 2; //待检查文本
|
||||
}
|
||||
//屏蔽字检查回复
|
||||
message SMDirtyWordCheck
|
||||
{
|
||||
optional int32 errcode = 1; //错误消息
|
||||
optional string errmsg = 2; //错误消息
|
||||
}
|
||||
|
||||
//获取自己的公会信息
|
||||
message CMGetUserGuild
|
||||
{
|
||||
optional string account_id = 1; //用户id,传空或不传获取自己
|
||||
}
|
||||
//获取自己
|
||||
message SMGetUserGuild
|
||||
{
|
||||
optional int32 errcode = 1; //1:公会不存在
|
||||
optional string errmsg = 2; //错误消息
|
||||
optional string account_id = 3; //用户id,传空或不传获取自己
|
||||
optional int64 guild_id = 4; //工会id(没有公会的话为0)
|
||||
optional int32 guild_job = 5; //公会职位 1:公会长 2:副公会长 3:精英成员 其他(0):普通会员
|
||||
}
|
||||
|
||||
//获取好友列表
|
||||
message CMFriendList
|
||||
{
|
||||
}
|
||||
//好友列表回复
|
||||
message SMFriendList
|
||||
{
|
||||
optional int32 errcode = 1; //错误消息
|
||||
optional string errmsg = 2; //错误消息
|
||||
repeated MFUserInfo friend_list = 3; //好友列表
|
||||
}
|
||||
|
||||
//好友申请
|
||||
message CMFriendApply
|
||||
{
|
||||
optional string friend_id = 1; //好友id
|
||||
optional string msg = 2; //消息
|
||||
}
|
||||
//好友申请回复
|
||||
message SMFriendApply
|
||||
{
|
||||
optional int32 errcode = 1; //1:已经是好友
|
||||
optional string errmsg = 2; //消息描述
|
||||
}
|
||||
|
||||
//获取好友申请列表
|
||||
message CMFriendApplyList
|
||||
{
|
||||
optional MFPaging paging = 1; //分页信息
|
||||
}
|
||||
//获取好友申请列表回复
|
||||
message SMFriendApplyList
|
||||
{
|
||||
optional int32 errcode = 1; //
|
||||
optional string errmsg = 2; //错误消息
|
||||
optional MFPaging paging = 3; //分页信息回传
|
||||
repeated MFFriendApply apply_list = 4; //申请加好友列表
|
||||
}
|
||||
|
||||
//同意申请
|
||||
message CMFriendAgree
|
||||
{
|
||||
optional MFFriendApply apply = 1; //申请信息
|
||||
}
|
||||
//同意申请回复
|
||||
message SMFriendAgree
|
||||
{
|
||||
optional int32 errcode = 1; //错误码
|
||||
optional string errmsg = 2; //错误消息
|
||||
}
|
||||
|
||||
//拒绝好友申请
|
||||
message CMFriendRefuse
|
||||
{
|
||||
optional MFFriendApply apply = 1; //申请信息
|
||||
}
|
||||
//拒绝好友申请回复
|
||||
message SMFriendRefuse
|
||||
{
|
||||
optional int32 errcode = 1; //错误码
|
||||
optional string errmsg = 2; //错误消息
|
||||
}
|
||||
|
||||
//删除好友
|
||||
message CMFriendDelete
|
||||
{
|
||||
optional string friend_id = 1; //好友id
|
||||
}
|
||||
//删除好友回复
|
||||
message SMFriendDelete
|
||||
{
|
||||
optional int32 errcode = 1; //错误码
|
||||
optional string errmsg = 2; //错误消息
|
||||
optional string friend_id = 3; //好友id
|
||||
}
|
||||
|
||||
//获取黑名单
|
||||
message CMFriendBlackList
|
||||
{
|
||||
}
|
||||
//获取黑名单回复
|
||||
message SMFriendBlackList
|
||||
{
|
||||
repeated MFUserInfo black_list = 1; //黑名单
|
||||
}
|
||||
|
||||
//添加黑名单
|
||||
message CMFriendAddBlack
|
||||
{
|
||||
optional MFUserInfo user_info = 1; //好友信息
|
||||
}
|
||||
//添加黑名单回复
|
||||
message SMFriendAddBlack
|
||||
{
|
||||
optional int32 errcode = 1; //
|
||||
optional string errmsg = 2; //错误消息
|
||||
}
|
||||
|
||||
//删除黑名单
|
||||
message CMFriendDeleteBlack
|
||||
{
|
||||
optional string account_id = 1; //好友id
|
||||
}
|
||||
//删除黑名单回复
|
||||
message SMFriendDeleteBlack
|
||||
{
|
||||
optional int32 errcode = 1; //
|
||||
optional string errmsg = 2; //错误消息
|
||||
}
|
||||
|
||||
//获取好友/黑名单id列表
|
||||
message CMFriendIdList
|
||||
{
|
||||
}
|
||||
//获取好友/黑名单id列表回复
|
||||
message SMFriendIdList
|
||||
{
|
||||
optional int32 errcode = 1; //
|
||||
optional string errmsg = 2; //错误消息
|
||||
repeated string friends = 3; //好友
|
||||
repeated string blacklist = 4; //黑名单
|
||||
}
|
||||
|
||||
//建群
|
||||
message CMTeamCreate
|
||||
{
|
||||
optional string team_name = 1; //群名称
|
||||
}
|
||||
//建群返回
|
||||
message SMTeamCreate
|
||||
{
|
||||
optional int32 errcode = 1; //1:群已存在 2: 你已经有群
|
||||
optional string errmsg = 2; //错误消息
|
||||
}
|
||||
|
||||
//加群
|
||||
message CMTeamJoin
|
||||
{
|
||||
optional int64 team_id = 1; //群id
|
||||
}
|
||||
//加群返回
|
||||
message SMTeamJoin
|
||||
{
|
||||
optional int32 errcode = 1; //1:群id不存在 2:群已满
|
||||
optional string errmsg = 2; //错误消息
|
||||
}
|
||||
|
||||
//同意加群
|
||||
message CMTeamAgree
|
||||
{
|
||||
}
|
||||
message SMTeamAgree
|
||||
{
|
||||
optional int32 errcode = 1;
|
||||
optional string errmsg = 2;
|
||||
}
|
||||
|
||||
//踢人
|
||||
message CMTeamKick
|
||||
{
|
||||
optional string account_id = 1;
|
||||
}
|
||||
|
||||
//踢人回复
|
||||
message SMTeamKick
|
||||
{
|
||||
optional int32 errcode = 1; //1:群id错误
|
||||
optional string errmsg = 2; //错误消息
|
||||
}
|
||||
|
||||
//退群
|
||||
message CMTeamQuit
|
||||
{
|
||||
}
|
||||
message SMTeamQuit
|
||||
{
|
||||
optional int32 errcode = 1; //错误码
|
||||
optional string errmsg = 2; //错误消息
|
||||
}
|
||||
|
||||
//解散群
|
||||
message CMTeamDismiss
|
||||
{
|
||||
}
|
||||
message SMTeamDismiss
|
||||
{
|
||||
optional int32 errcode = 1; //错误码
|
||||
optional string errmsg = 2; //错误信息
|
||||
}
|
||||
|
||||
//群改名
|
||||
message CMTeamRename
|
||||
{
|
||||
optional string new_team_name = 1; //新群名
|
||||
}
|
||||
message SMTeamRename
|
||||
{
|
||||
optional int32 errcode = 1; //错误码
|
||||
optional string errmsg = 2; //错误信息
|
||||
}
|
||||
|
||||
//获取公会信息
|
||||
message CMGuildInfo
|
||||
{
|
||||
optional int64 guild_id = 1; //公会id
|
||||
}
|
||||
//获取公会信息返回
|
||||
message SMGuildInfo
|
||||
{
|
||||
optional int32 errcode = 1; //1:公会不存在
|
||||
optional string errmsg = 2; //错误消息
|
||||
optional MFGuildBasic info = 3; //公会信息
|
||||
}
|
||||
|
||||
//建公会
|
||||
message CMGuildCreate
|
||||
{
|
||||
optional string guild_name = 1; //公会名字
|
||||
optional int32 guild_badge = 2; //公会徽标
|
||||
optional string guild_declaration = 3; //公会徽标
|
||||
optional int32 join_unlimited = 4; //不限制加入
|
||||
optional int32 join_cond1 = 5; //加入条件1
|
||||
optional int32 join_cond2 = 6; //加入条件2
|
||||
}
|
||||
//建公会返回
|
||||
message SMGuildCreate
|
||||
{
|
||||
optional int32 errcode = 1; //1:公会已存在 2: 你已经有公会
|
||||
optional string errmsg = 2; //错误消息
|
||||
optional int64 guild_id = 3; //公会id
|
||||
}
|
||||
|
||||
//加公会
|
||||
message CMGuildJoin
|
||||
{
|
||||
optional int64 guild_id = 1; //公会id
|
||||
}
|
||||
//加群返回
|
||||
message SMGuildJoin
|
||||
{
|
||||
optional int32 errcode = 1; //1:公会id不存在 2:公会已满
|
||||
optional string errmsg = 2; //错误消息
|
||||
}
|
||||
|
||||
//同意加公会
|
||||
message CMGuildAgree
|
||||
{
|
||||
optional MFGuildApply apply = 1; //申请信息
|
||||
optional int32 batchid = 2; //批次号(批量的时候id相同建议用时间戳)
|
||||
}
|
||||
message SMGuildAgree
|
||||
{
|
||||
optional int32 errcode = 1;
|
||||
optional string errmsg = 2;
|
||||
}
|
||||
|
||||
//拒绝加公会申请
|
||||
message CMGuildRefuse
|
||||
{
|
||||
optional MFGuildApply apply = 1; //申请信息
|
||||
optional int32 batchid = 2; //批次号(批量的时候id相同建议用时间戳)
|
||||
}
|
||||
message SMGuildRefuse
|
||||
{
|
||||
optional int32 errcode = 1;
|
||||
optional string errmsg = 2;
|
||||
}
|
||||
|
||||
//踢人
|
||||
message CMGuildKick
|
||||
{
|
||||
optional string account_id = 1;
|
||||
}
|
||||
|
||||
//踢人回复
|
||||
message SMGuildKick
|
||||
{
|
||||
optional int32 errcode = 1; //1:群id错误
|
||||
optional string errmsg = 2; //错误消息
|
||||
}
|
||||
|
||||
//退公会
|
||||
message CMGuildQuit
|
||||
{
|
||||
}
|
||||
message SMGuildQuit
|
||||
{
|
||||
optional int32 errcode = 1; //错误码
|
||||
optional string errmsg = 2; //错误消息
|
||||
}
|
||||
|
||||
//解散公会
|
||||
message CMGuildDismiss
|
||||
{
|
||||
}
|
||||
message SMGuildDismiss
|
||||
{
|
||||
optional int32 errcode = 1; //错误码
|
||||
optional string errmsg = 2; //错误信息
|
||||
}
|
||||
|
||||
//修改公会信息(增量更新不需要修改的字段不传)
|
||||
message CMGuildChange
|
||||
{
|
||||
optional string guild_name = 1; //公会名字
|
||||
optional int32 guild_badge = 2; //公会徽标
|
||||
optional string guild_declaration = 3; //公会徽标
|
||||
optional int32 join_unlimited = 4; //不限制加入
|
||||
optional int32 join_cond1 = 5; //加入条件1
|
||||
optional int32 join_cond2 = 6; //加入条件2
|
||||
}
|
||||
message SMGuildChange
|
||||
{
|
||||
optional int32 errcode = 1; //错误码
|
||||
optional string errmsg = 2; //错误信息
|
||||
optional MFGuildBasic info = 3; //公会信息
|
||||
}
|
||||
|
||||
//查询公会
|
||||
message CMGuildSearch
|
||||
{
|
||||
optional MFPaging paging = 1; //分页信息
|
||||
optional string guild_name = 2; //公会名字
|
||||
}
|
||||
message SMGuildSearch
|
||||
{
|
||||
optional int32 errcode = 1; //错误码
|
||||
optional string errmsg = 2; //错误信息
|
||||
optional MFPaging paging = 3; //分页信息
|
||||
repeated MFGuildBasic guild_list = 4; //公会列表
|
||||
}
|
||||
|
||||
//公会排行榜
|
||||
message CMGuildRank
|
||||
{
|
||||
optional MFPaging paging = 1; //分页信息
|
||||
}
|
||||
message SMGuildRank
|
||||
{
|
||||
optional int32 errcode = 1; //错误码
|
||||
optional string errmsg = 2; //错误信息
|
||||
optional MFPaging paging = 3; //分页信息
|
||||
repeated MFGuildBasic guild_list = 4; //公会列表
|
||||
}
|
||||
|
||||
//公会成员
|
||||
message CMGuildMemberList
|
||||
{
|
||||
optional MFPaging paging = 1; //分页信息
|
||||
optional string member_name = 2; //成员名字
|
||||
}
|
||||
message SMGuildMemberList
|
||||
{
|
||||
optional int32 errcode = 1; //错误码
|
||||
optional string errmsg = 2; //错误信息
|
||||
optional MFPaging paging = 3; //分页信息
|
||||
repeated MFUserInfo member_list = 4; //公会成员列表
|
||||
optional int32 guild_lv = 5; //公会等级
|
||||
}
|
||||
|
||||
//获取公会申请列表
|
||||
message CMGuildApplyList
|
||||
{
|
||||
optional MFPaging paging = 1; //分页信息
|
||||
}
|
||||
//获取公会申请列表回复
|
||||
message SMGuildApplyList
|
||||
{
|
||||
optional int32 errcode = 1; //
|
||||
optional string errmsg = 2; //错误消息
|
||||
optional MFPaging paging = 3; //分页信息回传
|
||||
repeated MFGuildApply apply_list = 4; //申请加公会友列表
|
||||
optional int32 guild_lv = 5; //公会等级
|
||||
}
|
||||
|
||||
//公会动态(日志)
|
||||
message CMGuildLog
|
||||
{
|
||||
optional MFPaging paging = 1; //分页信息
|
||||
}
|
||||
message SMGuildLog
|
||||
{
|
||||
optional int32 errcode = 1; //错误码
|
||||
optional string errmsg = 2; //错误信息
|
||||
optional MFPaging paging = 3; //分页信息
|
||||
/*
|
||||
values[0]: account_id
|
||||
values[1]: 角色名
|
||||
values[2]: 职位 1:队长 2:副队长 3:精英会员 其他(0):普通会员
|
||||
values[3]: 行为时间(unix时间戳)
|
||||
values[4]: 行为
|
||||
*/
|
||||
repeated MFStringTuple logs = 4;
|
||||
}
|
||||
|
||||
//设置公会成员职位
|
||||
message CMGuildMemberSetJob
|
||||
{
|
||||
optional string member_id = 1; //成员id
|
||||
optional int32 job = 2; //职位
|
||||
}
|
||||
message SMGuildMemberSetJob
|
||||
{
|
||||
optional int32 errcode = 1; //错误码
|
||||
optional string errmsg = 2; //错误信息
|
||||
}
|
||||
|
||||
//同意邀请
|
||||
message CMGuildAgreeInvite
|
||||
{
|
||||
optional int64 guild_id = 1; //公会id
|
||||
optional string user_sign = 2; //邀请方签名
|
||||
}
|
||||
message SMGuildAgreeInvite
|
||||
{
|
||||
optional int32 errcode = 1; //错误码
|
||||
optional string errmsg = 2; //错误信息
|
||||
}
|
||||
|
||||
//新增公会经验
|
||||
message CMGuildGainExp
|
||||
{
|
||||
optional int32 exp = 1; //检验值
|
||||
}
|
||||
message SMGuildGainExp
|
||||
{
|
||||
optional int32 errcode = 1; //错误码
|
||||
optional string errmsg = 2; //错误信息
|
||||
}
|
||||
|
||||
//查询公会成员信息
|
||||
message CMGuildSearchMember
|
||||
{
|
||||
optional string target_id = 1; //账号id
|
||||
}
|
||||
message SMGuildSearchMember
|
||||
{
|
||||
optional int32 errcode = 1; //错误码
|
||||
optional string errmsg = 2; //错误信息
|
||||
optional MFGuildBasic guild_basic = 3; //公会基本信息
|
||||
optional MFUserInfo user_info = 4; //用户信息
|
||||
}
|
||||
|
||||
//发送聊天消息
|
||||
message CMSendChatMsg
|
||||
{
|
||||
optional int32 chat_channel = 1; //聊天频道 1: 世界 2:好友 3:战队 4:小队(这时target表示队伍Id) 5:大喇叭 6:跑马灯(只能收不能发)
|
||||
optional string target = 2; //目标
|
||||
optional int32 msg_type = 3; ////消息类型 0:文本消息(json) 1:自定义协议 (json) 2:纯文本(但是任会做屏蔽字替换)
|
||||
optional string msg_body = 4; //消息内容
|
||||
repeated string members = 5; //小队成员列表(包含自己)
|
||||
}
|
||||
|
||||
//读取聊天消息列表并且开启聊天通知
|
||||
message CMReadMsgAndOpenChatNotify
|
||||
{
|
||||
optional int32 curr_channel = 1; //当前频道
|
||||
repeated MFPairInt64 last_ids = 2; //所有频道 key:聊天频道 val:该频道最后一次收到的消息id
|
||||
}
|
||||
|
||||
//设置当前私聊目标
|
||||
message CMSetCurrPrivateChatTarget
|
||||
{
|
||||
optional string private_target = 1; //私聊对象id, 只有当前聊频道是私聊时字段才有意义
|
||||
optional int64 last_id = 2; //最后收到想消息id
|
||||
}
|
||||
|
||||
//关闭聊天通知
|
||||
message CMCloseChatNotify
|
||||
{
|
||||
}
|
||||
|
||||
//发送自定义消息
|
||||
message CMSendCustomMsg
|
||||
{
|
||||
repeated string target_list = 1; //目标列表
|
||||
optional string msg = 2; //消息内容
|
||||
optional int64 param1 = 3; //透传参数1
|
||||
optional int64 param2 = 4; //透传参数2
|
||||
optional int64 param3 = 5; //透传参数3
|
||||
}
|
||||
|
||||
//更新临时自定义数据
|
||||
message CMUpdateTempCustomData
|
||||
{
|
||||
/*
|
||||
更新方式
|
||||
0: 覆盖
|
||||
1: 用新数据和服务器数据做或运算
|
||||
2: 用新数据和服务器数据做与运算
|
||||
|
||||
!!!注意
|
||||
MFUserRaltimeData走的是增量更新如果不需要处理的字段不传就行
|
||||
服务器对未传的自动不做任何处理
|
||||
*/
|
||||
optional int32 update_type = 1; //更新方式
|
||||
optional MFUserTempCustomData temp_custom_data = 2; //临时自定义数据
|
||||
|
||||
optional int32 delay_time = 100; //延迟更新(单位毫秒)
|
||||
optional int32 delay_flag = 101; //延迟更新标志(只能为1-16),相同的flag定时器覆盖
|
||||
}
|
||||
|
||||
//查询用户状态
|
||||
message CMQueryUserStatus
|
||||
{
|
||||
repeated string user_list = 1; //用户列表
|
||||
}
|
||||
//查询用户状态返回
|
||||
message SMQueryUserStatus
|
||||
{
|
||||
repeated MFUserStatus status_list = 1; //用户状态列表
|
||||
}
|
||||
|
||||
//获取推荐好友
|
||||
message CMRecommandFriend
|
||||
{
|
||||
}
|
||||
//获取推荐好友返回
|
||||
message SMRecommandFriend
|
||||
{
|
||||
repeated MFUserInfo friend_list = 1; //好友列表
|
||||
}
|
||||
|
||||
//用户上/下线通知
|
||||
message SMUserStatusNotify
|
||||
{
|
||||
repeated string online_users = 1; //上线用户
|
||||
repeated string offline_users = 2; //下线用户
|
||||
}
|
||||
|
||||
//聊天消息通知
|
||||
message SMChatMsgNotify
|
||||
{
|
||||
repeated MFChatMsg msg_list = 1; //消息列表,客户端需要根据chat_channel和msg_uuid更新本地的last_ids
|
||||
}
|
||||
|
||||
//发送自定义消息
|
||||
message SMCustomMsgNotify
|
||||
{
|
||||
optional string sender = 1; //发送者
|
||||
optional string msg = 2; //消息内容
|
||||
optional int64 param1 = 3; //透传参数1
|
||||
optional int64 param2 = 4; //透传参数2
|
||||
optional int64 param3 = 5; //透传参数3
|
||||
}
|
||||
|
||||
//更新用户信息
|
||||
message SMUserInfoUpdate
|
||||
{
|
||||
repeated MFUserInfo user_infos = 1; //用户信息列表
|
||||
}
|
||||
|
||||
//删除好友通知a
|
||||
message SMDeleteFriendNotify
|
||||
{
|
||||
repeated string user_list = 1; //用户列表
|
||||
}
|
||||
|
||||
//新增黑名单
|
||||
message SMAddBlackListNotify
|
||||
{
|
||||
repeated MFUserInfo user_infos = 1; //用户信息列表
|
||||
}
|
||||
|
||||
//删除黑名单通知
|
||||
message SMDeleteBlackListNotify
|
||||
{
|
||||
repeated string user_list = 1; //用户列表
|
||||
}
|
||||
|
||||
//更新用户临时自定义信息
|
||||
message SMUserTempCustomDataUpdate
|
||||
{
|
||||
optional string account_id = 1; //账号id
|
||||
optional MFUserTempCustomData temp_custom_data = 2; //用户临时自定义数据
|
||||
}
|
||||
|
||||
//更新账号信息通知
|
||||
message SMUpdateAccountInfo
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//更新红点信息
|
||||
message SMUpdateRedPointNotify
|
||||
{
|
||||
optional int32 red_point_flags = 1; //红点信息 1<<0:好友申请 1<<1:公会申请 1<<2:聊天红点
|
||||
}
|
||||
|
||||
//更新聊天红点信息
|
||||
message SMUpdateChatRedPointNotify
|
||||
{
|
||||
repeated int32 has_unread_msg_channels = 1; //含有未读消息的渠道id列表,不在列表里的渠道默认不含有
|
||||
}
|
||||
|
||||
//更新私聊红点信息
|
||||
message SMUpdatePrivateChatRedPointNotify
|
||||
{
|
||||
repeated string has_unread_msg_accounts = 1; //有未读消息的账号列表,不在列表里的好友more不含有
|
||||
}
|
||||
|
||||
//更新频道最后一次收到的消息id
|
||||
message SMUpdateChatChannelLastId
|
||||
{
|
||||
repeated MFPairInt64 last_ids = 1; //所有频道 key:聊天频道 val:该频道最后一次收到的消息id
|
||||
}
|
||||
|
||||
//显示飘字
|
||||
message SMShowErrorMsg
|
||||
{
|
||||
optional string msg = 1; //飘字内容
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
{
|
||||
"development":{
|
||||
"connector": [
|
||||
{"id": "connector-server-0", "host": "127.0.0.1", "port": 3150, "clientHost": "0.0.0.0", "proxyHost": "localhost", "clientPort": 3010, "frontend": true},
|
||||
{"id": "connector-server-1", "host": "127.0.0.1", "port": 3151, "clientHost": "0.0.0.0", "proxyHost": "localhost", "clientPort": 3011, "frontend": true}
|
||||
{"id": "connector-server-0", "host": "127.0.0.1", "port": 3150, "clientHost": "0.0.0.0", "proxyHost": "192.168.100.173", "clientPort": 4010, "frontend": true},
|
||||
{"id": "connector-server-1", "host": "127.0.0.1", "port": 3151, "clientHost": "0.0.0.0", "proxyHost": "192.168.100.173", "clientPort": 4011, "frontend": true}
|
||||
],
|
||||
"guild": [
|
||||
{"id": "guild-server-0", "host": "127.0.0.1", "port": 3200},
|
||||
|
17
proxy/.vscode/launch.json
vendored
Normal file
17
proxy/.vscode/launch.json
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Launch Program",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"program": "${workspaceFolder}/app.js"
|
||||
}
|
||||
]
|
||||
}
|
108
proxy/app.js
Normal file
108
proxy/app.js
Normal file
@ -0,0 +1,108 @@
|
||||
const net = require("net");
|
||||
const { PomeloClient } = require("./lib/boot");
|
||||
|
||||
|
||||
var listenPort = 4000;
|
||||
var listenHost = "127.0.0.1";
|
||||
|
||||
|
||||
const proxyList = require("./config/proxy.json");
|
||||
|
||||
console.log(proxyList);
|
||||
|
||||
proxyList.forEach((config) => {
|
||||
proxy(config);
|
||||
});
|
||||
|
||||
|
||||
function proxy(config) {
|
||||
console.log(config);
|
||||
|
||||
const host = config.host;
|
||||
const port = config.port;
|
||||
const srcHost = config.srcHost;
|
||||
const srcPort = config.srcPort;
|
||||
|
||||
const server = net.createServer((socket) => {
|
||||
console.log("listening");
|
||||
|
||||
const pomelo = new PomeloClient();
|
||||
const connectBuffer = [];
|
||||
let isReady = false;
|
||||
|
||||
pomelo.init({ host: srcHost, port: srcPort, log: true }, () => {
|
||||
isReady = true;
|
||||
connectBuffer.forEach((data) => {
|
||||
onData(data);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
socket.on("connect", () => {
|
||||
console.log("connect");
|
||||
});
|
||||
|
||||
socket.on("error", (error) => {
|
||||
console.log(error);
|
||||
});
|
||||
|
||||
socket.on("close", () => {
|
||||
console.log("close");
|
||||
pomelo.disconnect();
|
||||
});
|
||||
|
||||
socket.on("drop", () => {
|
||||
console.log("drop");
|
||||
});
|
||||
|
||||
socket.on("data", (data) => {
|
||||
if (isReady) {
|
||||
onData(data);
|
||||
} else {
|
||||
connectBuffer.push(data);
|
||||
}
|
||||
});
|
||||
|
||||
function onData(data) {
|
||||
console.log(data.toString());
|
||||
|
||||
const account = "6516_2006_0xef59f6cc4d190a0ae576c46d4583e92b61174340";
|
||||
pomelo.request("gate.gateHandler.queryEntry", { uid: account }, (data) => {
|
||||
socket.write(JSON.stringify(data));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
server.listen(port, host);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// const testAccounts = [
|
||||
// "6516_2006_0xef59f6cc4d190a0ae576c46d4583e92b61174340",
|
||||
// "6513_2006_FcZnmeGSoxGFQy1Zr6Lfr2o7dRoGcEYE",
|
||||
// "6513_2006_DAmSOj6LKh1jd45DlydwUm7g8iW4KjOv",
|
||||
// ];
|
||||
|
||||
// testAccounts.forEach((account) => {
|
||||
// const pomelo = new PomeloClient();
|
||||
|
||||
// pomelo.init(
|
||||
// {
|
||||
// host: "192.168.100.173",
|
||||
// port: 3999,
|
||||
// log: true,
|
||||
// },
|
||||
// () => {
|
||||
// pomelo.request(
|
||||
// "gate.gateHandler.queryEntry",
|
||||
// { uid: account },
|
||||
// (data) => {
|
||||
// console.log(data);
|
||||
// }
|
||||
// );
|
||||
// }
|
||||
// );
|
||||
// });
|
||||
|
||||
|
33
proxy/client.js
Normal file
33
proxy/client.js
Normal file
@ -0,0 +1,33 @@
|
||||
const net = require("net");
|
||||
|
||||
const port = 4999;
|
||||
const host = "127.0.0.1";
|
||||
|
||||
var client = new net.Socket();
|
||||
|
||||
client.connect(port, host, function () {
|
||||
console.log("Connected");
|
||||
client.write("queryEntry");
|
||||
});
|
||||
|
||||
client.on("data", function (data) {
|
||||
data = JSON.parse(data);
|
||||
console.log("Received: " + data);
|
||||
client.destroy(); // kill client after server's response
|
||||
|
||||
const game = new net.Socket();
|
||||
console.log(data.port, data.host);
|
||||
game.connect(data.port, data.host, function () {
|
||||
console.log("Connected");
|
||||
game.write("entry");
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
client.on("error", function (error) {
|
||||
console.log("Error: " + error);
|
||||
});
|
||||
|
||||
client.on("close", function () {
|
||||
console.log("Connection closed");
|
||||
});
|
5
proxy/config/proxy.json
Normal file
5
proxy/config/proxy.json
Normal file
@ -0,0 +1,5 @@
|
||||
[
|
||||
{ "host": "127.0.0.1", "port": 4999, "srcHost":"192.168.100.173", "srcPort": 3999 },
|
||||
{ "host": "127.0.0.1", "port": 4010, "srcHost":"192.168.100.173", "srcPort": 3010 },
|
||||
{ "host": "127.0.0.1", "port": 4011, "srcHost":"192.168.100.173", "srcPort": 3011 }
|
||||
]
|
6
proxy/lib/boot.js
Normal file
6
proxy/lib/boot.js
Normal file
@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
EventEmitter: require('./deps/emitter'),
|
||||
Protocol: require('./deps/pomelo-protocol'),
|
||||
protobuf: require('./deps/pomelo-protobuf'),
|
||||
PomeloClient: require('./deps/pomelo-jsclient'),
|
||||
}
|
157
proxy/lib/deps/emitter.js
Normal file
157
proxy/lib/deps/emitter.js
Normal file
@ -0,0 +1,157 @@
|
||||
var index = require('./indexof');
|
||||
|
||||
/**
|
||||
* Expose `Emitter`.
|
||||
*/
|
||||
|
||||
module.exports = Emitter;
|
||||
|
||||
/**
|
||||
* Initialize a new `Emitter`.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function Emitter(obj) {
|
||||
if (obj) return mixin(obj);
|
||||
};
|
||||
|
||||
/**
|
||||
* Mixin the emitter properties.
|
||||
*
|
||||
* @param {Object} obj
|
||||
* @return {Object}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function mixin(obj) {
|
||||
for (var key in Emitter.prototype) {
|
||||
obj[key] = Emitter.prototype[key];
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen on the given `event` with `fn`.
|
||||
*
|
||||
* @param {String} event
|
||||
* @param {Function} fn
|
||||
* @return {Emitter}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Emitter.prototype.on = function(event, fn){
|
||||
this._callbacks = this._callbacks || {};
|
||||
(this._callbacks[event] = this._callbacks[event] || [])
|
||||
.push(fn);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds an `event` listener that will be invoked a single
|
||||
* time then automatically removed.
|
||||
*
|
||||
* @param {String} event
|
||||
* @param {Function} fn
|
||||
* @return {Emitter}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Emitter.prototype.once = function(event, fn){
|
||||
var self = this;
|
||||
this._callbacks = this._callbacks || {};
|
||||
|
||||
function on() {
|
||||
self.off(event, on);
|
||||
fn.apply(this, arguments);
|
||||
}
|
||||
|
||||
fn._off = on;
|
||||
this.on(event, on);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove the given callback for `event` or all
|
||||
* registered callbacks.
|
||||
*
|
||||
* @param {String} event
|
||||
* @param {Function} fn
|
||||
* @return {Emitter}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Emitter.prototype.off =
|
||||
Emitter.prototype.removeListener =
|
||||
Emitter.prototype.removeAllListeners = function(event, fn){
|
||||
this._callbacks = this._callbacks || {};
|
||||
|
||||
// all
|
||||
if (0 == arguments.length) {
|
||||
this._callbacks = {};
|
||||
return this;
|
||||
}
|
||||
|
||||
// specific event
|
||||
var callbacks = this._callbacks[event];
|
||||
if (!callbacks) return this;
|
||||
|
||||
// remove all handlers
|
||||
if (1 == arguments.length) {
|
||||
delete this._callbacks[event];
|
||||
return this;
|
||||
}
|
||||
|
||||
// remove specific handler
|
||||
var i = index(callbacks, fn._off || fn);
|
||||
if (~i) callbacks.splice(i, 1);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Emit `event` with the given args.
|
||||
*
|
||||
* @param {String} event
|
||||
* @param {Mixed} ...
|
||||
* @return {Emitter}
|
||||
*/
|
||||
|
||||
Emitter.prototype.emit = function(event){
|
||||
this._callbacks = this._callbacks || {};
|
||||
var args = [].slice.call(arguments, 1)
|
||||
, callbacks = this._callbacks[event];
|
||||
|
||||
if (callbacks) {
|
||||
callbacks = callbacks.slice(0);
|
||||
for (var i = 0, len = callbacks.length; i < len; ++i) {
|
||||
callbacks[i].apply(this, args);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return array of callbacks for `event`.
|
||||
*
|
||||
* @param {String} event
|
||||
* @return {Array}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Emitter.prototype.listeners = function(event){
|
||||
this._callbacks = this._callbacks || {};
|
||||
return this._callbacks[event] || [];
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if this emitter has `event` handlers.
|
||||
*
|
||||
* @param {String} event
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
Emitter.prototype.hasListeners = function(event){
|
||||
return !! this.listeners(event).length;
|
||||
};
|
9
proxy/lib/deps/indexof.js
Normal file
9
proxy/lib/deps/indexof.js
Normal file
@ -0,0 +1,9 @@
|
||||
var indexOf = [].indexOf;
|
||||
|
||||
module.exports = function(arr, obj){
|
||||
if (indexOf) return arr.indexOf(obj);
|
||||
for (var i = 0; i < arr.length; ++i) {
|
||||
if (arr[i] === obj) return i;
|
||||
}
|
||||
return -1;
|
||||
};
|
337
proxy/lib/deps/pomelo-jsclient.js
Normal file
337
proxy/lib/deps/pomelo-jsclient.js
Normal file
@ -0,0 +1,337 @@
|
||||
const net = require("net");
|
||||
|
||||
var JS_WS_CLIENT_TYPE = "js-websocket";
|
||||
var JS_WS_CLIENT_VERSION = "0.0.1";
|
||||
|
||||
var Protocol = require("./pomelo-protocol");
|
||||
var Package = Protocol.Package;
|
||||
var Message = Protocol.Message;
|
||||
var EventEmitter = require("./emitter");
|
||||
const protobuf = require("./pomelo-protobuf");
|
||||
|
||||
var RES_OK = 200;
|
||||
var RES_FAIL = 500;
|
||||
var RES_OLD_CLIENT = 501;
|
||||
|
||||
class PomeloClient extends EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
this.socket = null;
|
||||
this.reqId = 0;
|
||||
this.callbacks = {};
|
||||
this.handlers = {};
|
||||
//Map from request id to route
|
||||
this.routeMap = {};
|
||||
|
||||
this.heartbeatInterval = 0;
|
||||
this.heartbeatTimeout = 0;
|
||||
this.nextHeartbeatTimeout = 0;
|
||||
this.gapThreshold = 100; // heartbeat gap threashold
|
||||
this.heartbeatId = null;
|
||||
this.heartbeatTimeoutId = null;
|
||||
|
||||
this.handshakeCallback = null;
|
||||
|
||||
this.handshakeBuffer = {
|
||||
sys: {
|
||||
type: JS_WS_CLIENT_TYPE,
|
||||
version: JS_WS_CLIENT_VERSION,
|
||||
},
|
||||
user: {},
|
||||
};
|
||||
|
||||
this.initCallback = null;
|
||||
|
||||
this.handlers[Package.TYPE_HANDSHAKE] = this.handshake.bind(this);
|
||||
this.handlers[Package.TYPE_HEARTBEAT] = this.heartbeat.bind(this);
|
||||
this.handlers[Package.TYPE_DATA] = this.onData.bind(this);
|
||||
this.handlers[Package.TYPE_KICK] = this.onKick.bind(this);
|
||||
}
|
||||
|
||||
init(params, cb) {
|
||||
this.initCallback = cb;
|
||||
var host = params.host;
|
||||
var port = params.port;
|
||||
|
||||
this.handshakeBuffer.user = params.user;
|
||||
this.handshakeCallback = params.handshakeCallback;
|
||||
this.initWebSocket(host, port, cb);
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
if (this.socket) {
|
||||
if (this.socket.disconnect) this.socket.disconnect();
|
||||
if (this.socket.close) this.socket.close();
|
||||
console.log("disconnect");
|
||||
this.socket = null;
|
||||
}
|
||||
|
||||
if (this.heartbeatId) {
|
||||
clearTimeout(this.heartbeatId);
|
||||
this.heartbeatId = null;
|
||||
}
|
||||
if (this.heartbeatTimeoutId) {
|
||||
clearTimeout(this.heartbeatTimeoutId);
|
||||
this.heartbeatTimeoutId = null;
|
||||
}
|
||||
}
|
||||
|
||||
request(route, msg, cb) {
|
||||
if (arguments.length === 2 && typeof msg === "function") {
|
||||
cb = msg;
|
||||
msg = {};
|
||||
} else {
|
||||
msg = msg || {};
|
||||
}
|
||||
route = route || msg.route;
|
||||
if (!route) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.reqId++;
|
||||
this.sendMessage(this.reqId, route, msg);
|
||||
|
||||
this.callbacks[this.reqId] = cb;
|
||||
this.routeMap[this.reqId] = route;
|
||||
}
|
||||
|
||||
notify(route, msg) {
|
||||
msg = msg || {};
|
||||
this.sendMessage(0, route, msg);
|
||||
}
|
||||
|
||||
sendMessage(reqId, route, msg) {
|
||||
var type = reqId ? Message.TYPE_REQUEST : Message.TYPE_NOTIFY;
|
||||
|
||||
//compress message by protobuf
|
||||
var protos = !!this.data.protos ? this.data.protos.client : {};
|
||||
if (!!protos[route]) {
|
||||
msg = protobuf.encode(route, msg);
|
||||
} else {
|
||||
msg = Protocol.strencode(JSON.stringify(msg));
|
||||
}
|
||||
|
||||
var compressRoute = 0;
|
||||
if (this.dict && this.dict[route]) {
|
||||
route = this.dict[route];
|
||||
compressRoute = 1;
|
||||
}
|
||||
|
||||
msg = Message.encode(reqId, type, compressRoute, route, msg);
|
||||
var packet = Package.encode(Package.TYPE_DATA, msg);
|
||||
this.send(packet);
|
||||
}
|
||||
|
||||
initWebSocket(host, port, cb) {
|
||||
console.log("connect to " + host + ":" + port);
|
||||
|
||||
this.socket = net.connect(port, host, (event) => {
|
||||
var obj = Package.encode(
|
||||
Package.TYPE_HANDSHAKE,
|
||||
Protocol.strencode(JSON.stringify(this.handshakeBuffer))
|
||||
);
|
||||
this.send(obj);
|
||||
});
|
||||
this.socket.on("data", (event) => {
|
||||
this.processPackage(Package.decode(event), cb);
|
||||
// new package arrived, update the heartbeat timeout
|
||||
if (this.heartbeatTimeout) {
|
||||
this.nextHeartbeatTimeout = Date.now() + this.heartbeatTimeout;
|
||||
}
|
||||
});
|
||||
this.socket.on("error", (event) => {
|
||||
this.emit("io-error", event);
|
||||
console.error("socket error: ", event);
|
||||
});
|
||||
this.socket.on("close", (event) => {
|
||||
this.emit("close", event);
|
||||
console.error("socket close: ", event);
|
||||
});
|
||||
}
|
||||
|
||||
send(packet) {
|
||||
this.socket.write(packet);
|
||||
}
|
||||
|
||||
processPackage(msg) {
|
||||
this.handlers[msg.type](msg.body);
|
||||
}
|
||||
|
||||
heartbeat(data) {
|
||||
if (!this.heartbeatInterval) {
|
||||
// no heartbeat
|
||||
return;
|
||||
}
|
||||
|
||||
var obj = Package.encode(Package.TYPE_HEARTBEAT);
|
||||
if (this.heartbeatTimeoutId) {
|
||||
clearTimeout(this.heartbeatTimeoutId);
|
||||
this.heartbeatTimeoutId = null;
|
||||
}
|
||||
|
||||
if (this.heartbeatId) {
|
||||
// already in a heartbeat interval
|
||||
return;
|
||||
}
|
||||
|
||||
this.heartbeatId = setTimeout(
|
||||
function () {
|
||||
this.heartbeatId = null;
|
||||
this.send(obj);
|
||||
|
||||
this.nextHeartbeatTimeout = Date.now() + this.heartbeatTimeout;
|
||||
this.heartbeatTimeoutId = setTimeout(
|
||||
this.heartbeatTimeoutCb.bind(this),
|
||||
this.heartbeatTimeout
|
||||
);
|
||||
}.bind(this),
|
||||
this.heartbeatInterval
|
||||
);
|
||||
}
|
||||
|
||||
heartbeatTimeoutCb() {
|
||||
var gap = this.nextHeartbeatTimeout - Date.now();
|
||||
if (gap > this.gapThreshold) {
|
||||
this.heartbeatTimeoutId = setTimeout(this.heartbeatTimeoutCb, gap);
|
||||
} else {
|
||||
console.error("server heartbeat timeout");
|
||||
this.emit("heartbeat timeout");
|
||||
this.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
handshake(data) {
|
||||
data = JSON.parse(Protocol.strdecode(data));
|
||||
if (data.code === RES_OLD_CLIENT) {
|
||||
this.emit("error", "client version not fullfill");
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.code !== RES_OK) {
|
||||
this.emit("error", "handshake fail");
|
||||
return;
|
||||
}
|
||||
|
||||
this.handshakeInit(data);
|
||||
|
||||
var obj = Package.encode(Package.TYPE_HANDSHAKE_ACK);
|
||||
this.send(obj);
|
||||
if (this.initCallback) {
|
||||
this.initCallback(this.socket);
|
||||
this.initCallback = null;
|
||||
}
|
||||
}
|
||||
|
||||
handshakeInit(data) {
|
||||
if (data.sys && data.sys.heartbeat) {
|
||||
this.heartbeatInterval = data.sys.heartbeat * 1000; // heartbeat interval
|
||||
this.heartbeatTimeout = this.heartbeatInterval * 2; // max heartbeat timeout
|
||||
} else {
|
||||
this.heartbeatInterval = 0;
|
||||
this.heartbeatTimeout = 0;
|
||||
}
|
||||
|
||||
this.initData(data);
|
||||
|
||||
if (typeof this.handshakeCallback === "function") {
|
||||
this.handshakeCallback(data.user);
|
||||
}
|
||||
}
|
||||
|
||||
initData(data) {
|
||||
if (!data || !data.sys) {
|
||||
return;
|
||||
}
|
||||
this.data = this.data || {};
|
||||
var dict = data.sys.dict;
|
||||
var protos = data.sys.protos;
|
||||
|
||||
//Init compress dict
|
||||
if (dict) {
|
||||
this.data.dict = dict;
|
||||
this.data.abbrs = {};
|
||||
|
||||
for (var route in dict) {
|
||||
this.data.abbrs[dict[route]] = route;
|
||||
}
|
||||
}
|
||||
|
||||
//Init protobuf protos
|
||||
if (protos) {
|
||||
this.data.protos = {
|
||||
server: protos.server || {},
|
||||
client: protos.client || {},
|
||||
};
|
||||
if (!!protobuf) {
|
||||
protobuf.init({
|
||||
encoderProtos: protos.client,
|
||||
decoderProtos: protos.server,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onData(data) {
|
||||
//probuff decode
|
||||
var msg = Message.decode(data);
|
||||
|
||||
if (msg.id > 0) {
|
||||
msg.route = this.routeMap[msg.id];
|
||||
delete this.routeMap[msg.id];
|
||||
if (!msg.route) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
msg.body = this.deCompose(msg);
|
||||
|
||||
this.processMessage(msg);
|
||||
}
|
||||
|
||||
deCompose(msg) {
|
||||
var protos = !!this.data.protos ? this.data.protos.server : {};
|
||||
var abbrs = this.data.abbrs;
|
||||
var route = msg.route;
|
||||
|
||||
//Decompose route from dict
|
||||
if (msg.compressRoute) {
|
||||
if (!abbrs[route]) {
|
||||
return {};
|
||||
}
|
||||
|
||||
route = msg.route = abbrs[route];
|
||||
}
|
||||
if (!!protos[route]) {
|
||||
return protobuf.decode(route, msg.body);
|
||||
} else {
|
||||
return JSON.parse(Protocol.strdecode(msg.body));
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
processMessage(msg) {
|
||||
if(!msg.id) {
|
||||
// server push message
|
||||
this.emit(msg.route, msg.body);
|
||||
return;
|
||||
}
|
||||
|
||||
//if have a id then find the callback function with the request
|
||||
var cb = this.callbacks[msg.id];
|
||||
|
||||
delete this.callbacks[msg.id];
|
||||
if(typeof cb !== 'function') {
|
||||
return;
|
||||
}
|
||||
|
||||
cb(msg.body);
|
||||
return;
|
||||
};
|
||||
|
||||
onKick(data) {
|
||||
this.emit("onKick");
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = PomeloClient;
|
611
proxy/lib/deps/pomelo-protobuf.js
Normal file
611
proxy/lib/deps/pomelo-protobuf.js
Normal file
@ -0,0 +1,611 @@
|
||||
/* ProtocolBuffer client 0.1.0*/
|
||||
|
||||
/**
|
||||
* pomelo-protobuf
|
||||
* @author <zhang0935@gmail.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Protocol buffer root
|
||||
* In browser, it will be window.protbuf
|
||||
*/
|
||||
(function (exports, global){
|
||||
var Protobuf = exports;
|
||||
|
||||
Protobuf.init = function(opts){
|
||||
//On the serverside, use serverProtos to encode messages send to client
|
||||
Protobuf.encoder.init(opts.encoderProtos);
|
||||
|
||||
//On the serverside, user clientProtos to decode messages receive from clients
|
||||
Protobuf.decoder.init(opts.decoderProtos);
|
||||
};
|
||||
|
||||
Protobuf.encode = function(key, msg){
|
||||
return Protobuf.encoder.encode(key, msg);
|
||||
};
|
||||
|
||||
Protobuf.decode = function(key, msg){
|
||||
return Protobuf.decoder.decode(key, msg);
|
||||
};
|
||||
|
||||
// exports to support for components
|
||||
module.exports = Protobuf;
|
||||
})('object' === typeof module ? module.exports : (this.protobuf = {}), this);
|
||||
|
||||
/**
|
||||
* constants
|
||||
*/
|
||||
(function (exports, global){
|
||||
var constants = exports.constants = {};
|
||||
|
||||
constants.TYPES = {
|
||||
uInt32 : 0,
|
||||
sInt32 : 0,
|
||||
int32 : 0,
|
||||
double : 1,
|
||||
string : 2,
|
||||
message : 2,
|
||||
float : 5
|
||||
};
|
||||
|
||||
})('undefined' !== typeof protobuf ? protobuf : module.exports, this);
|
||||
|
||||
/**
|
||||
* util module
|
||||
*/
|
||||
(function (exports, global){
|
||||
|
||||
var Util = exports.util = {};
|
||||
|
||||
Util.isSimpleType = function(type){
|
||||
return ( type === 'uInt32' ||
|
||||
type === 'sInt32' ||
|
||||
type === 'int32' ||
|
||||
type === 'uInt64' ||
|
||||
type === 'sInt64' ||
|
||||
type === 'float' ||
|
||||
type === 'double' );
|
||||
};
|
||||
|
||||
})('undefined' !== typeof protobuf ? protobuf : module.exports, this);
|
||||
|
||||
/**
|
||||
* codec module
|
||||
*/
|
||||
(function (exports, global){
|
||||
|
||||
var Codec = exports.codec = {};
|
||||
|
||||
var buffer = new ArrayBuffer(8);
|
||||
var float32Array = new Float32Array(buffer);
|
||||
var float64Array = new Float64Array(buffer);
|
||||
var uInt8Array = new Uint8Array(buffer);
|
||||
|
||||
Codec.encodeUInt32 = function(n){
|
||||
var n = parseInt(n);
|
||||
if(isNaN(n) || n < 0){
|
||||
return null;
|
||||
}
|
||||
|
||||
var result = [];
|
||||
do{
|
||||
var tmp = n % 128;
|
||||
var next = Math.floor(n/128);
|
||||
|
||||
if(next !== 0){
|
||||
tmp = tmp + 128;
|
||||
}
|
||||
result.push(tmp);
|
||||
n = next;
|
||||
}while(n !== 0);
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
Codec.encodeSInt32 = function(n){
|
||||
var n = parseInt(n);
|
||||
if(isNaN(n)){
|
||||
return null;
|
||||
}
|
||||
n = n<0?(Math.abs(n)*2-1):n*2;
|
||||
|
||||
return Codec.encodeUInt32(n);
|
||||
};
|
||||
|
||||
Codec.decodeUInt32 = function(bytes){
|
||||
var n = 0;
|
||||
|
||||
for(var i = 0; i < bytes.length; i++){
|
||||
var m = parseInt(bytes[i]);
|
||||
n = n + ((m & 0x7f) * Math.pow(2,(7*i)));
|
||||
if(m < 128){
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
};
|
||||
|
||||
|
||||
Codec.decodeSInt32 = function(bytes){
|
||||
var n = this.decodeUInt32(bytes);
|
||||
var flag = ((n%2) === 1)?-1:1;
|
||||
|
||||
n = ((n%2 + n)/2)*flag;
|
||||
|
||||
return n;
|
||||
};
|
||||
|
||||
Codec.encodeFloat = function(float){
|
||||
float32Array[0] = float;
|
||||
return uInt8Array;
|
||||
};
|
||||
|
||||
Codec.decodeFloat = function(bytes, offset){
|
||||
if(!bytes || bytes.length < (offset +4)){
|
||||
return null;
|
||||
}
|
||||
|
||||
for(var i = 0; i < 4; i++){
|
||||
uInt8Array[i] = bytes[offset + i];
|
||||
}
|
||||
|
||||
return float32Array[0];
|
||||
};
|
||||
|
||||
Codec.encodeDouble = function(double){
|
||||
float64Array[0] = double;
|
||||
return uInt8Array.subarray(0, 8);
|
||||
};
|
||||
|
||||
Codec.decodeDouble = function(bytes, offset){
|
||||
if(!bytes || bytes.length < (8 + offset)){
|
||||
return null;
|
||||
}
|
||||
|
||||
for(var i = 0; i < 8; i++){
|
||||
uInt8Array[i] = bytes[offset + i];
|
||||
}
|
||||
|
||||
return float64Array[0];
|
||||
};
|
||||
|
||||
Codec.encodeStr = function(bytes, offset, str){
|
||||
for(var i = 0; i < str.length; i++){
|
||||
var code = str.charCodeAt(i);
|
||||
var codes = encode2UTF8(code);
|
||||
|
||||
for(var j = 0; j < codes.length; j++){
|
||||
bytes[offset] = codes[j];
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
};
|
||||
|
||||
/**
|
||||
* Decode string from utf8 bytes
|
||||
*/
|
||||
Codec.decodeStr = function(bytes, offset, length){
|
||||
var array = [];
|
||||
var end = offset + length;
|
||||
|
||||
while(offset < end){
|
||||
var code = 0;
|
||||
|
||||
if(bytes[offset] < 128){
|
||||
code = bytes[offset];
|
||||
|
||||
offset += 1;
|
||||
}else if(bytes[offset] < 224){
|
||||
code = ((bytes[offset] & 0x3f)<<6) + (bytes[offset+1] & 0x3f);
|
||||
offset += 2;
|
||||
}else{
|
||||
code = ((bytes[offset] & 0x0f)<<12) + ((bytes[offset+1] & 0x3f)<<6) + (bytes[offset+2] & 0x3f);
|
||||
offset += 3;
|
||||
}
|
||||
|
||||
array.push(code);
|
||||
|
||||
}
|
||||
|
||||
var str = '';
|
||||
for(var i = 0; i < array.length;){
|
||||
str += String.fromCharCode.apply(null, array.slice(i, i + 10000));
|
||||
i += 10000;
|
||||
}
|
||||
|
||||
return str;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the byte length of the str use utf8
|
||||
*/
|
||||
Codec.byteLength = function(str){
|
||||
if(typeof(str) !== 'string'){
|
||||
return -1;
|
||||
}
|
||||
|
||||
var length = 0;
|
||||
|
||||
for(var i = 0; i < str.length; i++){
|
||||
var code = str.charCodeAt(i);
|
||||
length += codeLength(code);
|
||||
}
|
||||
|
||||
return length;
|
||||
};
|
||||
|
||||
/**
|
||||
* Encode a unicode16 char code to utf8 bytes
|
||||
*/
|
||||
function encode2UTF8(charCode){
|
||||
if(charCode <= 0x7f){
|
||||
return [charCode];
|
||||
}else if(charCode <= 0x7ff){
|
||||
return [0xc0|(charCode>>6), 0x80|(charCode & 0x3f)];
|
||||
}else{
|
||||
return [0xe0|(charCode>>12), 0x80|((charCode & 0xfc0)>>6), 0x80|(charCode & 0x3f)];
|
||||
}
|
||||
}
|
||||
|
||||
function codeLength(code){
|
||||
if(code <= 0x7f){
|
||||
return 1;
|
||||
}else if(code <= 0x7ff){
|
||||
return 2;
|
||||
}else{
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
})('undefined' !== typeof protobuf ? protobuf : module.exports, this);
|
||||
|
||||
/**
|
||||
* encoder module
|
||||
*/
|
||||
(function (exports, global){
|
||||
|
||||
var protobuf = exports;
|
||||
var MsgEncoder = exports.encoder = {};
|
||||
|
||||
var codec = protobuf.codec;
|
||||
var constant = protobuf.constants;
|
||||
var util = protobuf.util;
|
||||
|
||||
MsgEncoder.init = function(protos){
|
||||
this.protos = protos || {};
|
||||
};
|
||||
|
||||
MsgEncoder.encode = function(route, msg){
|
||||
//Get protos from protos map use the route as key
|
||||
var protos = this.protos[route];
|
||||
|
||||
//Check msg
|
||||
if(!checkMsg(msg, protos)){
|
||||
return null;
|
||||
}
|
||||
|
||||
//Set the length of the buffer 2 times bigger to prevent overflow
|
||||
var length = codec.byteLength(JSON.stringify(msg));
|
||||
|
||||
//Init buffer and offset
|
||||
var buffer = new ArrayBuffer(length);
|
||||
var uInt8Array = new Uint8Array(buffer);
|
||||
var offset = 0;
|
||||
|
||||
if(!!protos){
|
||||
offset = encodeMsg(uInt8Array, offset, protos, msg);
|
||||
if(offset > 0){
|
||||
return uInt8Array.subarray(0, offset);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the msg follow the defination in the protos
|
||||
*/
|
||||
function checkMsg(msg, protos){
|
||||
if(!protos){
|
||||
return false;
|
||||
}
|
||||
|
||||
for(var name in protos){
|
||||
var proto = protos[name];
|
||||
|
||||
//All required element must exist
|
||||
switch(proto.option){
|
||||
case 'required' :
|
||||
if(typeof(msg[name]) === 'undefined'){
|
||||
return false;
|
||||
}
|
||||
case 'optional' :
|
||||
if(typeof(msg[name]) !== 'undefined'){
|
||||
if(!!protos.__messages[proto.type]){
|
||||
checkMsg(msg[name], protos.__messages[proto.type]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'repeated' :
|
||||
//Check nest message in repeated elements
|
||||
if(!!msg[name] && !!protos.__messages[proto.type]){
|
||||
for(var i = 0; i < msg[name].length; i++){
|
||||
if(!checkMsg(msg[name][i], protos.__messages[proto.type])){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function encodeMsg(buffer, offset, protos, msg){
|
||||
for(var name in msg){
|
||||
if(!!protos[name]){
|
||||
var proto = protos[name];
|
||||
|
||||
switch(proto.option){
|
||||
case 'required' :
|
||||
case 'optional' :
|
||||
offset = writeBytes(buffer, offset, encodeTag(proto.type, proto.tag));
|
||||
offset = encodeProp(msg[name], proto.type, offset, buffer, protos);
|
||||
break;
|
||||
case 'repeated' :
|
||||
if(msg[name].length > 0){
|
||||
offset = encodeArray(msg[name], proto, offset, buffer, protos);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
function encodeProp(value, type, offset, buffer, protos){
|
||||
switch(type){
|
||||
case 'uInt32':
|
||||
offset = writeBytes(buffer, offset, codec.encodeUInt32(value));
|
||||
break;
|
||||
case 'int32' :
|
||||
case 'sInt32':
|
||||
offset = writeBytes(buffer, offset, codec.encodeSInt32(value));
|
||||
break;
|
||||
case 'float':
|
||||
writeBytes(buffer, offset, codec.encodeFloat(value));
|
||||
offset += 4;
|
||||
break;
|
||||
case 'double':
|
||||
writeBytes(buffer, offset, codec.encodeDouble(value));
|
||||
offset += 8;
|
||||
break;
|
||||
case 'string':
|
||||
var length = codec.byteLength(value);
|
||||
|
||||
//Encode length
|
||||
offset = writeBytes(buffer, offset, codec.encodeUInt32(length));
|
||||
//write string
|
||||
codec.encodeStr(buffer, offset, value);
|
||||
offset += length;
|
||||
break;
|
||||
default :
|
||||
if(!!protos.__messages[type]){
|
||||
//Use a tmp buffer to build an internal msg
|
||||
var tmpBuffer = new ArrayBuffer(codec.byteLength(JSON.stringify(value)));
|
||||
var length = 0;
|
||||
|
||||
length = encodeMsg(tmpBuffer, length, protos.__messages[type], value);
|
||||
//Encode length
|
||||
offset = writeBytes(buffer, offset, codec.encodeUInt32(length));
|
||||
//contact the object
|
||||
for(var i = 0; i < length; i++){
|
||||
buffer[offset] = tmpBuffer[i];
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode reapeated properties, simple msg and object are decode differented
|
||||
*/
|
||||
function encodeArray(array, proto, offset, buffer, protos){
|
||||
var i = 0;
|
||||
|
||||
if(util.isSimpleType(proto.type)){
|
||||
offset = writeBytes(buffer, offset, encodeTag(proto.type, proto.tag));
|
||||
offset = writeBytes(buffer, offset, codec.encodeUInt32(array.length));
|
||||
for(i = 0; i < array.length; i++){
|
||||
offset = encodeProp(array[i], proto.type, offset, buffer);
|
||||
}
|
||||
}else{
|
||||
for(i = 0; i < array.length; i++){
|
||||
offset = writeBytes(buffer, offset, encodeTag(proto.type, proto.tag));
|
||||
offset = encodeProp(array[i], proto.type, offset, buffer, protos);
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
function writeBytes(buffer, offset, bytes){
|
||||
for(var i = 0; i < bytes.length; i++, offset++){
|
||||
buffer[offset] = bytes[i];
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
function encodeTag(type, tag){
|
||||
var value = constant.TYPES[type]||2;
|
||||
return codec.encodeUInt32((tag<<3)|value);
|
||||
}
|
||||
})('undefined' !== typeof protobuf ? protobuf : module.exports, this);
|
||||
|
||||
/**
|
||||
* decoder module
|
||||
*/
|
||||
(function (exports, global){
|
||||
var protobuf = exports;
|
||||
var MsgDecoder = exports.decoder = {};
|
||||
|
||||
var codec = protobuf.codec;
|
||||
var util = protobuf.util;
|
||||
|
||||
var buffer;
|
||||
var offset = 0;
|
||||
|
||||
MsgDecoder.init = function(protos){
|
||||
this.protos = protos || {};
|
||||
};
|
||||
|
||||
MsgDecoder.setProtos = function(protos){
|
||||
if(!!protos){
|
||||
this.protos = protos;
|
||||
}
|
||||
};
|
||||
|
||||
MsgDecoder.decode = function(route, buf){
|
||||
var protos = this.protos[route];
|
||||
|
||||
buffer = buf;
|
||||
offset = 0;
|
||||
|
||||
if(!!protos){
|
||||
return decodeMsg({}, protos, buffer.length);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
function decodeMsg(msg, protos, length){
|
||||
while(offset<length){
|
||||
var head = getHead();
|
||||
var type = head.type;
|
||||
var tag = head.tag;
|
||||
var name = protos.__tags[tag];
|
||||
|
||||
switch(protos[name].option){
|
||||
case 'optional' :
|
||||
case 'required' :
|
||||
msg[name] = decodeProp(protos[name].type, protos);
|
||||
break;
|
||||
case 'repeated' :
|
||||
if(!msg[name]){
|
||||
msg[name] = [];
|
||||
}
|
||||
decodeArray(msg[name], protos[name].type, protos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the given msg is finished
|
||||
*/
|
||||
function isFinish(msg, protos){
|
||||
return (!protos.__tags[peekHead().tag]);
|
||||
}
|
||||
/**
|
||||
* Get property head from protobuf
|
||||
*/
|
||||
function getHead(){
|
||||
var tag = codec.decodeUInt32(getBytes());
|
||||
|
||||
return {
|
||||
type : tag&0x7,
|
||||
tag : tag>>3
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tag head without move the offset
|
||||
*/
|
||||
function peekHead(){
|
||||
var tag = codec.decodeUInt32(peekBytes());
|
||||
|
||||
return {
|
||||
type : tag&0x7,
|
||||
tag : tag>>3
|
||||
};
|
||||
}
|
||||
|
||||
function decodeProp(type, protos){
|
||||
switch(type){
|
||||
case 'uInt32':
|
||||
return codec.decodeUInt32(getBytes());
|
||||
case 'int32' :
|
||||
case 'sInt32' :
|
||||
return codec.decodeSInt32(getBytes());
|
||||
case 'float' :
|
||||
var float = codec.decodeFloat(buffer, offset);
|
||||
offset += 4;
|
||||
return float;
|
||||
case 'double' :
|
||||
var double = codec.decodeDouble(buffer, offset);
|
||||
offset += 8;
|
||||
return double;
|
||||
case 'string' :
|
||||
var length = codec.decodeUInt32(getBytes());
|
||||
|
||||
var str = codec.decodeStr(buffer, offset, length);
|
||||
offset += length;
|
||||
|
||||
return str;
|
||||
default :
|
||||
if(!!protos && !!protos.__messages[type]){
|
||||
var length = codec.decodeUInt32(getBytes());
|
||||
var msg = {};
|
||||
decodeMsg(msg, protos.__messages[type], offset+length);
|
||||
return msg;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function decodeArray(array, type, protos){
|
||||
if(util.isSimpleType(type)){
|
||||
var length = codec.decodeUInt32(getBytes());
|
||||
|
||||
for(var i = 0; i < length; i++){
|
||||
array.push(decodeProp(type));
|
||||
}
|
||||
}else{
|
||||
array.push(decodeProp(type, protos));
|
||||
}
|
||||
}
|
||||
|
||||
function getBytes(flag){
|
||||
var bytes = [];
|
||||
var pos = offset;
|
||||
flag = flag || false;
|
||||
|
||||
var b;
|
||||
|
||||
do{
|
||||
b = buffer[pos];
|
||||
bytes.push(b);
|
||||
pos++;
|
||||
}while(b >= 128);
|
||||
|
||||
if(!flag){
|
||||
offset = pos;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
function peekBytes(){
|
||||
return getBytes(true);
|
||||
}
|
||||
|
||||
})('undefined' !== typeof protobuf ? protobuf : module.exports, this);
|
341
proxy/lib/deps/pomelo-protocol.js
Normal file
341
proxy/lib/deps/pomelo-protocol.js
Normal file
@ -0,0 +1,341 @@
|
||||
const ByteArray = Uint8Array;
|
||||
var Protocol = exports;
|
||||
|
||||
|
||||
var PKG_HEAD_BYTES = 4;
|
||||
var MSG_FLAG_BYTES = 1;
|
||||
var MSG_ROUTE_CODE_BYTES = 2;
|
||||
var MSG_ID_MAX_BYTES = 5;
|
||||
var MSG_ROUTE_LEN_BYTES = 1;
|
||||
|
||||
var MSG_ROUTE_CODE_MAX = 0xffff;
|
||||
|
||||
var MSG_COMPRESS_ROUTE_MASK = 0x1;
|
||||
var MSG_TYPE_MASK = 0x7;
|
||||
|
||||
var Package = Protocol.Package = {};
|
||||
var Message = Protocol.Message = {};
|
||||
|
||||
Package.TYPE_HANDSHAKE = 1;
|
||||
Package.TYPE_HANDSHAKE_ACK = 2;
|
||||
Package.TYPE_HEARTBEAT = 3;
|
||||
Package.TYPE_DATA = 4;
|
||||
Package.TYPE_KICK = 5;
|
||||
|
||||
Message.TYPE_REQUEST = 0;
|
||||
Message.TYPE_NOTIFY = 1;
|
||||
Message.TYPE_RESPONSE = 2;
|
||||
Message.TYPE_PUSH = 3;
|
||||
|
||||
/**
|
||||
* pomele client encode
|
||||
* id message id;
|
||||
* route message route
|
||||
* msg message body
|
||||
* socketio current support string
|
||||
*/
|
||||
Protocol.strencode = function(str) {
|
||||
var byteArray = new ByteArray(str.length * 3);
|
||||
var offset = 0;
|
||||
for(var i = 0; i < str.length; i++){
|
||||
var charCode = str.charCodeAt(i);
|
||||
var codes = null;
|
||||
if(charCode <= 0x7f){
|
||||
codes = [charCode];
|
||||
}else if(charCode <= 0x7ff){
|
||||
codes = [0xc0|(charCode>>6), 0x80|(charCode & 0x3f)];
|
||||
}else{
|
||||
codes = [0xe0|(charCode>>12), 0x80|((charCode & 0xfc0)>>6), 0x80|(charCode & 0x3f)];
|
||||
}
|
||||
for(var j = 0; j < codes.length; j++){
|
||||
byteArray[offset] = codes[j];
|
||||
++offset;
|
||||
}
|
||||
}
|
||||
var _buffer = new ByteArray(offset);
|
||||
copyArray(_buffer, 0, byteArray, 0, offset);
|
||||
return _buffer;
|
||||
};
|
||||
|
||||
/**
|
||||
* client decode
|
||||
* msg String data
|
||||
* return Message Object
|
||||
*/
|
||||
Protocol.strdecode = function(buffer) {
|
||||
var bytes = new ByteArray(buffer);
|
||||
var array = [];
|
||||
var offset = 0;
|
||||
var charCode = 0;
|
||||
var end = bytes.length;
|
||||
while(offset < end){
|
||||
if(bytes[offset] < 128){
|
||||
charCode = bytes[offset];
|
||||
offset += 1;
|
||||
}else if(bytes[offset] < 224){
|
||||
charCode = ((bytes[offset] & 0x3f)<<6) + (bytes[offset+1] & 0x3f);
|
||||
offset += 2;
|
||||
}else{
|
||||
charCode = ((bytes[offset] & 0x0f)<<12) + ((bytes[offset+1] & 0x3f)<<6) + (bytes[offset+2] & 0x3f);
|
||||
offset += 3;
|
||||
}
|
||||
array.push(charCode);
|
||||
}
|
||||
var res = '';
|
||||
var chunk = 8 * 1024;
|
||||
var i;
|
||||
for (i = 0; i < array.length / chunk; i++) {
|
||||
res += String.fromCharCode.apply(null, array.slice(i * chunk, (i + 1) * chunk));
|
||||
}
|
||||
res += String.fromCharCode.apply(null, array.slice(i * chunk));
|
||||
return res;
|
||||
};
|
||||
|
||||
/**
|
||||
* Package protocol encode.
|
||||
*
|
||||
* Pomelo package format:
|
||||
* +------+-------------+------------------+
|
||||
* | type | body length | body |
|
||||
* +------+-------------+------------------+
|
||||
*
|
||||
* Head: 4bytes
|
||||
* 0: package type,
|
||||
* 1 - handshake,
|
||||
* 2 - handshake ack,
|
||||
* 3 - heartbeat,
|
||||
* 4 - data
|
||||
* 5 - kick
|
||||
* 1 - 3: big-endian body length
|
||||
* Body: body length bytes
|
||||
*
|
||||
* @param {Number} type package type
|
||||
* @param {ByteArray} body body content in bytes
|
||||
* @return {ByteArray} new byte array that contains encode result
|
||||
*/
|
||||
Package.encode = function(type, body){
|
||||
var length = body ? body.length : 0;
|
||||
var buffer = new ByteArray(PKG_HEAD_BYTES + length);
|
||||
var index = 0;
|
||||
buffer[index++] = type & 0xff;
|
||||
buffer[index++] = (length >> 16) & 0xff;
|
||||
buffer[index++] = (length >> 8) & 0xff;
|
||||
buffer[index++] = length & 0xff;
|
||||
if(body) {
|
||||
copyArray(buffer, index, body, 0, length);
|
||||
}
|
||||
return buffer;
|
||||
};
|
||||
|
||||
/**
|
||||
* Package protocol decode.
|
||||
* See encode for package format.
|
||||
*
|
||||
* @param {ByteArray} buffer byte array containing package content
|
||||
* @return {Object} {type: package type, buffer: body byte array}
|
||||
*/
|
||||
Package.decode = function(buffer){
|
||||
var bytes = new ByteArray(buffer);
|
||||
var type = bytes[0];
|
||||
var index = 1;
|
||||
var length = ((bytes[index++]) << 16 | (bytes[index++]) << 8 | bytes[index++]) >>> 0;
|
||||
var body = length ? new ByteArray(length) : null;
|
||||
copyArray(body, 0, bytes, PKG_HEAD_BYTES, length);
|
||||
return {'type': type, 'body': body};
|
||||
};
|
||||
|
||||
/**
|
||||
* Message protocol encode.
|
||||
*
|
||||
* @param {Number} id message id
|
||||
* @param {Number} type message type
|
||||
* @param {Number} compressRoute whether compress route
|
||||
* @param {Number|String} route route code or route string
|
||||
* @param {Buffer} msg message body bytes
|
||||
* @return {Buffer} encode result
|
||||
*/
|
||||
Message.encode = function(id, type, compressRoute, route, msg){
|
||||
// caculate message max length
|
||||
var idBytes = msgHasId(type) ? caculateMsgIdBytes(id) : 0;
|
||||
var msgLen = MSG_FLAG_BYTES + idBytes;
|
||||
|
||||
if(msgHasRoute(type)) {
|
||||
if(compressRoute) {
|
||||
if(typeof route !== 'number'){
|
||||
throw new Error('error flag for number route!');
|
||||
}
|
||||
msgLen += MSG_ROUTE_CODE_BYTES;
|
||||
} else {
|
||||
msgLen += MSG_ROUTE_LEN_BYTES;
|
||||
if(route) {
|
||||
route = Protocol.strencode(route);
|
||||
if(route.length>255) {
|
||||
throw new Error('route maxlength is overflow');
|
||||
}
|
||||
msgLen += route.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(msg) {
|
||||
msgLen += msg.length;
|
||||
}
|
||||
|
||||
var buffer = new ByteArray(msgLen);
|
||||
var offset = 0;
|
||||
|
||||
// add flag
|
||||
offset = encodeMsgFlag(type, compressRoute, buffer, offset);
|
||||
|
||||
// add message id
|
||||
if(msgHasId(type)) {
|
||||
offset = encodeMsgId(id, idBytes, buffer, offset);
|
||||
}
|
||||
|
||||
// add route
|
||||
if(msgHasRoute(type)) {
|
||||
offset = encodeMsgRoute(compressRoute, route, buffer, offset);
|
||||
}
|
||||
|
||||
// add body
|
||||
if(msg) {
|
||||
offset = encodeMsgBody(msg, buffer, offset);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
};
|
||||
|
||||
/**
|
||||
* Message protocol decode.
|
||||
*
|
||||
* @param {Buffer|Uint8Array} buffer message bytes
|
||||
* @return {Object} message object
|
||||
*/
|
||||
Message.decode = function(buffer) {
|
||||
var bytes = new ByteArray(buffer);
|
||||
var bytesLen = bytes.length || bytes.byteLength;
|
||||
var offset = 0;
|
||||
var id = 0;
|
||||
var route = null;
|
||||
|
||||
// parse flag
|
||||
var flag = bytes[offset++];
|
||||
var compressRoute = flag & MSG_COMPRESS_ROUTE_MASK;
|
||||
var type = (flag >> 1) & MSG_TYPE_MASK;
|
||||
|
||||
// parse id
|
||||
if(msgHasId(type)) {
|
||||
var byte = bytes[offset++];
|
||||
id = byte & 0x7f;
|
||||
while(byte & 0x80) {
|
||||
id <<= 7;
|
||||
byte = bytes[offset++];
|
||||
id |= byte & 0x7f;
|
||||
}
|
||||
}
|
||||
|
||||
// parse route
|
||||
if(msgHasRoute(type)) {
|
||||
if(compressRoute) {
|
||||
route = (bytes[offset++]) << 8 | bytes[offset++];
|
||||
} else {
|
||||
var routeLen = bytes[offset++];
|
||||
if(routeLen) {
|
||||
route = new ByteArray(routeLen);
|
||||
copyArray(route, 0, bytes, offset, routeLen);
|
||||
route = Protocol.strdecode(route);
|
||||
} else {
|
||||
route = '';
|
||||
}
|
||||
offset += routeLen;
|
||||
}
|
||||
}
|
||||
|
||||
// parse body
|
||||
var bodyLen = bytesLen - offset;
|
||||
var body = new ByteArray(bodyLen);
|
||||
|
||||
copyArray(body, 0, bytes, offset, bodyLen);
|
||||
|
||||
return {'id': id, 'type': type, 'compressRoute': compressRoute,
|
||||
'route': route, 'body': body};
|
||||
};
|
||||
|
||||
var copyArray = function(dest, doffset, src, soffset, length) {
|
||||
if('function' === typeof src.copy) {
|
||||
// Buffer
|
||||
src.copy(dest, doffset, soffset, soffset + length);
|
||||
} else {
|
||||
// Uint8Array
|
||||
for(var index=0; index<length; index++){
|
||||
dest[doffset++] = src[soffset++];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var msgHasId = function(type) {
|
||||
return type === Message.TYPE_REQUEST || type === Message.TYPE_RESPONSE;
|
||||
};
|
||||
|
||||
var msgHasRoute = function(type) {
|
||||
return type === Message.TYPE_REQUEST || type === Message.TYPE_NOTIFY ||
|
||||
type === Message.TYPE_PUSH;
|
||||
};
|
||||
|
||||
var caculateMsgIdBytes = function(id) {
|
||||
var len = 0;
|
||||
do {
|
||||
len += 1;
|
||||
id >>= 7;
|
||||
} while(id > 0);
|
||||
return len;
|
||||
};
|
||||
|
||||
var encodeMsgFlag = function(type, compressRoute, buffer, offset) {
|
||||
if(type !== Message.TYPE_REQUEST && type !== Message.TYPE_NOTIFY &&
|
||||
type !== Message.TYPE_RESPONSE && type !== Message.TYPE_PUSH) {
|
||||
throw new Error('unkonw message type: ' + type);
|
||||
}
|
||||
|
||||
buffer[offset] = (type << 1) | (compressRoute ? 1 : 0);
|
||||
|
||||
return offset + MSG_FLAG_BYTES;
|
||||
};
|
||||
|
||||
var encodeMsgId = function(id, idBytes, buffer, offset) {
|
||||
var index = offset + idBytes - 1;
|
||||
buffer[index--] = id & 0x7f;
|
||||
while(index >= offset) {
|
||||
id >>= 7;
|
||||
buffer[index--] = id & 0x7f | 0x80;
|
||||
}
|
||||
return offset + idBytes;
|
||||
};
|
||||
|
||||
var encodeMsgRoute = function(compressRoute, route, buffer, offset) {
|
||||
if (compressRoute) {
|
||||
if(route > MSG_ROUTE_CODE_MAX){
|
||||
throw new Error('route number is overflow');
|
||||
}
|
||||
|
||||
buffer[offset++] = (route >> 8) & 0xff;
|
||||
buffer[offset++] = route & 0xff;
|
||||
} else {
|
||||
if(route) {
|
||||
buffer[offset++] = route.length & 0xff;
|
||||
copyArray(buffer, offset, route, 0, route.length);
|
||||
offset += route.length;
|
||||
} else {
|
||||
buffer[offset++] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
};
|
||||
|
||||
var encodeMsgBody = function(msg, buffer, offset) {
|
||||
copyArray(buffer, offset, msg, 0, msg.length);
|
||||
return offset + msg.length;
|
||||
};
|
||||
|
||||
module.exports = Protocol;
|
16
proxy/node_modules/.package-lock.json
generated
vendored
Normal file
16
proxy/node_modules/.package-lock.json
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "proxy",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"node_modules/bytearray": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/bytearray/-/bytearray-0.1.3.tgz",
|
||||
"integrity": "sha512-oEKhhGYMfEdfnp4yViXVeauXLLYLj0hs8cQpJmu0JXbhuVX1iTeVmZ2IW4QtXhBcZitzOZ6pYNRvMDJRl5/0og==",
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
15
proxy/node_modules/bytearray/.jshintrc
generated
vendored
Normal file
15
proxy/node_modules/bytearray/.jshintrc
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"curly": true,
|
||||
"eqeqeq": true,
|
||||
"immed": true,
|
||||
"latedef": true,
|
||||
"newcap": true,
|
||||
"noarg": true,
|
||||
"sub": true,
|
||||
"undef": true,
|
||||
"unused": true,
|
||||
"boss": true,
|
||||
"eqnull": true,
|
||||
"node": true,
|
||||
"es5": true
|
||||
}
|
3
proxy/node_modules/bytearray/.npmignore
generated
vendored
Normal file
3
proxy/node_modules/bytearray/.npmignore
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/node_modules/
|
||||
.DS_Store
|
||||
*.swp
|
22
proxy/node_modules/bytearray/LICENSE-MIT
generated
vendored
Normal file
22
proxy/node_modules/bytearray/LICENSE-MIT
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
Copyright (c) 2013 yi
|
||||
|
||||
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.
|
31
proxy/node_modules/bytearray/README.md
generated
vendored
Normal file
31
proxy/node_modules/bytearray/README.md
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
# bytearray
|
||||
|
||||
a Node.JS module for Buffer processing exposes API similar to ByteArray of ActionScript
|
||||
|
||||
## Install
|
||||
Install the module with: `npm install bytearray`
|
||||
|
||||
```javascript
|
||||
var bytearray = require('bytearray');
|
||||
```
|
||||
|
||||
## Usage
|
||||
* bytearray.readBoolean(buf, [offset]):Boolean
|
||||
* bytearray.readInt(buf, [offset]):int
|
||||
* bytearray.readShort(buf, [offset]):int
|
||||
* bytearray.readUnsignedByte(buf, [offset]):uint
|
||||
* bytearray.readUnsignedInt(buf, [offset]):uint
|
||||
* bytearray.readUnsignedShort(buf, [offset]):uint
|
||||
* bytearray.readUTF(buf, [offset]):String
|
||||
* bytearray.readUTFByte(buf, [offset]s(length:uint):String
|
||||
* bytearray.writeBoolean(value:Boolean):void
|
||||
* bytearray.writeByte(value:int):void
|
||||
* bytearray.writeBytes(bytes:ByteArray, offset:uint = 0, length:uint = 0):void
|
||||
* bytearray.writeInt(value:int):void
|
||||
* bytearray.writeShort(value:int):void
|
||||
* bytearray.writeUnsignedInt(value:uint):void
|
||||
* bytearray.writeUTF(value:String):void
|
||||
|
||||
## License
|
||||
Copyright (c) 2013 yi
|
||||
Licensed under the MIT license.
|
1
proxy/node_modules/bytearray/bin/coffee-watch.bat
generated
vendored
Executable file
1
proxy/node_modules/bytearray/bin/coffee-watch.bat
generated
vendored
Executable file
@ -0,0 +1 @@
|
||||
coffee -o ./lib/ -cw ./src/
|
367
proxy/node_modules/bytearray/lib/bytearray.js
generated
vendored
Normal file
367
proxy/node_modules/bytearray/lib/bytearray.js
generated
vendored
Normal file
@ -0,0 +1,367 @@
|
||||
// Generated by CoffeeScript 1.6.3
|
||||
/*
|
||||
# a collection of utility methods for Buffer
|
||||
#
|
||||
# 这个工具类的设计以实现两个目地
|
||||
# 1. 读写方法,匹配 Actionscript 的 ByteArray 读写方法
|
||||
# 2. ActionScript 的默认采用 big endian,这个工具方法,对此进行封装,以是外部不用关心 endian
|
||||
#
|
||||
*/
|
||||
|
||||
|
||||
(function() {
|
||||
module.exports = {
|
||||
readUTF: function(buf, offset) {
|
||||
var len;
|
||||
if (!Buffer.isBuffer(buf)) {
|
||||
return null;
|
||||
}
|
||||
offset = offset < 0 ? buf.length + offset : (offset === 0 ? 0 : offset || buf.position || 0);
|
||||
if (buf.length <= offset + 2) {
|
||||
return null;
|
||||
}
|
||||
len = buf.readUInt16BE(offset);
|
||||
if (buf.length < len + offset) {
|
||||
return null;
|
||||
}
|
||||
offset += 2;
|
||||
buf.position = offset + len;
|
||||
return buf.toString('utf8', offset, offset + len);
|
||||
},
|
||||
readUTFBytes: function(buf, length, offset) {
|
||||
if (!Buffer.isBuffer(buf)) {
|
||||
return null;
|
||||
}
|
||||
offset = offset < 0 ? buf.length + offset : (offset === 0 ? 0 : offset || buf.position || 0);
|
||||
if (buf.length <= offset) {
|
||||
return null;
|
||||
}
|
||||
buf.position = offset + length;
|
||||
return buf.toString('utf8', offset, offset + length);
|
||||
},
|
||||
readFixLengthASCII: function(buf, offset) {
|
||||
var len;
|
||||
if (!Buffer.isBuffer(buf)) {
|
||||
return null;
|
||||
}
|
||||
offset = offset < 0 ? buf.length + offset : (offset === 0 ? 0 : offset || buf.position || 0);
|
||||
if (buf.length <= offset + 2) {
|
||||
return null;
|
||||
}
|
||||
len = buf.readUInt8(offset);
|
||||
if (buf.length < len + offset) {
|
||||
return null;
|
||||
}
|
||||
offset += 1;
|
||||
buf.position = offset + len;
|
||||
return buf.toString('utf8', offset, offset + len);
|
||||
},
|
||||
readUnsignedShort: function(buf, offset) {
|
||||
if (!Buffer.isBuffer(buf)) {
|
||||
return 0;
|
||||
}
|
||||
offset = offset < 0 ? buf.length + offset : (offset === 0 ? 0 : offset || buf.position || 0);
|
||||
buf.position = offset + 2;
|
||||
return buf.readUInt16BE(offset);
|
||||
},
|
||||
readShort: function(buf, offset) {
|
||||
if (!Buffer.isBuffer(buf)) {
|
||||
return 0;
|
||||
}
|
||||
offset = offset < 0 ? buf.length + offset : (offset === 0 ? 0 : offset || buf.position || 0);
|
||||
buf.position = offset + 2;
|
||||
return buf.readInt16BE(offset);
|
||||
},
|
||||
readUnsignedByte: function(buf, offset) {
|
||||
if (!Buffer.isBuffer(buf)) {
|
||||
return 0;
|
||||
}
|
||||
offset = offset < 0 ? buf.length + offset : (offset === 0 ? 0 : offset || buf.position || 0);
|
||||
buf.position = offset + 1;
|
||||
return buf.readUInt8(offset);
|
||||
},
|
||||
readByte: function(buf, offset) {
|
||||
if (!Buffer.isBuffer(buf)) {
|
||||
return 0;
|
||||
}
|
||||
offset = offset < 0 ? buf.length + offset : (offset === 0 ? 0 : offset || buf.position || 0);
|
||||
buf.position = offset + 1;
|
||||
return buf.readInt8(offset);
|
||||
},
|
||||
readUnsignedInt: function(buf, offset) {
|
||||
if (!Buffer.isBuffer(buf)) {
|
||||
return 0;
|
||||
}
|
||||
offset = offset < 0 ? buf.length + offset : (offset === 0 ? 0 : offset || buf.position || 0);
|
||||
buf.position = offset + 4;
|
||||
return buf.readUInt32BE(offset);
|
||||
},
|
||||
readInt: function(buf, offset) {
|
||||
if (!Buffer.isBuffer(buf)) {
|
||||
return 0;
|
||||
}
|
||||
offset = offset < 0 ? buf.length + offset : (offset === 0 ? 0 : offset || buf.position || 0);
|
||||
buf.position = offset + 4;
|
||||
return buf.readInt32BE(offset);
|
||||
},
|
||||
readFloat: function(buf, offset) {
|
||||
if (!Buffer.isBuffer(buf)) {
|
||||
return 0;
|
||||
}
|
||||
offset = offset < 0 ? buf.length + offset : (offset === 0 ? 0 : offset || buf.position || 0);
|
||||
buf.position = offset + 4;
|
||||
return buf.readFloatLE(offset);
|
||||
},
|
||||
readUnsignedIntArray: function(buf, offset) {
|
||||
var a, arr, len;
|
||||
offset = offset < 0 ? buf.length + offset : (offset === 0 ? 0 : offset || buf.position || 0);
|
||||
len = buf.readUInt16BE(offset) >>> 2;
|
||||
offset += 2;
|
||||
arr = [];
|
||||
if (len === 0 || len > 1024) {
|
||||
buf.position = offset;
|
||||
return arr;
|
||||
}
|
||||
while (len > 0) {
|
||||
a = buf.readUInt32BE(offset);
|
||||
arr.push(a);
|
||||
offset += 4;
|
||||
len -= 1;
|
||||
}
|
||||
buf.position = offset;
|
||||
return arr;
|
||||
},
|
||||
writeUnsignedInt: function(buf, value, offset) {
|
||||
offset = offset < 0 ? buf.length + offset : (offset === 0 ? 0 : offset || buf.position || 0);
|
||||
buf.writeUInt32BE(value, offset);
|
||||
buf.position = offset + 4;
|
||||
},
|
||||
writeInt: function(buf, value, offset) {
|
||||
offset = offset < 0 ? buf.length + offset : (offset === 0 ? 0 : offset || buf.position || 0);
|
||||
buf.writeInt32BE(value, offset);
|
||||
buf.position = offset + 4;
|
||||
},
|
||||
writeFloat: function(buf, value, offset) {
|
||||
offset = offset < 0 ? buf.length + offset : (offset === 0 ? 0 : offset || buf.position || 0);
|
||||
buf.writeFloatLE(value, offset);
|
||||
buf.position = offset + 4;
|
||||
},
|
||||
writeUnsignedShort: function(buf, value, offset) {
|
||||
offset = offset < 0 ? buf.length + offset : (offset === 0 ? 0 : offset || buf.position || 0);
|
||||
buf.writeUInt16BE(value, offset);
|
||||
buf.position = offset + 2;
|
||||
},
|
||||
writeShort: function(buf, value, offset) {
|
||||
offset = offset < 0 ? buf.length + offset : (offset === 0 ? 0 : offset || buf.position || 0);
|
||||
buf.writeInt16BE(value, offset);
|
||||
buf.position = offset + 2;
|
||||
},
|
||||
writeUnsignedByte: function(buf, value, offset) {
|
||||
offset = offset < 0 ? buf.length + offset : (offset === 0 ? 0 : offset || buf.position || 0);
|
||||
buf.writeUInt8(value, offset);
|
||||
buf.position = offset + 1;
|
||||
},
|
||||
writeByte: function(buf, value, offset) {
|
||||
offset = offset < 0 ? buf.length + offset : (offset === 0 ? 0 : offset || buf.position || 0);
|
||||
buf.writeInt8(value, offset);
|
||||
buf.position = offset + 1;
|
||||
},
|
||||
writeBoolean: function(buf, value, offset) {
|
||||
offset = offset < 0 ? buf.length + offset : (offset === 0 ? 0 : offset || buf.position || 0);
|
||||
value = value ? 1 : 0;
|
||||
buf.writeInt8(value, offset);
|
||||
buf.position = offset + 1;
|
||||
},
|
||||
writeFixLengthASCII: function(buf, str, maxNumOfChar, offset) {
|
||||
offset = offset < 0 ? buf.length + offset : (offset === 0 ? 0 : offset || buf.position || 0);
|
||||
buf.writeUInt8(maxNumOfChar, offset);
|
||||
offset += 1;
|
||||
buf.fill(0x20, offset, offset + maxNumOfChar);
|
||||
buf.write(str, offset, maxNumOfChar, 'ascii');
|
||||
buf.position = offset + maxNumOfChar;
|
||||
},
|
||||
writeFixLengthUTF: function(buf, str, maxNumOfChar, offset) {
|
||||
offset = offset < 0 ? buf.length + offset : (offset === 0 ? 0 : offset || buf.position || 0);
|
||||
maxNumOfChar *= 6;
|
||||
buf.writeUInt16BE(maxNumOfChar, offset);
|
||||
offset += 2;
|
||||
buf.fill(0x20, offset, offset + maxNumOfChar);
|
||||
buf.write(str, offset, maxNumOfChar, 'utf8');
|
||||
buf.position = offset + maxNumOfChar;
|
||||
},
|
||||
writeUTF: function(buf, str, offset) {
|
||||
var byteLength;
|
||||
offset = offset < 0 ? buf.length + offset : (offset === 0 ? 0 : offset || buf.position || 0);
|
||||
byteLength = Buffer.byteLength(str);
|
||||
buf.writeUInt16BE(byteLength, offset);
|
||||
offset += 2;
|
||||
buf.write(str, offset);
|
||||
buf.position = offset + byteLength;
|
||||
},
|
||||
writeUTFBytes: function(buf, str, offset) {
|
||||
offset = offset < 0 ? buf.length + offset : (offset === 0 ? 0 : offset || buf.position || 0);
|
||||
buf.write(str, offset);
|
||||
buf.position = offset + Buffer.byteLength(str);
|
||||
},
|
||||
writeUTFArray: function(buf, strArray, offset) {
|
||||
var byteLength, str, _i, _len;
|
||||
offset = offset < 0 ? buf.length + offset : (offset === 0 ? 0 : offset || buf.position || 0);
|
||||
if (!((strArray != null) && strArray.length > 0)) {
|
||||
buf.writeUInt16BE(0, offset);
|
||||
buf.position = offset + 2;
|
||||
return;
|
||||
}
|
||||
buf.writeUInt16BE(strArray.length, offset);
|
||||
offset += 2;
|
||||
for (_i = 0, _len = strArray.length; _i < _len; _i++) {
|
||||
str = strArray[_i];
|
||||
byteLength = Buffer.byteLength(str);
|
||||
buf.writeUInt16BE(byteLength, offset);
|
||||
offset += 2;
|
||||
buf.write(str, offset);
|
||||
offset += byteLength;
|
||||
}
|
||||
return buf.position = offset;
|
||||
},
|
||||
getByteLengthOfUTFArray: function(strArray) {
|
||||
var len, str, _i, _len;
|
||||
len = 2;
|
||||
if (!((strArray != null) && strArray.length > 0)) {
|
||||
return len;
|
||||
}
|
||||
for (_i = 0, _len = strArray.length; _i < _len; _i++) {
|
||||
str = strArray[_i];
|
||||
len = len + 2 + Buffer.byteLength(str);
|
||||
}
|
||||
return len;
|
||||
},
|
||||
writeUnsignedIntArray: function(buf, arr, fixedLength, offset) {
|
||||
var i, n, _i, _len;
|
||||
if (fixedLength == null) {
|
||||
fixedLength = -1;
|
||||
}
|
||||
arr = arr || [];
|
||||
offset = offset < 0 ? buf.length + offset : (offset === 0 ? 0 : offset || buf.position || 0);
|
||||
n = arr.length;
|
||||
if (fixedLength > 0 && fixedLength !== n) {
|
||||
if (fixedLength < n) {
|
||||
arr = arr.slice(0, fixedLength);
|
||||
} else {
|
||||
arr = arr.concat();
|
||||
arr.length = fixedLength;
|
||||
}
|
||||
n = fixedLength;
|
||||
}
|
||||
n = n << 2;
|
||||
buf.writeUInt16BE(n, offset);
|
||||
offset += 2;
|
||||
for (_i = 0, _len = arr.length; _i < _len; _i++) {
|
||||
i = arr[_i];
|
||||
buf.writeUInt32BE(parseInt(i, 10) || 0, offset);
|
||||
offset += 4;
|
||||
}
|
||||
buf.position = offset;
|
||||
},
|
||||
getByteLengthOfIntArray: function(arr) {
|
||||
return (arr.length << 2) + 2;
|
||||
},
|
||||
writeUnsignedShortArray: function(buf, arr, fixedLength, offset) {
|
||||
var i, n, _i, _len;
|
||||
if (fixedLength == null) {
|
||||
fixedLength = -1;
|
||||
}
|
||||
arr = arr || [];
|
||||
offset = offset < 0 ? buf.length + offset : (offset === 0 ? 0 : offset || buf.position || 0);
|
||||
n = arr.length;
|
||||
if (fixedLength > 0 && fixedLength !== n) {
|
||||
if (fixedLength < n) {
|
||||
arr = arr.slice(0, fixedLength);
|
||||
} else {
|
||||
arr = arr.concat();
|
||||
arr.length = fixedLength;
|
||||
}
|
||||
n = fixedLength;
|
||||
}
|
||||
n = n << 1;
|
||||
buf.writeUInt16BE(n, offset);
|
||||
offset += 2;
|
||||
for (_i = 0, _len = arr.length; _i < _len; _i++) {
|
||||
i = arr[_i];
|
||||
buf.writeUInt16BE(parseInt(i, 10) || 0, offset);
|
||||
offset += 2;
|
||||
}
|
||||
buf.position = offset;
|
||||
},
|
||||
getBytesAvailable: function(buf) {
|
||||
if (buf != null) {
|
||||
return buf.length - (buf.position || 0);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
scrap: function(buf, length) {
|
||||
var offset, result;
|
||||
if (!((buf != null) && length > 0)) {
|
||||
return null;
|
||||
}
|
||||
offset = buf.position || 0;
|
||||
if (length + offset > buf.length) {
|
||||
return null;
|
||||
}
|
||||
result = new Buffer(length);
|
||||
buf.copy(result, 0, offset, offset + length);
|
||||
buf.position = offset + length;
|
||||
return result;
|
||||
},
|
||||
duplicate: function(buf) {
|
||||
var n, result;
|
||||
n = buf.length || 0;
|
||||
if (n === 0) {
|
||||
return null;
|
||||
}
|
||||
result = new Buffer(n);
|
||||
buf.copy(result, 0, 0, n);
|
||||
return result;
|
||||
},
|
||||
utfStringToBuf: function(str) {
|
||||
var buf, n;
|
||||
str = String(str || '');
|
||||
n = Buffer.byteLength(str, 'utf8');
|
||||
buf = new Buffer(n + 2);
|
||||
buf.writeUInt16BE(n, 0);
|
||||
buf.write(str, 2);
|
||||
return buf;
|
||||
},
|
||||
isAvailableBuf: function(buf) {
|
||||
return Buffer.isBuffer(buf) && buf.length > 0;
|
||||
},
|
||||
writeIntArray: function(buf, arr, fixedLength, offset) {
|
||||
var i, n, _i, _len;
|
||||
if (fixedLength == null) {
|
||||
fixedLength = -1;
|
||||
}
|
||||
arr = arr || [];
|
||||
offset = offset < 0 ? buf.length + offset : (offset === 0 ? 0 : offset || buf.position || 0);
|
||||
n = arr.length;
|
||||
if (fixedLength > 0 && fixedLength !== n) {
|
||||
if (fixedLength < n) {
|
||||
arr = arr.slice(0, fixedLength);
|
||||
} else {
|
||||
arr = arr.concat();
|
||||
arr.length = fixedLength;
|
||||
}
|
||||
n = fixedLength;
|
||||
}
|
||||
n = n << 2;
|
||||
buf.writeUInt16BE(n, offset);
|
||||
offset += 2;
|
||||
for (_i = 0, _len = arr.length; _i < _len; _i++) {
|
||||
i = arr[_i];
|
||||
buf.writeInt32BE(parseInt(i, 10) || 0, offset);
|
||||
offset += 4;
|
||||
}
|
||||
buf.position = offset;
|
||||
}
|
||||
};
|
||||
|
||||
}).call(this);
|
92
proxy/node_modules/bytearray/lib/test/bytearray_test.js
generated
vendored
Normal file
92
proxy/node_modules/bytearray/lib/test/bytearray_test.js
generated
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
// Generated by CoffeeScript 1.6.3
|
||||
(function() {
|
||||
var FIXTURE_UTF, FIXTURE_UTF_BUFF, FIXTURE_UTF_BYTE_LENGTH, FIXTURE_UTF_LENGTH, UNIT_ARR, VECTOR_UINT_1, VECTOR_UINT_STR_1, bytearray, should;
|
||||
|
||||
require('mocha');
|
||||
|
||||
should = require('should');
|
||||
|
||||
bytearray = require('../byteArray');
|
||||
|
||||
FIXTURE_UTF = "这个LED花洒有意思,@陈中 可建议 @吴海 在桔子酒店引入,";
|
||||
|
||||
FIXTURE_UTF_LENGTH = FIXTURE_UTF.length;
|
||||
|
||||
FIXTURE_UTF_BYTE_LENGTH = Buffer.byteLength(FIXTURE_UTF);
|
||||
|
||||
FIXTURE_UTF_BUFF = new Buffer(2 + FIXTURE_UTF_BYTE_LENGTH);
|
||||
|
||||
FIXTURE_UTF_BUFF.writeUInt16BE(FIXTURE_UTF_BYTE_LENGTH, 0);
|
||||
|
||||
FIXTURE_UTF_BUFF.write(FIXTURE_UTF, 2);
|
||||
|
||||
VECTOR_UINT_1 = [4196330, 4196812, 4198245, 4198550, 4196885, 4197941, 4197659, 4196640, 4196980, 4196368, 4196795, 4197527, 4196374, 4196672, 4197016, 4197661, 4197014, 4197449, 4197615, 4196330, 4196579, 4196714, 4196835, 4196808, 4196786, 4197947, 4196473, 4196646, 4197939, 4197928, 4196366, 4197926, 4197559, 4196333, 4198850, 4196840, 4197927, 4196511, 4197938, 4196812, 4197925, 4197526, 4196312, 4196804, 4197528, 4196682, 4196954, 4196409, 4196258, 4198177, 4196291, 4198245, 4198180, 4196216, 4198277, 4196263, 4198280, 4198276, 4198282, 4198201, 4198279, 4197004, 4198211, 4197011, 4196759, 4197097, 4196512, 4197018, 4198236, 4198304, 4196397, 4198237, 4198312, 4198198, 4198199, 4198259, 4198310, 4198305, 4197201, 4198160, 4198326, 4198189, 4197704, 4197257, 4198311, 4197475, 4198283, 4198222, 4196299, 4198250, 4198230, 4196996, 4198149, 4198315, 4197312, 4198327, 4199252, 4198181, 4198221, 4198316, 4198154, 4198244, 4196920, 4196943, 4198325, 4198320, 4196975, 4198249];
|
||||
|
||||
VECTOR_UINT_STR_1 = ["4196330", "4196812", "4198245", "4198550", "4196885", "4197941", "4197659", "4196640", "4196980", "4196368", "4196795", "4197527", "4196374", "4196672", "4197016", "4197661", "4197014", "4197449", "4197615", "4196330", "4196579", "4196714", "4196835", "4196808", "4196786", "4197947", "4196473", "4196646", "4197939", "4197928", "4196366", "4197926", "4197559", "4196333", "4198850", "4196840", "4197927", "4196511", "4197938", "4196812", "4197925", "4197526", "4196312", "4196804", "4197528", "4196682", "4196954", "4196409", "4196258", "4198177", "4196291", "4198245", "4198180", "4196216", "4198277", "4196263", "4198280", "4198276", "4198282", "4198201", "4198279", "4197004", "4198211", "4197011", "4196759", "4197097", "4196512", "4197018", "4198236", "4198304", "4196397", "4198237", "4198312", "4198198", "4198199", "4198259", "4198310", "4198305", "4197201", "4198160", "4198326", "4198189", "4197704", "4197257", "4198311", "4197475", "4198283", "4198222", "4196299", "4198250", "4198230", "4196996", "4198149", "4198315", "4197312", "4198327", "4199252", "4198181", "4198221", "4198316", "4198154", "4198244", "4196920", "4196943", "4198325", "4198320", "4196975", "4198249"];
|
||||
|
||||
UNIT_ARR = [1, 2, 3, 4, 5, 6, 0xfffffff1, 0xfffffff2];
|
||||
|
||||
describe('bytearray', function() {
|
||||
it('should read/write dynamic length utf correctly', function() {
|
||||
var buf;
|
||||
buf = new Buffer(2 + FIXTURE_UTF_BYTE_LENGTH);
|
||||
bytearray.writeUTF(buf, FIXTURE_UTF);
|
||||
buf.toString('hex').should.eql(FIXTURE_UTF_BUFF.toString('hex'));
|
||||
return bytearray.readUTF(buf, 0).should.eql(FIXTURE_UTF);
|
||||
});
|
||||
it('should conver utf string to buffer correctly', function() {
|
||||
var buf, byteLength, str;
|
||||
str = "中午侧阿凡达是否违反片假名ニホンゴ,罗马音nihon go 将( المنهج الواضح لتعل&#...";
|
||||
byteLength = Buffer.byteLength(str);
|
||||
buf = bytearray.utfStringToBuf(str);
|
||||
bytearray.readUnsignedShort(buf, 0).should.eql(byteLength);
|
||||
console.log("[bytearray_test::test utfStringToBuf] buf:" + (buf.toString('hex')));
|
||||
return buf.slice(2).toString('hex').should.eql((new Buffer(str)).toString('hex'));
|
||||
});
|
||||
it('should able to write/read an uint vector', function() {
|
||||
var arr, buf;
|
||||
buf = new Buffer(VECTOR_UINT_1.length * 4 + 2);
|
||||
bytearray.writeUnsignedIntArray(buf, VECTOR_UINT_1);
|
||||
arr = bytearray.readUnsignedIntArray(buf, 0);
|
||||
console.log("[bytearray_test::write/read an uint vector] arr:" + arr);
|
||||
return arr.join(',').should.eql(VECTOR_UINT_1.join(','));
|
||||
});
|
||||
it('should able to write/read an string vector as an uint vector', function() {
|
||||
var arr, buf;
|
||||
buf = new Buffer(VECTOR_UINT_STR_1.length * 4 + 2);
|
||||
bytearray.writeUnsignedIntArray(buf, VECTOR_UINT_STR_1);
|
||||
arr = bytearray.readUnsignedIntArray(buf, 0);
|
||||
console.log("[bytearray_test::write/read an uint vector] arr:" + arr);
|
||||
return arr.join(',').should.eql(VECTOR_UINT_1.join(','));
|
||||
});
|
||||
it('should read and write UTFBytes correctly', function() {
|
||||
var buf, buf2, byteLength, str;
|
||||
str = "hellow, how are you";
|
||||
byteLength = Buffer.byteLength(str);
|
||||
buf = new Buffer(byteLength);
|
||||
bytearray.writeUTFBytes(buf, str);
|
||||
buf2 = new Buffer(str);
|
||||
buf.toString('hex').should.equal(buf2.toString('hex'));
|
||||
buf.position.should.equal(byteLength);
|
||||
return bytearray.readUTFBytes(buf, byteLength, 0).should.equal(str);
|
||||
});
|
||||
return it('should read and write Float correctly', function() {
|
||||
var buf, i, orgin, readback, sample, _i, _j, _ref, _ref1, _results;
|
||||
sample = [321.324241, 0.323131, 4242.5435, 0.43242342];
|
||||
buf = new Buffer(sample.length * 4);
|
||||
for (i = _i = 0, _ref = sample.length; _i < _ref; i = _i += 1) {
|
||||
bytearray.writeFloat(buf, sample[i]);
|
||||
}
|
||||
buf.position = 0;
|
||||
_results = [];
|
||||
for (i = _j = 0, _ref1 = sample.length; _j < _ref1; i = _j += 1) {
|
||||
orgin = sample[i];
|
||||
readback = bytearray.readFloat(buf);
|
||||
console.log("[bytearray_test::Float test] orgin:" + orgin + ", readback:" + readback);
|
||||
_results.push(Math.abs(readback - orgin).should.below(0.01));
|
||||
}
|
||||
return _results;
|
||||
});
|
||||
});
|
||||
|
||||
}).call(this);
|
36
proxy/node_modules/bytearray/package.json
generated
vendored
Normal file
36
proxy/node_modules/bytearray/package.json
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "bytearray",
|
||||
"description": "a Node.JS module for Buffer processing exposes API similar to ByteArray of ActionScript",
|
||||
"version": "0.1.3",
|
||||
"homepage": "https://github.com/yi/node-bytearray",
|
||||
"author": {
|
||||
"name": "yi",
|
||||
"email": "yi2004@gmail.com"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/yi/node-bytearray.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/yi/node-bytearray/issues"
|
||||
},
|
||||
"licenses": [
|
||||
{
|
||||
"type": "MIT",
|
||||
"url": "https://github.com/yi/node-bytearray/blob/master/LICENSE-MIT"
|
||||
}
|
||||
],
|
||||
"main": "lib/bytearray",
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha tests/bytearray_test.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"chai": ">=1.2.0",
|
||||
"mocha": ">=1.3.2",
|
||||
"should": ">=1.1.0"
|
||||
},
|
||||
"keywords": ["buffer","buf","endian","actionscript","bytearray"]
|
||||
}
|
437
proxy/node_modules/bytearray/src/bytearray.coffee
generated
vendored
Normal file
437
proxy/node_modules/bytearray/src/bytearray.coffee
generated
vendored
Normal file
@ -0,0 +1,437 @@
|
||||
###
|
||||
# a collection of utility methods for Buffer
|
||||
#
|
||||
# 这个工具类的设计以实现两个目地
|
||||
# 1. 读写方法,匹配 Actionscript 的 ByteArray 读写方法
|
||||
# 2. ActionScript 的默认采用 big endian,这个工具方法,对此进行封装,以是外部不用关心 endian
|
||||
#
|
||||
###
|
||||
|
||||
module.exports =
|
||||
|
||||
# Reads a UTF-8 string from the byte stream. The string is assumed to be prefixed with an unsigned short indicating the length in bytes.
|
||||
# @param {Buff} buf
|
||||
# @param {int} [offset] optional, specify the offset where read should beging
|
||||
readUTF : (buf, offset)->
|
||||
return null unless Buffer.isBuffer buf
|
||||
offset = if offset < 0 then buf.length + offset else (if offset is 0 then 0 else offset || buf.position || 0)
|
||||
return null if buf.length <= offset + 2
|
||||
len = buf.readUInt16BE(offset)
|
||||
#console.log "[readUTF] buf.position:#{buf.position}, buf.length:#{buf.length}, offset:#{offset}, len:#{len} "
|
||||
return null if buf.length < len + offset
|
||||
offset += 2
|
||||
buf.position = offset + len
|
||||
return buf.toString 'utf8', offset, offset+len
|
||||
|
||||
# Reads a sequence of UTF-8 bytes specified by the length parameter from the byte stream and returns a string.
|
||||
# @param {Buff} buf
|
||||
# @param {uint} length, number of bytes to read
|
||||
# @param {int} [offset] optional, specify the offset where read should beging
|
||||
readUTFBytes : (buf, length, offset)->
|
||||
return null unless Buffer.isBuffer buf
|
||||
offset = if offset < 0 then buf.length + offset else (if offset is 0 then 0 else offset || buf.position || 0)
|
||||
return null if buf.length <= offset
|
||||
buf.position = offset + length
|
||||
#console.log "[bytearray::readUTFBytes] buf:#{buf}, offset:#{offset}"
|
||||
return buf.toString('utf8', offset, offset + length)
|
||||
|
||||
# @param {Buff} buf
|
||||
# @param {int} [offset] optional, specify the offset where read should beging
|
||||
readFixLengthASCII : (buf, offset) ->
|
||||
return null unless Buffer.isBuffer buf
|
||||
offset = if offset < 0 then buf.length + offset else (if offset is 0 then 0 else offset || buf.position || 0)
|
||||
return null if buf.length <= offset + 2
|
||||
len = buf.readUInt8(offset)
|
||||
return null if buf.length < len + offset
|
||||
offset += 1
|
||||
buf.position = offset + len
|
||||
buf.toString 'utf8', offset, offset+len
|
||||
|
||||
# Reads an unsigned 16-bit integer from the byte stream.
|
||||
# @param {Buff} buf
|
||||
# @param {int} [offset] optional, specify the offset where read should beging
|
||||
readUnsignedShort : (buf, offset)->
|
||||
return 0 unless Buffer.isBuffer buf
|
||||
offset = if offset < 0 then buf.length + offset else (if offset is 0 then 0 else offset || buf.position || 0)
|
||||
buf.position = offset + 2
|
||||
return buf.readUInt16BE offset
|
||||
|
||||
# Reads a 16-bit integer from the byte stream.
|
||||
# @param {Buff} buf
|
||||
# @param {int} [offset] optional, specify the offset where read should beging
|
||||
readShort : (buf, offset)->
|
||||
return 0 unless Buffer.isBuffer buf
|
||||
offset = if offset < 0 then buf.length + offset else (if offset is 0 then 0 else offset || buf.position || 0)
|
||||
buf.position = offset + 2
|
||||
buf.readInt16BE offset
|
||||
|
||||
# co-read to actionscript's ByteArray.readUnsignedByte
|
||||
# @param {Buff} buf
|
||||
# @param {int} [offset] optional, specify the offset where read should beging
|
||||
readUnsignedByte : (buf, offset)->
|
||||
return 0 unless Buffer.isBuffer buf
|
||||
offset = if offset < 0 then buf.length + offset else (if offset is 0 then 0 else offset || buf.position || 0)
|
||||
buf.position = offset + 1
|
||||
buf.readUInt8 offset
|
||||
|
||||
# Reads a byte from the byte stream.
|
||||
# @param {Buff} buf
|
||||
# @param {int} [offset] optional, specify the offset where read should beging
|
||||
readByte : (buf, offset)->
|
||||
return 0 unless Buffer.isBuffer buf
|
||||
offset = if offset < 0 then buf.length + offset else (if offset is 0 then 0 else offset || buf.position || 0)
|
||||
buf.position = offset + 1
|
||||
buf.readInt8 offset
|
||||
|
||||
# Reads an unsigned byte from the byte stream.
|
||||
# @param {Buff} buf
|
||||
# @param {int} [offset] optional, specify the offset where read should beging
|
||||
readUnsignedInt: (buf, offset)->
|
||||
return 0 unless Buffer.isBuffer buf
|
||||
offset = if offset < 0 then buf.length + offset else (if offset is 0 then 0 else offset || buf.position || 0)
|
||||
buf.position = offset + 4
|
||||
buf.readUInt32BE offset
|
||||
|
||||
# Reads a signed 32-bit integer from the byte stream.
|
||||
# @param {Buff} buf
|
||||
# @param {int} [offset] optional, specify the offset where read should beging
|
||||
readInt: (buf, offset)->
|
||||
return 0 unless Buffer.isBuffer buf
|
||||
offset = if offset < 0 then buf.length + offset else (if offset is 0 then 0 else offset || buf.position || 0)
|
||||
buf.position = offset + 4
|
||||
buf.readInt32BE offset
|
||||
|
||||
# Reads a signed 32-bit integer from the byte stream.
|
||||
# @param {Buff} buf
|
||||
# @param {int} [offset] optional, specify the offset where read should beging
|
||||
readFloat : (buf, offset)->
|
||||
return 0 unless Buffer.isBuffer buf
|
||||
offset = if offset < 0 then buf.length + offset else (if offset is 0 then 0 else offset || buf.position || 0)
|
||||
buf.position = offset + 4
|
||||
buf.readFloatLE offset
|
||||
# TODO:
|
||||
# this is a quick hack, should implement a proper endian swicher
|
||||
# ty 2013-10-08
|
||||
|
||||
|
||||
|
||||
# @param {Buff} buf
|
||||
# @param {int} [offset] optional, specify the offset where read should beging
|
||||
readUnsignedIntArray:(buf, offset)->
|
||||
offset = if offset < 0 then buf.length + offset else (if offset is 0 then 0 else offset || buf.position || 0)
|
||||
len = buf.readUInt16BE(offset) >>> 2 # *4 bytes for an int
|
||||
offset += 2
|
||||
arr = []
|
||||
if len is 0 or len > 1024
|
||||
buf.position = offset
|
||||
return arr
|
||||
while(len > 0)
|
||||
a = buf.readUInt32BE(offset)
|
||||
arr.push(a)
|
||||
offset += 4
|
||||
len -= 1
|
||||
buf.position = offset
|
||||
return arr
|
||||
|
||||
# @param {Buff} buf
|
||||
# @param {uint} value
|
||||
# @param {int} [offset] optional, specify the offset where read should beging
|
||||
writeUnsignedInt : (buf, value, offset) ->
|
||||
offset = if offset < 0 then buf.length + offset else (if offset is 0 then 0 else offset || buf.position || 0)
|
||||
#console.log "[msg] buf.length:#{buf.length}, offset:#{offset}"
|
||||
buf.writeUInt32BE value, offset
|
||||
buf.position = offset + 4
|
||||
return
|
||||
|
||||
# @param {Buff} buf
|
||||
# @param {int} value
|
||||
# @param {int} [offset] optional, specify the offset where read should beging
|
||||
writeInt : (buf, value, offset) ->
|
||||
offset = if offset < 0 then buf.length + offset else (if offset is 0 then 0 else offset || buf.position || 0)
|
||||
buf.writeInt32BE value, offset
|
||||
buf.position = offset + 4
|
||||
return
|
||||
|
||||
|
||||
# @param {Buff} buf
|
||||
# @param {int} value
|
||||
# @param {int} [offset] optional, specify the offset where read should beging
|
||||
writeFloat : (buf, value, offset) ->
|
||||
offset = if offset < 0 then buf.length + offset else (if offset is 0 then 0 else offset || buf.position || 0)
|
||||
buf.writeFloatLE value, offset
|
||||
# TODO:
|
||||
# this is a quick hack, should implement a proper endian swicher
|
||||
# ty 2013-10-08
|
||||
|
||||
buf.position = offset + 4
|
||||
return
|
||||
|
||||
|
||||
|
||||
|
||||
# @param {Buff} buf
|
||||
# @param {ushort} value
|
||||
# @param {int} [offset] optional, specify the offset where read should beging
|
||||
writeUnsignedShort: (buf, value, offset) ->
|
||||
offset = if offset < 0 then buf.length + offset else (if offset is 0 then 0 else offset || buf.position || 0)
|
||||
buf.writeUInt16BE value, offset
|
||||
buf.position = offset + 2
|
||||
return
|
||||
|
||||
# @param {Buff} buf
|
||||
# @param {short} value
|
||||
# @param {int} [offset] optional, specify the offset where read should beging
|
||||
writeShort: (buf, value, offset) ->
|
||||
offset = if offset < 0 then buf.length + offset else (if offset is 0 then 0 else offset || buf.position || 0)
|
||||
buf.writeInt16BE value, offset
|
||||
buf.position = offset + 2
|
||||
return
|
||||
|
||||
# @param {Buff} buf
|
||||
# @param {ubyte} value
|
||||
# @param {int} [offset] optional, specify the offset where read should beging
|
||||
writeUnsignedByte: (buf, value, offset) ->
|
||||
offset = if offset < 0 then buf.length + offset else (if offset is 0 then 0 else offset || buf.position || 0)
|
||||
buf.writeUInt8 value, offset
|
||||
buf.position = offset + 1
|
||||
return
|
||||
|
||||
# @param {Buff} buf
|
||||
# @param {byte} value
|
||||
# @param {int} [offset] optional, specify the offset where read should beging
|
||||
writeByte: (buf, value, offset) ->
|
||||
offset = if offset < 0 then buf.length + offset else (if offset is 0 then 0 else offset || buf.position || 0)
|
||||
buf.writeInt8 value, offset
|
||||
buf.position = offset + 1
|
||||
return
|
||||
|
||||
# @param {Buff} buf
|
||||
# @param {Boolean} value
|
||||
# @param {int} [offset] optional, specify the offset where read should beging
|
||||
writeBoolean: (buf, value, offset) ->
|
||||
offset = if offset < 0 then buf.length + offset else (if offset is 0 then 0 else offset || buf.position || 0)
|
||||
value = if value then 1 else 0
|
||||
buf.writeInt8 value, offset
|
||||
buf.position = offset + 1
|
||||
return
|
||||
|
||||
# 以 ASCII 方式在定长bytes中写入给定的字符串,并且保持 position 的连续
|
||||
# buf : 需要写入的 Buffer 实例
|
||||
# str : 需要写入的字符串
|
||||
# maxNumOfChar : 最多所写入的字符长度
|
||||
# offset : 从自定义的偏移处开始写
|
||||
writeFixLengthASCII : (buf, str, maxNumOfChar, offset) ->
|
||||
offset = if offset < 0 then buf.length + offset else (if offset is 0 then 0 else offset || buf.position || 0)
|
||||
buf.writeUInt8 maxNumOfChar, offset
|
||||
offset += 1 #+1 因为已经写了1byte的ascii 长度
|
||||
buf.fill(0x20, offset, offset + maxNumOfChar) # 整平这个目标buf
|
||||
buf.write str, offset, maxNumOfChar, 'ascii'
|
||||
buf.position = offset + maxNumOfChar
|
||||
return
|
||||
|
||||
# 以 UTF-8 方式在定长bytes中写入给定的字符串,并且保持 position 的连续
|
||||
# buf : 需要写入的 Buffer 实例
|
||||
# str : 需要写入的字符串
|
||||
# maxNumOfChar : 最多所写入的字符长度
|
||||
# offset : 从自定义的偏移处开始写
|
||||
writeFixLengthUTF: (buf, str, maxNumOfChar, offset) ->
|
||||
offset = if offset < 0 then buf.length + offset else (if offset is 0 then 0 else offset || buf.position || 0)
|
||||
maxNumOfChar *= 6 # 给每个 utf-8 char 预留 6 byte 的空间
|
||||
buf.writeUInt16BE maxNumOfChar, offset
|
||||
offset += 2 # +2 因为已经写了2byte的utf长度
|
||||
buf.fill(0x20, offset, offset + maxNumOfChar) # 整平这个目标buf
|
||||
buf.write str, offset, maxNumOfChar, 'utf8'
|
||||
buf.position = offset + maxNumOfChar
|
||||
return
|
||||
|
||||
# 以 UTF-8 方式在bytes中写入动态长度的字符串,并且保持 position 的连续
|
||||
# buf : 需要写入的 Buffer 实例
|
||||
# str : 需要写入的字符串
|
||||
# offset : 从自定义的偏移处开始写
|
||||
writeUTF: (buf, str, offset) ->
|
||||
offset = if offset < 0 then buf.length + offset else (if offset is 0 then 0 else offset || buf.position || 0)
|
||||
byteLength = Buffer.byteLength(str)
|
||||
buf.writeUInt16BE(byteLength , offset)
|
||||
offset += 2 # +2 因为已经写了2byte的utf长度
|
||||
buf.write(str, offset)
|
||||
buf.position = offset + byteLength
|
||||
return
|
||||
|
||||
# 以 UTF-8 方式在bytes中写入动态长度的字符串,并且保持 position 的连续
|
||||
# buf : 需要写入的 Buffer 实例
|
||||
# str : 需要写入的字符串
|
||||
# offset : 从自定义的偏移处开始写
|
||||
writeUTFBytes: (buf, str, offset) ->
|
||||
offset = if offset < 0 then buf.length + offset else (if offset is 0 then 0 else offset || buf.position || 0)
|
||||
buf.write(str, offset)
|
||||
buf.position = offset + Buffer.byteLength(str)
|
||||
return
|
||||
|
||||
# 以 UTF-8 方式在bytes中写入动态长度的字符串,并且保持 position 的连续
|
||||
# buf : 需要写入的 Buffer 实例
|
||||
# strArray : 需要写入的字符串数组
|
||||
# offset : 从自定义的偏移处开始写
|
||||
writeUTFArray:(buf,strArray,offset)->
|
||||
offset = if offset < 0 then buf.length + offset else (if offset is 0 then 0 else offset || buf.position || 0)
|
||||
unless strArray? and strArray.length>0
|
||||
buf.writeUInt16BE(0 , offset)
|
||||
buf.position=offset+2
|
||||
return
|
||||
|
||||
buf.writeUInt16BE(strArray.length , offset)
|
||||
offset += 2 # +2 因为已经写了2byte的utf长度
|
||||
for str in strArray
|
||||
byteLength = Buffer.byteLength(str)
|
||||
buf.writeUInt16BE(byteLength , offset)
|
||||
offset += 2 # +2 因为已经写了2byte的utf长度
|
||||
buf.write(str, offset)
|
||||
offset += byteLength
|
||||
buf.position=offset
|
||||
|
||||
|
||||
getByteLengthOfUTFArray:(strArray)->
|
||||
len=2
|
||||
return len unless strArray? and strArray.length>0
|
||||
for str in strArray
|
||||
len=len+2+Buffer.byteLength(str)
|
||||
return len
|
||||
|
||||
|
||||
# 以int 的方式写入一个数组
|
||||
# @param buf : 需要写入的 Buffer 实例
|
||||
# @param arr : 需要写入的数组
|
||||
# @param offset : 从自定义的偏移处开始写
|
||||
# @param fixedLength : 写入数组的给定长度内容
|
||||
writeUnsignedIntArray:(buf, arr, fixedLength = -1, offset)->
|
||||
arr = arr || [] # make sure argument arr is usable
|
||||
offset = if offset < 0 then buf.length + offset else (if offset is 0 then 0 else offset || buf.position || 0)
|
||||
n = arr.length
|
||||
if fixedLength > 0 and fixedLength isnt n
|
||||
# user require to write a fixed length of the given array
|
||||
if fixedLength < n
|
||||
arr = arr.slice(0, fixedLength)
|
||||
# NOTE 不能用 splice 因为会改变输入的array 的内容 arr.splice(fixedLength - n)
|
||||
else
|
||||
arr = arr.concat() # make a copy of the given arr
|
||||
arr.length = fixedLength
|
||||
n = fixedLength
|
||||
|
||||
n = n << 2 # *4 bytes for an int
|
||||
buf.writeUInt16BE(n, offset)
|
||||
offset += 2
|
||||
|
||||
for i in arr
|
||||
buf.writeUInt32BE( parseInt(i,10) || 0 , offset)
|
||||
offset += 4
|
||||
|
||||
buf.position = offset
|
||||
return
|
||||
|
||||
# 计算出给定的int数组要写入成二进制时所占的byte长度
|
||||
# @param {int[]} arr an integer array
|
||||
getByteLengthOfIntArray : (arr) ->
|
||||
(arr.length << 2) + 2
|
||||
|
||||
|
||||
# 以 short 的方式写入一个数组
|
||||
# @param buf : 需要写入的 Buffer 实例
|
||||
# @param arr : 需要写入的数组
|
||||
# @param offset : 从自定义的偏移处开始写
|
||||
# @param fixedLength : 写入数组的给定长度内容
|
||||
writeUnsignedShortArray:(buf, arr, fixedLength = -1, offset)->
|
||||
#console.log "[offset 1]:#{offset}"
|
||||
arr = arr || [] # make sure argument arr is usable
|
||||
offset = if offset < 0 then buf.length + offset else (if offset is 0 then 0 else offset || buf.position || 0)
|
||||
#console.log "[offset 2]:#{offset}"
|
||||
n = arr.length
|
||||
if fixedLength > 0 and fixedLength isnt n
|
||||
# user require to write a fixed length of the given array
|
||||
if fixedLength < n
|
||||
arr = arr.slice(0, fixedLength)
|
||||
# NOTE 不能用 splice 因为会改变输入的array 的内容 arr.splice(fixedLength - n)
|
||||
else
|
||||
arr = arr.concat() # make a copy of the given arr
|
||||
arr.length = fixedLength
|
||||
n = fixedLength
|
||||
|
||||
n = n << 1 # * 2 bytes for a short
|
||||
#console.log "[offset]:#{offset}"
|
||||
buf.writeUInt16BE(n, offset)
|
||||
offset += 2
|
||||
|
||||
for i in arr
|
||||
buf.writeUInt16BE( parseInt(i, 10) || 0 , offset)
|
||||
offset += 2
|
||||
|
||||
buf.position = offset
|
||||
return
|
||||
|
||||
# 计算一个 buf 从当前的 position 开始还有多少byte 可以读取
|
||||
getBytesAvailable : (buf) ->
|
||||
return if buf? then buf.length - (buf.position || 0) else 0
|
||||
|
||||
# 从给定的buf的当前position位置,复制出给定length的byte片段,并且推进buf的position属性
|
||||
scrap : (buf, length) ->
|
||||
return null unless buf? and length > 0
|
||||
offset = (buf.position || 0)
|
||||
return null if length + offset > buf.length
|
||||
result = new Buffer(length)
|
||||
buf.copy(result, 0, offset, offset + length)
|
||||
buf.position = offset + length
|
||||
return result
|
||||
|
||||
# 复制一个和给定的 buf 完全一样的新buf
|
||||
duplicate : (buf) ->
|
||||
n = buf.length || 0
|
||||
return null if n is 0
|
||||
result = new Buffer(n)
|
||||
buf.copy result, 0, 0, n
|
||||
return result
|
||||
|
||||
# convert an input str to buffer by utf8 encoding, and add byte length by a short at the begine of the buffer
|
||||
utfStringToBuf : (str) ->
|
||||
str = String(str || '')
|
||||
n = Buffer.byteLength(str, 'utf8')
|
||||
buf = new Buffer(n+2)
|
||||
buf.writeUInt16BE(n,0)
|
||||
buf.write(str, 2)
|
||||
return buf
|
||||
|
||||
#是buf并且buf length >0
|
||||
isAvailableBuf:(buf)->
|
||||
return Buffer.isBuffer(buf) and buf.length>0
|
||||
|
||||
# 以int 的方式写入一个数组
|
||||
# @param buf : 需要写入的 Buffer 实例
|
||||
# @param arr : 需要写入的数组
|
||||
# @param offset : 从自定义的偏移处开始写
|
||||
# @param fixedLength : 写入数组的给定长度内容
|
||||
writeIntArray:(buf, arr, fixedLength = -1, offset)->
|
||||
arr = arr || [] # make sure argument arr is usable
|
||||
offset = if offset < 0 then buf.length + offset else (if offset is 0 then 0 else offset || buf.position || 0)
|
||||
n = arr.length
|
||||
if fixedLength > 0 and fixedLength isnt n
|
||||
# user require to write a fixed length of the given array
|
||||
if fixedLength < n
|
||||
arr = arr.slice(0, fixedLength)
|
||||
# NOTE 不能用 splice 因为会改变输入的array 的内容 arr.splice(fixedLength - n)
|
||||
else
|
||||
arr = arr.concat() # make a copy of the given arr
|
||||
arr.length = fixedLength
|
||||
n = fixedLength
|
||||
|
||||
n = n << 2 # *4 bytes for an int
|
||||
buf.writeUInt16BE(n, offset)
|
||||
offset += 2
|
||||
|
||||
for i in arr
|
||||
buf.writeInt32BE( parseInt(i,10) || 0 , offset)
|
||||
offset += 4
|
||||
|
||||
buf.position = offset
|
||||
return
|
||||
|
||||
|
||||
|
||||
|
||||
|
86
proxy/node_modules/bytearray/src/test/bytearray_test.coffee
generated
vendored
Normal file
86
proxy/node_modules/bytearray/src/test/bytearray_test.coffee
generated
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
|
||||
require 'mocha'
|
||||
should = require 'should'
|
||||
|
||||
bytearray = require '../byteArray'
|
||||
|
||||
FIXTURE_UTF = "这个LED花洒有意思,@陈中 可建议 @吴海 在桔子酒店引入,"
|
||||
FIXTURE_UTF_LENGTH = FIXTURE_UTF.length
|
||||
FIXTURE_UTF_BYTE_LENGTH = Buffer.byteLength(FIXTURE_UTF)
|
||||
FIXTURE_UTF_BUFF = new Buffer(2 + FIXTURE_UTF_BYTE_LENGTH)
|
||||
FIXTURE_UTF_BUFF.writeUInt16BE( FIXTURE_UTF_BYTE_LENGTH, 0)
|
||||
FIXTURE_UTF_BUFF.write(FIXTURE_UTF, 2)
|
||||
|
||||
|
||||
VECTOR_UINT_1 = [4196330,4196812,4198245,4198550,4196885,4197941,4197659,4196640,4196980,4196368,4196795,4197527,4196374,4196672,4197016,4197661,4197014,4197449,4197615,4196330,4196579,4196714,4196835,4196808,4196786,4197947,4196473,4196646,4197939,4197928,4196366,4197926,4197559,4196333,4198850,4196840,4197927,4196511,4197938,4196812,4197925,4197526,4196312,4196804,4197528,4196682,4196954,4196409,4196258,4198177,4196291,4198245,4198180,4196216,4198277,4196263,4198280,4198276,4198282,4198201,4198279,4197004,4198211,4197011,4196759,4197097,4196512,4197018,4198236,4198304,4196397,4198237,4198312,4198198,4198199,4198259,4198310,4198305,4197201,4198160,4198326,4198189,4197704,4197257,4198311,4197475,4198283,4198222,4196299,4198250,4198230,4196996,4198149,4198315,4197312,4198327,4199252,4198181,4198221,4198316,4198154,4198244,4196920,4196943,4198325,4198320,4196975,4198249]
|
||||
|
||||
VECTOR_UINT_STR_1 = ["4196330","4196812","4198245","4198550","4196885","4197941","4197659","4196640","4196980","4196368","4196795","4197527","4196374","4196672","4197016","4197661","4197014","4197449","4197615","4196330","4196579","4196714","4196835","4196808","4196786","4197947","4196473","4196646","4197939","4197928","4196366","4197926","4197559","4196333","4198850","4196840","4197927","4196511","4197938","4196812","4197925","4197526","4196312","4196804","4197528","4196682","4196954","4196409","4196258","4198177","4196291","4198245","4198180","4196216","4198277","4196263","4198280","4198276","4198282","4198201","4198279","4197004","4198211","4197011","4196759","4197097","4196512","4197018","4198236","4198304","4196397","4198237","4198312","4198198","4198199","4198259","4198310","4198305","4197201","4198160","4198326","4198189","4197704","4197257","4198311","4197475","4198283","4198222","4196299","4198250","4198230","4196996","4198149","4198315","4197312","4198327","4199252","4198181","4198221","4198316","4198154","4198244","4196920","4196943","4198325","4198320","4196975","4198249"]
|
||||
|
||||
|
||||
UNIT_ARR = [1,2,3,4,5,6,0xfffffff1, 0xfffffff2]
|
||||
|
||||
describe 'bytearray', ->
|
||||
|
||||
it 'should read/write dynamic length utf correctly', ->
|
||||
buf = new Buffer(2 + FIXTURE_UTF_BYTE_LENGTH)
|
||||
bytearray.writeUTF(buf, FIXTURE_UTF)
|
||||
#console.log "[bytearray_test::] buf:#{buf.toString('hex')}"
|
||||
buf.toString('hex').should.eql(FIXTURE_UTF_BUFF.toString('hex'))
|
||||
#console.log "[bytearray_test::] bytearray.readUTF(buf, 0):#{bytearray.readUTF(buf, 0)}"
|
||||
bytearray.readUTF(buf, 0).should.eql(FIXTURE_UTF)
|
||||
|
||||
it 'should conver utf string to buffer correctly', ->
|
||||
str = "中午侧阿凡达是否违反片假名ニホンゴ,罗马音nihon go 将( المنهج الواضح لتعل&#..."
|
||||
byteLength = Buffer.byteLength(str)
|
||||
buf = bytearray.utfStringToBuf(str)
|
||||
bytearray.readUnsignedShort(buf,0).should.eql(byteLength)
|
||||
console.log "[bytearray_test::test utfStringToBuf] buf:#{buf.toString('hex')}"
|
||||
buf.slice(2).toString('hex').should.eql((new Buffer(str)).toString('hex'))
|
||||
|
||||
it 'should able to write/read an uint vector', ->
|
||||
buf = new Buffer(VECTOR_UINT_1.length * 4 + 2)
|
||||
bytearray.writeUnsignedIntArray(buf, VECTOR_UINT_1)
|
||||
arr = bytearray.readUnsignedIntArray(buf, 0)
|
||||
console.log "[bytearray_test::write/read an uint vector] arr:#{arr}"
|
||||
arr.join(',').should.eql(VECTOR_UINT_1.join(','))
|
||||
|
||||
it 'should able to write/read an string vector as an uint vector', ->
|
||||
buf = new Buffer(VECTOR_UINT_STR_1.length * 4 + 2)
|
||||
bytearray.writeUnsignedIntArray(buf, VECTOR_UINT_STR_1)
|
||||
arr = bytearray.readUnsignedIntArray(buf, 0)
|
||||
console.log "[bytearray_test::write/read an uint vector] arr:#{arr}"
|
||||
arr.join(',').should.eql(VECTOR_UINT_1.join(','))
|
||||
|
||||
it 'should read and write UTFBytes correctly' , ->
|
||||
str = "hellow, how are you"
|
||||
byteLength = Buffer.byteLength(str)
|
||||
buf = new Buffer byteLength
|
||||
bytearray.writeUTFBytes buf, str
|
||||
buf2 = new Buffer str
|
||||
buf.toString('hex').should.equal(buf2.toString('hex'))
|
||||
buf.position.should.equal(byteLength)
|
||||
bytearray.readUTFBytes(buf, byteLength, 0).should.equal str
|
||||
|
||||
it 'should read and write Float correctly' , ->
|
||||
sample = [321.324241, 0.323131, 4242.5435, 0.43242342]
|
||||
buf = new Buffer sample.length * 4
|
||||
for i in [0...sample.length] by 1
|
||||
bytearray.writeFloat buf, sample[i]
|
||||
|
||||
buf.position = 0
|
||||
|
||||
for i in [0...sample.length] by 1
|
||||
orgin = sample[i]
|
||||
readback = bytearray.readFloat(buf)
|
||||
console.log "[bytearray_test::Float test] orgin:#{orgin}, readback:#{readback}"
|
||||
Math.abs(readback - orgin).should.below(0.01)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
24
proxy/package-lock.json
generated
Normal file
24
proxy/package-lock.json
generated
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "proxy",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "proxy",
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"bytearray": "^0.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/bytearray": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/bytearray/-/bytearray-0.1.3.tgz",
|
||||
"integrity": "sha512-oEKhhGYMfEdfnp4yViXVeauXLLYLj0hs8cQpJmu0JXbhuVX1iTeVmZ2IW4QtXhBcZitzOZ6pYNRvMDJRl5/0og==",
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
15
proxy/package.json
Normal file
15
proxy/package.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "proxy",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"bytearray": "^0.1.3"
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user