project firt import
This commit is contained in:
commit
0636568859
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
.vs
|
||||
.vscode
|
||||
dist
|
52
app/main.js
Normal file
52
app/main.js
Normal file
@ -0,0 +1,52 @@
|
||||
const electron = require('electron');
|
||||
// Module to control application life.
|
||||
const {app} = electron;
|
||||
// Module to create native browser window.
|
||||
const {BrowserWindow} = electron;
|
||||
|
||||
// Keep a global reference of the window object, if you don't, the window will
|
||||
// be closed automatically when the JavaScript object is garbage collected.
|
||||
let win;
|
||||
|
||||
function createWindow() {
|
||||
// Create the browser window.
|
||||
win = new BrowserWindow({width: 1200, height: 800,webPreferences: {
|
||||
nodeIntegration: true
|
||||
}});
|
||||
|
||||
// and load the index.html of the app.
|
||||
win.loadURL("http://127.0.0.1:12345/index.html");
|
||||
|
||||
// Open the DevTools.
|
||||
win.webContents.openDevTools();
|
||||
|
||||
// Emitted when the window is closed.
|
||||
win.on('closed', () => {
|
||||
// Dereference the window object, usually you would store windows
|
||||
// in an array if your app supports multi windows, this is the time
|
||||
// when you should delete the corresponding element.
|
||||
win = null;
|
||||
});
|
||||
}
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.on('ready', createWindow);
|
||||
|
||||
// Quit when all windows are closed.
|
||||
app.on('window-all-closed', () => {
|
||||
// On OS X it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
|
||||
app.on('activate', () => {
|
||||
// On OS X it's common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (win === null) {
|
||||
createWindow();
|
||||
}
|
||||
});
|
5
app/package.json
Normal file
5
app/package.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"name" : "H5工具",
|
||||
"version" : "0.1.0",
|
||||
"main" : "main.js"
|
||||
}
|
379
client/PBMessageUtils.ts
Normal file
379
client/PBMessageUtils.ts
Normal file
@ -0,0 +1,379 @@
|
||||
module junyou {
|
||||
|
||||
const LITTLE_ENDIAN = egret.Endian.LITTLE_ENDIAN;
|
||||
const TYPE_DOUBLE: number = 1;
|
||||
const TYPE_FLOAT: number = 2;
|
||||
const TYPE_INT64: number = 3;
|
||||
const TYPE_UINT64: number = 4;
|
||||
const TYPE_INT32: number = 5;
|
||||
const TYPE_FIXED64: number = 6;
|
||||
const TYPE_FIXED32: number = 7;
|
||||
const TYPE_BOOL: number = 8;
|
||||
const TYPE_STRING: number = 9;
|
||||
const TYPE_GROUP: number = 10;
|
||||
const TYPE_MESSAGE: number = 11;
|
||||
const TYPE_BYTES: number = 12;
|
||||
const TYPE_UINT32: number = 13;
|
||||
const TYPE_ENUM: number = 14;
|
||||
const TYPE_SFIXED32: number = 15;
|
||||
const TYPE_SFIXED64: number = 16;
|
||||
const TYPE_SINT32: number = 17;
|
||||
const TYPE_SINT64: number = 18;
|
||||
/**
|
||||
0 必有 属性名字
|
||||
1 必有 required optional repeated
|
||||
2 必有 数据类型
|
||||
3 可选 消息类型名称
|
||||
4 可选 默认值
|
||||
*/
|
||||
declare type MessageStruct =
|
||||
[/**0 */string, /**1 */number,/**2 */number] |
|
||||
[/**属性名字 */string, /**选项 */number,/**数据类型 */number,/**如果是子消息,消息名称 */string] |
|
||||
[/**属性名字 */string, /**选项 */number,/**数据类型 */number,/**如果是子消息,消息名称 */string, /**默认值 */any]
|
||||
/**
|
||||
*
|
||||
* @author 3tion
|
||||
* javascript 只会使用到 varint32->number string boolean
|
||||
*
|
||||
*/
|
||||
export class PBMessageUtils {
|
||||
|
||||
/**
|
||||
*
|
||||
* 根据message名字得到的结构数据
|
||||
* @static
|
||||
* @type
|
||||
*/
|
||||
public static structByName: { /**消息名称*/[index: string]:
|
||||
{
|
||||
/**索引 */
|
||||
[index: number]:
|
||||
|
||||
MessageStruct
|
||||
}
|
||||
} = {};
|
||||
|
||||
/**
|
||||
*
|
||||
* 根据message名字绑定的类名,用于读取消息时创建的对象
|
||||
* 如果没有注册,则直接使用{}创建对象
|
||||
* @static
|
||||
* @type {{ [index: string]: { new () } }}
|
||||
*/
|
||||
public static ctorByName: { [index: string]: { new () } } = {};
|
||||
|
||||
public static readFrom(msgType: string, bytes: ByteArray, len?: number): Object {
|
||||
let ctor = PBMessageUtils.ctorByName[msgType];
|
||||
let msg = ctor ? new ctor : {};
|
||||
if (len === undefined) len = -1;
|
||||
let afterLen = 0;
|
||||
if (len > -1) {
|
||||
afterLen = bytes.bytesAvailable - len;
|
||||
}
|
||||
let encode = PBMessageUtils.structByName[msgType];
|
||||
if (!encode) {
|
||||
ThrowError(`非法的通信类型[${msgType}],堆栈信息:${new Error()}`);
|
||||
return;
|
||||
}
|
||||
//检查处理默认值
|
||||
for (let idx in encode) {
|
||||
let body = encode[idx];
|
||||
//0 key
|
||||
//1 required optional repeated
|
||||
//2 数据类型
|
||||
//3 Message
|
||||
//4 默认值
|
||||
if (4 in body) {//有默认值
|
||||
let key = body[0];
|
||||
//消息中没有对应key的数据,先赋值成默认值,等待后续处理
|
||||
if (!(key in msg)) {
|
||||
msg[key] = body[4];
|
||||
}
|
||||
}
|
||||
}
|
||||
while (bytes.bytesAvailable > afterLen) {
|
||||
let tag = bytes.readVarint();
|
||||
if (tag == 0)
|
||||
continue;
|
||||
let idx = tag >>> 3;
|
||||
let body = encode[idx];
|
||||
if (!body) {
|
||||
ThrowError(`读取消息类型为:${msgType},索引${idx}时数据出现错误,找不到对应的数据结构配置`);
|
||||
return;
|
||||
}
|
||||
let name = body[0];
|
||||
let label = body[1];
|
||||
let type = body[2];
|
||||
let subMsgType = body[3];
|
||||
let value: Object;
|
||||
if (label != 3 || (tag & 0b111) != 7) {//自定义 tag & 0b111 == 7 为 数组中 undefined的情况
|
||||
switch (type) {
|
||||
case TYPE_DOUBLE:
|
||||
value = bytes.readDouble();
|
||||
break;
|
||||
case TYPE_FLOAT:
|
||||
value = bytes.readFloat();
|
||||
break;
|
||||
case TYPE_INT64:
|
||||
case TYPE_UINT64:
|
||||
case TYPE_SINT64:
|
||||
value = bytes.readVarint64();//理论上项目不使用
|
||||
break;
|
||||
case TYPE_INT32:
|
||||
case TYPE_SINT32:
|
||||
value = PBMessageUtils.decodeZigzag32(bytes.readVarint());
|
||||
break;
|
||||
case TYPE_UINT32:
|
||||
case TYPE_ENUM:
|
||||
value = bytes.readVarint();
|
||||
break;
|
||||
case TYPE_FIXED64:
|
||||
case TYPE_SFIXED64:
|
||||
value = PBMessageUtils.readFix64(bytes);//理论上项目不使用
|
||||
break;
|
||||
case TYPE_FIXED32:
|
||||
value = bytes.readUnsignedInt();
|
||||
break;
|
||||
case TYPE_BOOL:
|
||||
value = PBMessageUtils.readBoolean(bytes);
|
||||
break;
|
||||
case TYPE_STRING:
|
||||
value = PBMessageUtils.readString(bytes);
|
||||
break;
|
||||
case TYPE_GROUP://(protobuf 已弃用)
|
||||
value = undefined;
|
||||
ThrowError(`读取消息类型为:${msgType},索引${idx}时数据出现已弃用的GROUP分组类型(${TYPE_GROUP})`);
|
||||
break;
|
||||
case TYPE_MESSAGE://消息
|
||||
value = PBMessageUtils.readMessage(bytes, subMsgType);
|
||||
break;
|
||||
case TYPE_BYTES:
|
||||
value = PBMessageUtils.readBytes(bytes);
|
||||
break;
|
||||
case TYPE_SFIXED32:
|
||||
value = bytes.readInt();
|
||||
break;
|
||||
default:
|
||||
value = PBMessageUtils.readValue(tag, bytes);
|
||||
}
|
||||
}
|
||||
if (label == 3) {//repeated
|
||||
let arr = msg[name];
|
||||
if (!arr) msg[name] = arr = [];
|
||||
arr.push(value);
|
||||
}
|
||||
else {
|
||||
msg[name] = value;
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
private static readValue(tag: number, bytes: ByteArray): any {
|
||||
let wireType: number = tag & 7;
|
||||
let value: any;
|
||||
switch (wireType) {
|
||||
case 0: //Varint int32, int64, uint32, uint64, sint32, sint64, bool, enum
|
||||
value = bytes.readVarint();
|
||||
break;
|
||||
case 2: //Length-delimi string, bytes, embedded messages, packed repeated fields
|
||||
value = PBMessageUtils.readString(bytes);
|
||||
break;
|
||||
case 5: //32-bit fixed32, sfixed32, float
|
||||
value = bytes.readInt();
|
||||
break;
|
||||
case 1: //64-bit fixed64, sfixed64, double
|
||||
value = bytes.readDouble();
|
||||
break;
|
||||
//case 3://Start group Groups (deprecated)
|
||||
//break;
|
||||
//case 4://End group Groups (deprecated)
|
||||
//break;
|
||||
default:
|
||||
ThrowError("protobuf的wireType未知");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
private static readFix64(bytes: ByteArray): Object {
|
||||
let v: Int64 = new Int64;
|
||||
v.low = bytes.readUnsignedInt();
|
||||
v.high = bytes.readUnsignedInt();
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
private static readBoolean(bytes: ByteArray): Object {
|
||||
return bytes.readVarint() > 0;
|
||||
}
|
||||
|
||||
private static readString(bytes: ByteArray): Object {
|
||||
let blen: number = bytes.readVarint();
|
||||
if (blen > 0) {
|
||||
return bytes.readUTFBytes(blen);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* 读取消息
|
||||
* @private
|
||||
* @static
|
||||
* @param {number} tag 标签
|
||||
* @param {ByteArray} bytes 被处理的字节数组
|
||||
* @param {string} subMsgType 类型标识
|
||||
* @returns {Object}
|
||||
*/
|
||||
private static readMessage(bytes: ByteArray, msgType: string): Object {
|
||||
let blen: number = bytes.readVarint();
|
||||
return PBMessageUtils.readFrom(msgType, bytes, blen);
|
||||
}
|
||||
|
||||
private static readBytes(bytes: ByteArray): Object {
|
||||
let blen: number = bytes.readVarint();
|
||||
return bytes.readByteArray(blen);
|
||||
}
|
||||
|
||||
public static writeTo(msg: Object, msgType: string, bytes?: ByteArray): ByteArray {
|
||||
if (msg == undefined) {
|
||||
return;
|
||||
}
|
||||
let messageEncode = PBMessageUtils.structByName[msgType];// msg.mMessageEncode;
|
||||
if (!messageEncode) {
|
||||
ThrowError(`非法的通信类型[${msgType}],堆栈信息:${new Error()}`);
|
||||
return;
|
||||
}
|
||||
if (!bytes) {
|
||||
bytes = new ByteArray;
|
||||
}
|
||||
// bytes.endian = LITTLE_ENDIAN;
|
||||
for (let numberStr in messageEncode) {
|
||||
let num = +numberStr;
|
||||
let body = messageEncode[num];
|
||||
let label = body[1];
|
||||
let name = body[0];
|
||||
if (label == 1 && !(name in msg)) {
|
||||
continue;
|
||||
}
|
||||
let value: Object = msg[name];
|
||||
if (value == undefined || value === body[4]/* 默认值 */) {
|
||||
continue;
|
||||
}
|
||||
let type = body[2];
|
||||
let subMsgType = body[3];
|
||||
let wireType = PBMessageUtils.type2WireType(type);
|
||||
let tag = (num << 3) | wireType;
|
||||
if (label == 3) {
|
||||
for (let key in value) {
|
||||
let element = value[key];
|
||||
// 针对repeated中无法处理空的占位数组做处理,Protobuf 2 中不支持undefined进行占位 由于 wireType 只使用 0 1 2 3 4 5
|
||||
// 现在使用 7 作为 undefined 占位使用
|
||||
PBMessageUtils.writeElementTo(element, type, element == undefined ? ((num << 3) | 7) : tag, bytes, subMsgType);
|
||||
}
|
||||
}
|
||||
else {
|
||||
PBMessageUtils.writeElementTo(value, type, tag, bytes, subMsgType);
|
||||
}
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static writeElementTo(value: any, type: number, tag: number, bytes: ByteArray, subMsgType?: string): void {
|
||||
bytes.writeVarint(tag);
|
||||
switch (type) {
|
||||
case TYPE_FIXED32:
|
||||
bytes.writeUnsignedInt(value as number);
|
||||
break;
|
||||
case TYPE_SFIXED32:
|
||||
bytes.writeInt(value as number);
|
||||
break;
|
||||
case TYPE_FLOAT:
|
||||
bytes.writeFloat(value as number);
|
||||
break;
|
||||
case TYPE_DOUBLE:
|
||||
case TYPE_FIXED64:
|
||||
case TYPE_SFIXED64:
|
||||
bytes.writeDouble(value as number);
|
||||
break;
|
||||
case TYPE_INT32://int32处理负数,没有按规定的 10字节数据进行处理,直接使用SINT32处理
|
||||
// Signed Integers
|
||||
// As you saw in the previous section, all the protocol buffer types associated with wire type 0 are encoded as varints. However, there is an important difference between the signed int types (sint32 and sint64) and the "standard" int types (int32 and int64) when it comes to encoding negative numbers. If you use int32 or int64 as the type for a negative number, the resulting varint is always ten bytes long – it is, effectively, treated like a very large unsigned integer. If you use one of the signed types, the resulting varint uses ZigZag encoding, which is much more efficient.
|
||||
case TYPE_SINT32:
|
||||
bytes.writeVarint(PBMessageUtils.zigzag32(value as number));
|
||||
break;
|
||||
case TYPE_ENUM:
|
||||
case TYPE_UINT32:
|
||||
bytes.writeVarint(value as number);
|
||||
break;
|
||||
case TYPE_INT64:
|
||||
case TYPE_SINT64:
|
||||
case TYPE_UINT64:
|
||||
bytes.writeVarint64(value as Int64);
|
||||
break;
|
||||
case TYPE_BOOL:
|
||||
bytes.writeVarint(value ? 1 : 0);
|
||||
break;
|
||||
case TYPE_STRING:
|
||||
case TYPE_BYTES:
|
||||
case TYPE_MESSAGE:
|
||||
if (type == TYPE_MESSAGE) {
|
||||
var temp: ByteArray = PBMessageUtils.writeTo(value, subMsgType);
|
||||
}
|
||||
else if (type == TYPE_BYTES) {
|
||||
temp = value as ByteArray;
|
||||
}
|
||||
else {
|
||||
temp = new ByteArray;
|
||||
temp.writeUTFBytes(value as string);
|
||||
}
|
||||
length = temp ? temp.length : 0;
|
||||
bytes.writeVarint(length);
|
||||
if (length > 0) {
|
||||
bytes.writeBytes(temp, 0, length);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static type2WireType(type: number): number {
|
||||
switch (type) {
|
||||
case TYPE_FIXED32:
|
||||
case TYPE_SFIXED32:
|
||||
case TYPE_FLOAT:
|
||||
return 5;
|
||||
case TYPE_DOUBLE:
|
||||
case TYPE_FIXED64:
|
||||
case TYPE_SFIXED64:
|
||||
return 1;
|
||||
case TYPE_INT32:
|
||||
case TYPE_SINT32:
|
||||
case TYPE_ENUM:
|
||||
case TYPE_UINT32:
|
||||
case TYPE_INT64:
|
||||
case TYPE_SINT64:
|
||||
case TYPE_UINT64:
|
||||
case TYPE_BOOL:
|
||||
return 0;
|
||||
case TYPE_STRING:
|
||||
case TYPE_MESSAGE:
|
||||
case TYPE_BYTES:
|
||||
return 2;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
public static zigzag32(n: number) {
|
||||
return (n << 1) ^ (n >> 31);
|
||||
}
|
||||
|
||||
public static decodeZigzag32(n: number) {
|
||||
return n >> 1 ^ (((n & 1) << 31) >> 31);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
5
copy.bat
Normal file
5
copy.bat
Normal file
@ -0,0 +1,5 @@
|
||||
echo 开始copy
|
||||
|
||||
robocopy .\dist ..\..\release\protocal /MIR
|
||||
|
||||
pause
|
15
package.json
Normal file
15
package.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "prototools",
|
||||
"version": "0.0.1",
|
||||
"description": "wiki上定义的前后端通信指令,自动生成前端代码",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "electron ."
|
||||
},
|
||||
"author": "null",
|
||||
"license": "ISC",
|
||||
"directories": {
|
||||
"test": "test"
|
||||
}
|
||||
}
|
12
proto/as3options.proto
Normal file
12
proto/as3options.proto
Normal file
@ -0,0 +1,12 @@
|
||||
package as3;
|
||||
import "google/protobuf/descriptor.proto";
|
||||
extend google.protobuf.FileOptions{
|
||||
optional string f_package = 50000;
|
||||
}
|
||||
extend google.protobuf.MessageOptions{
|
||||
optional string m_package = 50000;
|
||||
repeated int32 m_cmd = 50001;
|
||||
}
|
||||
extend google.protobuf.EnumOptions{
|
||||
optional string e_package = 50000;
|
||||
}
|
19
proto/external-common.proto
Normal file
19
proto/external-common.proto
Normal file
@ -0,0 +1,19 @@
|
||||
package com.junyou.common.protocol;
|
||||
import "as3options.proto";
|
||||
option (as3.f_package) = "huaqiangu.login";
|
||||
message ServerInfoVO{
|
||||
option (as3.m_package) = "huaqiangu.login";
|
||||
required int64 serverOpenTime=1;//服务器开服时间
|
||||
optional int64 serverTime=2;//服务器当前时间
|
||||
optional string serverVersion=3;//服务器版本
|
||||
repeated int64 serverMergeTime=4;//服务器合服时间
|
||||
repeated int32 serverOffsetTime=5;//服务器时区偏移量(单位:分钟)
|
||||
}
|
||||
message ChooseRoleVO{
|
||||
option (as3.m_package) = "huaqiangu.login";
|
||||
required int32 configId=1;//配置id
|
||||
required int64 guid=2;//唯一标识
|
||||
required string name=3;//名字
|
||||
required int32 level=4;//等级
|
||||
required int32 roleType=5;//角色类型,0普通用户,1是GM,2新手指导员,3是VIP专员
|
||||
}
|
62
proto/external.proto
Normal file
62
proto/external.proto
Normal file
@ -0,0 +1,62 @@
|
||||
package com.junyou.common.protocol;
|
||||
import "as3options.proto";
|
||||
import "external-common.proto";
|
||||
|
||||
//登录
|
||||
message Login_C2S{
|
||||
option (as3.m_package) = "huaqiangu.login";
|
||||
option (as3.m_cmd) = 2000;
|
||||
option (as3.m_cmd) = 2001;
|
||||
required string platformAccount=1;//平台用户账号
|
||||
required string roleCreateGlobalServerId=2;//玩家角色创建的全局服务器id
|
||||
required bool chenmi=3;//该用户是否需要开启防沉迷
|
||||
required string sign=4;//验证字符串 md5 以及时间戳,拼在一起
|
||||
required bool weiduan=5;//是否使用登录器登录true为用登录器登录,false为没有用登录器登录的
|
||||
optional string parameter=6;//服务器需要的其他参数
|
||||
}
|
||||
//登录成功
|
||||
message LoginSuccess_S2C{
|
||||
option (as3.m_package) = "huaqiangu.login";
|
||||
required int32 retStatus=1;
|
||||
optional ServerInfoVO serverInfo=2;
|
||||
optional ChooseRoleVO roleVO=3;//数据为空 标示没有角色,客户端发送创建角色指令
|
||||
optional int64 chenmiTime=4;//防沉迷时间
|
||||
optional string clientIp=5;//客户端IP
|
||||
}
|
||||
//登录失败
|
||||
message LoginFail_S2C{
|
||||
option (as3.m_package) = "huaqiangu.login";
|
||||
required int32 retStatus=1;
|
||||
required int32 msgCode=2;
|
||||
repeated string parameter=3;//code相关参数
|
||||
}
|
||||
//创建角色并进入游戏
|
||||
message CreateRole_C2S{
|
||||
option (as3.m_package) = "huaqiangu.login";
|
||||
required string name=1;//角色名字
|
||||
required int32 configId=2;//角色配置ID
|
||||
required bool autoCreate=3;//true:自动创号玩家,false:正常玩家,默认是false:正常玩家
|
||||
}
|
||||
//创建角色并进入游戏成功
|
||||
message CreateRoleSuccess_S2C{
|
||||
option (as3.m_package) = "huaqiangu.login";
|
||||
required int32 retStatus=1;
|
||||
optional ChooseRoleVO roleVO=2;
|
||||
}
|
||||
//创建角色并进入游戏失败
|
||||
message CreateRoleFail_S2C{
|
||||
option (as3.m_package) = "huaqiangu.login";
|
||||
required int32 retStatus=1;
|
||||
optional int32 msgCode=2;//错误码
|
||||
}
|
||||
//服务端主动断开(需要状态)
|
||||
message KickRole_S2C{
|
||||
option (as3.m_package) = "huaqiangu.server";
|
||||
required int32 retStatus=1;
|
||||
optional string parameter=2;//参数
|
||||
}
|
||||
//服务器端通知指定时间开始停机
|
||||
message ServerStopNotice_S2C{
|
||||
option (as3.m_package) = "huaqiangu.server";
|
||||
required int64 stopTime=1;//开始停机时间戳,给的时间戳会小于真实开始的时间
|
||||
}
|
779
proto/google/protobuf/descriptor.proto
Normal file
779
proto/google/protobuf/descriptor.proto
Normal file
@ -0,0 +1,779 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
//
|
||||
// The messages in this file describe the definitions found in .proto files.
|
||||
// A valid .proto file can be translated directly to a FileDescriptorProto
|
||||
// without any other information (e.g. without reading its imports).
|
||||
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
package google.protobuf;
|
||||
option go_package = "descriptor";
|
||||
option java_package = "com.google.protobuf";
|
||||
option java_outer_classname = "DescriptorProtos";
|
||||
option csharp_namespace = "Google.Protobuf.Reflection";
|
||||
option objc_class_prefix = "GPB";
|
||||
|
||||
// descriptor.proto must be optimized for speed because reflection-based
|
||||
// algorithms don't work during bootstrapping.
|
||||
option optimize_for = SPEED;
|
||||
|
||||
// The protocol compiler can output a FileDescriptorSet containing the .proto
|
||||
// files it parses.
|
||||
message FileDescriptorSet {
|
||||
repeated FileDescriptorProto file = 1;
|
||||
}
|
||||
|
||||
// Describes a complete .proto file.
|
||||
message FileDescriptorProto {
|
||||
optional string name = 1; // file name, relative to root of source tree
|
||||
optional string package = 2; // e.g. "foo", "foo.bar", etc.
|
||||
|
||||
// Names of files imported by this file.
|
||||
repeated string dependency = 3;
|
||||
// Indexes of the public imported files in the dependency list above.
|
||||
repeated int32 public_dependency = 10;
|
||||
// Indexes of the weak imported files in the dependency list.
|
||||
// For Google-internal migration only. Do not use.
|
||||
repeated int32 weak_dependency = 11;
|
||||
|
||||
// All top-level definitions in this file.
|
||||
repeated DescriptorProto message_type = 4;
|
||||
repeated EnumDescriptorProto enum_type = 5;
|
||||
repeated ServiceDescriptorProto service = 6;
|
||||
repeated FieldDescriptorProto extension = 7;
|
||||
|
||||
optional FileOptions options = 8;
|
||||
|
||||
// This field contains optional information about the original source code.
|
||||
// You may safely remove this entire field without harming runtime
|
||||
// functionality of the descriptors -- the information is needed only by
|
||||
// development tools.
|
||||
optional SourceCodeInfo source_code_info = 9;
|
||||
|
||||
// The syntax of the proto file.
|
||||
// The supported values are "proto2" and "proto3".
|
||||
optional string syntax = 12;
|
||||
}
|
||||
|
||||
// Describes a message type.
|
||||
message DescriptorProto {
|
||||
optional string name = 1;
|
||||
|
||||
repeated FieldDescriptorProto field = 2;
|
||||
repeated FieldDescriptorProto extension = 6;
|
||||
|
||||
repeated DescriptorProto nested_type = 3;
|
||||
repeated EnumDescriptorProto enum_type = 4;
|
||||
|
||||
message ExtensionRange {
|
||||
optional int32 start = 1;
|
||||
optional int32 end = 2;
|
||||
}
|
||||
repeated ExtensionRange extension_range = 5;
|
||||
|
||||
repeated OneofDescriptorProto oneof_decl = 8;
|
||||
|
||||
optional MessageOptions options = 7;
|
||||
|
||||
// Range of reserved tag numbers. Reserved tag numbers may not be used by
|
||||
// fields or extension ranges in the same message. Reserved ranges may
|
||||
// not overlap.
|
||||
message ReservedRange {
|
||||
optional int32 start = 1; // Inclusive.
|
||||
optional int32 end = 2; // Exclusive.
|
||||
}
|
||||
repeated ReservedRange reserved_range = 9;
|
||||
// Reserved field names, which may not be used by fields in the same message.
|
||||
// A given name may only be reserved once.
|
||||
repeated string reserved_name = 10;
|
||||
}
|
||||
|
||||
// Describes a field within a message.
|
||||
message FieldDescriptorProto {
|
||||
enum Type {
|
||||
// 0 is reserved for errors.
|
||||
// Order is weird for historical reasons.
|
||||
TYPE_DOUBLE = 1;
|
||||
TYPE_FLOAT = 2;
|
||||
// Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if
|
||||
// negative values are likely.
|
||||
TYPE_INT64 = 3;
|
||||
TYPE_UINT64 = 4;
|
||||
// Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if
|
||||
// negative values are likely.
|
||||
TYPE_INT32 = 5;
|
||||
TYPE_FIXED64 = 6;
|
||||
TYPE_FIXED32 = 7;
|
||||
TYPE_BOOL = 8;
|
||||
TYPE_STRING = 9;
|
||||
TYPE_GROUP = 10; // Tag-delimited aggregate.
|
||||
TYPE_MESSAGE = 11; // Length-delimited aggregate.
|
||||
|
||||
// New in version 2.
|
||||
TYPE_BYTES = 12;
|
||||
TYPE_UINT32 = 13;
|
||||
TYPE_ENUM = 14;
|
||||
TYPE_SFIXED32 = 15;
|
||||
TYPE_SFIXED64 = 16;
|
||||
TYPE_SINT32 = 17; // Uses ZigZag encoding.
|
||||
TYPE_SINT64 = 18; // Uses ZigZag encoding.
|
||||
};
|
||||
|
||||
enum Label {
|
||||
// 0 is reserved for errors
|
||||
LABEL_OPTIONAL = 1;
|
||||
LABEL_REQUIRED = 2;
|
||||
LABEL_REPEATED = 3;
|
||||
// TODO(sanjay): Should we add LABEL_MAP?
|
||||
};
|
||||
|
||||
optional string name = 1;
|
||||
optional int32 number = 3;
|
||||
optional Label label = 4;
|
||||
|
||||
// If type_name is set, this need not be set. If both this and type_name
|
||||
// are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP.
|
||||
optional Type type = 5;
|
||||
|
||||
// For message and enum types, this is the name of the type. If the name
|
||||
// starts with a '.', it is fully-qualified. Otherwise, C++-like scoping
|
||||
// rules are used to find the type (i.e. first the nested types within this
|
||||
// message are searched, then within the parent, on up to the root
|
||||
// namespace).
|
||||
optional string type_name = 6;
|
||||
|
||||
// For extensions, this is the name of the type being extended. It is
|
||||
// resolved in the same manner as type_name.
|
||||
optional string extendee = 2;
|
||||
|
||||
// For numeric types, contains the original text representation of the value.
|
||||
// For booleans, "true" or "false".
|
||||
// For strings, contains the default text contents (not escaped in any way).
|
||||
// For bytes, contains the C escaped value. All bytes >= 128 are escaped.
|
||||
// TODO(kenton): Base-64 encode?
|
||||
optional string default_value = 7;
|
||||
|
||||
// If set, gives the index of a oneof in the containing type's oneof_decl
|
||||
// list. This field is a member of that oneof.
|
||||
optional int32 oneof_index = 9;
|
||||
|
||||
// JSON name of this field. The value is set by protocol compiler. If the
|
||||
// user has set a "json_name" option on this field, that option's value
|
||||
// will be used. Otherwise, it's deduced from the field's name by converting
|
||||
// it to camelCase.
|
||||
optional string json_name = 10;
|
||||
|
||||
optional FieldOptions options = 8;
|
||||
}
|
||||
|
||||
// Describes a oneof.
|
||||
message OneofDescriptorProto {
|
||||
optional string name = 1;
|
||||
}
|
||||
|
||||
// Describes an enum type.
|
||||
message EnumDescriptorProto {
|
||||
optional string name = 1;
|
||||
|
||||
repeated EnumValueDescriptorProto value = 2;
|
||||
|
||||
optional EnumOptions options = 3;
|
||||
}
|
||||
|
||||
// Describes a value within an enum.
|
||||
message EnumValueDescriptorProto {
|
||||
optional string name = 1;
|
||||
optional int32 number = 2;
|
||||
|
||||
optional EnumValueOptions options = 3;
|
||||
}
|
||||
|
||||
// Describes a service.
|
||||
message ServiceDescriptorProto {
|
||||
optional string name = 1;
|
||||
repeated MethodDescriptorProto method = 2;
|
||||
|
||||
optional ServiceOptions options = 3;
|
||||
}
|
||||
|
||||
// Describes a method of a service.
|
||||
message MethodDescriptorProto {
|
||||
optional string name = 1;
|
||||
|
||||
// Input and output type names. These are resolved in the same way as
|
||||
// FieldDescriptorProto.type_name, but must refer to a message type.
|
||||
optional string input_type = 2;
|
||||
optional string output_type = 3;
|
||||
|
||||
optional MethodOptions options = 4;
|
||||
|
||||
// Identifies if client streams multiple client messages
|
||||
optional bool client_streaming = 5 [default=false];
|
||||
// Identifies if server streams multiple server messages
|
||||
optional bool server_streaming = 6 [default=false];
|
||||
}
|
||||
|
||||
|
||||
// ===================================================================
|
||||
// Options
|
||||
|
||||
// Each of the definitions above may have "options" attached. These are
|
||||
// just annotations which may cause code to be generated slightly differently
|
||||
// or may contain hints for code that manipulates protocol messages.
|
||||
//
|
||||
// Clients may define custom options as extensions of the *Options messages.
|
||||
// These extensions may not yet be known at parsing time, so the parser cannot
|
||||
// store the values in them. Instead it stores them in a field in the *Options
|
||||
// message called uninterpreted_option. This field must have the same name
|
||||
// across all *Options messages. We then use this field to populate the
|
||||
// extensions when we build a descriptor, at which point all protos have been
|
||||
// parsed and so all extensions are known.
|
||||
//
|
||||
// Extension numbers for custom options may be chosen as follows:
|
||||
// * For options which will only be used within a single application or
|
||||
// organization, or for experimental options, use field numbers 50000
|
||||
// through 99999. It is up to you to ensure that you do not use the
|
||||
// same number for multiple options.
|
||||
// * For options which will be published and used publicly by multiple
|
||||
// independent entities, e-mail protobuf-global-extension-registry@google.com
|
||||
// to reserve extension numbers. Simply provide your project name (e.g.
|
||||
// Objective-C plugin) and your project website (if available) -- there's no
|
||||
// need to explain how you intend to use them. Usually you only need one
|
||||
// extension number. You can declare multiple options with only one extension
|
||||
// number by putting them in a sub-message. See the Custom Options section of
|
||||
// the docs for examples:
|
||||
// https://developers.google.com/protocol-buffers/docs/proto#options
|
||||
// If this turns out to be popular, a web service will be set up
|
||||
// to automatically assign option numbers.
|
||||
|
||||
|
||||
message FileOptions {
|
||||
|
||||
// Sets the Java package where classes generated from this .proto will be
|
||||
// placed. By default, the proto package is used, but this is often
|
||||
// inappropriate because proto packages do not normally start with backwards
|
||||
// domain names.
|
||||
optional string java_package = 1;
|
||||
|
||||
|
||||
// If set, all the classes from the .proto file are wrapped in a single
|
||||
// outer class with the given name. This applies to both Proto1
|
||||
// (equivalent to the old "--one_java_file" option) and Proto2 (where
|
||||
// a .proto always translates to a single class, but you may want to
|
||||
// explicitly choose the class name).
|
||||
optional string java_outer_classname = 8;
|
||||
|
||||
// If set true, then the Java code generator will generate a separate .java
|
||||
// file for each top-level message, enum, and service defined in the .proto
|
||||
// file. Thus, these types will *not* be nested inside the outer class
|
||||
// named by java_outer_classname. However, the outer class will still be
|
||||
// generated to contain the file's getDescriptor() method as well as any
|
||||
// top-level extensions defined in the file.
|
||||
optional bool java_multiple_files = 10 [default=false];
|
||||
|
||||
// If set true, then the Java code generator will generate equals() and
|
||||
// hashCode() methods for all messages defined in the .proto file.
|
||||
// This increases generated code size, potentially substantially for large
|
||||
// protos, which may harm a memory-constrained application.
|
||||
// - In the full runtime this is a speed optimization, as the
|
||||
// AbstractMessage base class includes reflection-based implementations of
|
||||
// these methods.
|
||||
// - In the lite runtime, setting this option changes the semantics of
|
||||
// equals() and hashCode() to more closely match those of the full runtime;
|
||||
// the generated methods compute their results based on field values rather
|
||||
// than object identity. (Implementations should not assume that hashcodes
|
||||
// will be consistent across runtimes or versions of the protocol compiler.)
|
||||
optional bool java_generate_equals_and_hash = 20 [default=false];
|
||||
|
||||
// If set true, then the Java2 code generator will generate code that
|
||||
// throws an exception whenever an attempt is made to assign a non-UTF-8
|
||||
// byte sequence to a string field.
|
||||
// Message reflection will do the same.
|
||||
// However, an extension field still accepts non-UTF-8 byte sequences.
|
||||
// This option has no effect on when used with the lite runtime.
|
||||
optional bool java_string_check_utf8 = 27 [default=false];
|
||||
|
||||
|
||||
// Generated classes can be optimized for speed or code size.
|
||||
enum OptimizeMode {
|
||||
SPEED = 1; // Generate complete code for parsing, serialization,
|
||||
// etc.
|
||||
CODE_SIZE = 2; // Use ReflectionOps to implement these methods.
|
||||
LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime.
|
||||
}
|
||||
optional OptimizeMode optimize_for = 9 [default=SPEED];
|
||||
|
||||
// Sets the Go package where structs generated from this .proto will be
|
||||
// placed. If omitted, the Go package will be derived from the following:
|
||||
// - The basename of the package import path, if provided.
|
||||
// - Otherwise, the package statement in the .proto file, if present.
|
||||
// - Otherwise, the basename of the .proto file, without extension.
|
||||
optional string go_package = 11;
|
||||
|
||||
|
||||
|
||||
// Should generic services be generated in each language? "Generic" services
|
||||
// are not specific to any particular RPC system. They are generated by the
|
||||
// main code generators in each language (without additional plugins).
|
||||
// Generic services were the only kind of service generation supported by
|
||||
// early versions of google.protobuf.
|
||||
//
|
||||
// Generic services are now considered deprecated in favor of using plugins
|
||||
// that generate code specific to your particular RPC system. Therefore,
|
||||
// these default to false. Old code which depends on generic services should
|
||||
// explicitly set them to true.
|
||||
optional bool cc_generic_services = 16 [default=false];
|
||||
optional bool java_generic_services = 17 [default=false];
|
||||
optional bool py_generic_services = 18 [default=false];
|
||||
|
||||
// Is this file deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for everything in the file, or it will be completely ignored; in the very
|
||||
// least, this is a formalization for deprecating files.
|
||||
optional bool deprecated = 23 [default=false];
|
||||
|
||||
// Enables the use of arenas for the proto messages in this file. This applies
|
||||
// only to generated classes for C++.
|
||||
optional bool cc_enable_arenas = 31 [default=false];
|
||||
|
||||
|
||||
// Sets the objective c class prefix which is prepended to all objective c
|
||||
// generated classes from this .proto. There is no default.
|
||||
optional string objc_class_prefix = 36;
|
||||
|
||||
// Namespace for generated classes; defaults to the package.
|
||||
optional string csharp_namespace = 37;
|
||||
|
||||
// Whether the nano proto compiler should generate in the deprecated non-nano
|
||||
// suffixed package.
|
||||
optional bool javanano_use_deprecated_package = 38;
|
||||
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
message MessageOptions {
|
||||
// Set true to use the old proto1 MessageSet wire format for extensions.
|
||||
// This is provided for backwards-compatibility with the MessageSet wire
|
||||
// format. You should not use this for any other reason: It's less
|
||||
// efficient, has fewer features, and is more complicated.
|
||||
//
|
||||
// The message must be defined exactly as follows:
|
||||
// message Foo {
|
||||
// option message_set_wire_format = true;
|
||||
// extensions 4 to max;
|
||||
// }
|
||||
// Note that the message cannot have any defined fields; MessageSets only
|
||||
// have extensions.
|
||||
//
|
||||
// All extensions of your type must be singular messages; e.g. they cannot
|
||||
// be int32s, enums, or repeated messages.
|
||||
//
|
||||
// Because this is an option, the above two restrictions are not enforced by
|
||||
// the protocol compiler.
|
||||
optional bool message_set_wire_format = 1 [default=false];
|
||||
|
||||
// Disables the generation of the standard "descriptor()" accessor, which can
|
||||
// conflict with a field of the same name. This is meant to make migration
|
||||
// from proto1 easier; new code should avoid fields named "descriptor".
|
||||
optional bool no_standard_descriptor_accessor = 2 [default=false];
|
||||
|
||||
// Is this message deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for the message, or it will be completely ignored; in the very least,
|
||||
// this is a formalization for deprecating messages.
|
||||
optional bool deprecated = 3 [default=false];
|
||||
|
||||
// Whether the message is an automatically generated map entry type for the
|
||||
// maps field.
|
||||
//
|
||||
// For maps fields:
|
||||
// map<KeyType, ValueType> map_field = 1;
|
||||
// The parsed descriptor looks like:
|
||||
// message MapFieldEntry {
|
||||
// option map_entry = true;
|
||||
// optional KeyType key = 1;
|
||||
// optional ValueType value = 2;
|
||||
// }
|
||||
// repeated MapFieldEntry map_field = 1;
|
||||
//
|
||||
// Implementations may choose not to generate the map_entry=true message, but
|
||||
// use a native map in the target language to hold the keys and values.
|
||||
// The reflection APIs in such implementions still need to work as
|
||||
// if the field is a repeated message field.
|
||||
//
|
||||
// NOTE: Do not set the option in .proto files. Always use the maps syntax
|
||||
// instead. The option should only be implicitly set by the proto compiler
|
||||
// parser.
|
||||
optional bool map_entry = 7;
|
||||
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
message FieldOptions {
|
||||
// The ctype option instructs the C++ code generator to use a different
|
||||
// representation of the field than it normally would. See the specific
|
||||
// options below. This option is not yet implemented in the open source
|
||||
// release -- sorry, we'll try to include it in a future version!
|
||||
optional CType ctype = 1 [default = STRING];
|
||||
enum CType {
|
||||
// Default mode.
|
||||
STRING = 0;
|
||||
|
||||
CORD = 1;
|
||||
|
||||
STRING_PIECE = 2;
|
||||
}
|
||||
// The packed option can be enabled for repeated primitive fields to enable
|
||||
// a more efficient representation on the wire. Rather than repeatedly
|
||||
// writing the tag and type for each element, the entire array is encoded as
|
||||
// a single length-delimited blob. In proto3, only explicit setting it to
|
||||
// false will avoid using packed encoding.
|
||||
optional bool packed = 2;
|
||||
|
||||
|
||||
// The jstype option determines the JavaScript type used for values of the
|
||||
// field. The option is permitted only for 64 bit integral and fixed types
|
||||
// (int64, uint64, sint64, fixed64, sfixed64). By default these types are
|
||||
// represented as JavaScript strings. This avoids loss of precision that can
|
||||
// happen when a large value is converted to a floating point JavaScript
|
||||
// numbers. Specifying JS_NUMBER for the jstype causes the generated
|
||||
// JavaScript code to use the JavaScript "number" type instead of strings.
|
||||
// This option is an enum to permit additional types to be added,
|
||||
// e.g. goog.math.Integer.
|
||||
optional JSType jstype = 6 [default = JS_NORMAL];
|
||||
enum JSType {
|
||||
// Use the default type.
|
||||
JS_NORMAL = 0;
|
||||
|
||||
// Use JavaScript strings.
|
||||
JS_STRING = 1;
|
||||
|
||||
// Use JavaScript numbers.
|
||||
JS_NUMBER = 2;
|
||||
}
|
||||
|
||||
// Should this field be parsed lazily? Lazy applies only to message-type
|
||||
// fields. It means that when the outer message is initially parsed, the
|
||||
// inner message's contents will not be parsed but instead stored in encoded
|
||||
// form. The inner message will actually be parsed when it is first accessed.
|
||||
//
|
||||
// This is only a hint. Implementations are free to choose whether to use
|
||||
// eager or lazy parsing regardless of the value of this option. However,
|
||||
// setting this option true suggests that the protocol author believes that
|
||||
// using lazy parsing on this field is worth the additional bookkeeping
|
||||
// overhead typically needed to implement it.
|
||||
//
|
||||
// This option does not affect the public interface of any generated code;
|
||||
// all method signatures remain the same. Furthermore, thread-safety of the
|
||||
// interface is not affected by this option; const methods remain safe to
|
||||
// call from multiple threads concurrently, while non-const methods continue
|
||||
// to require exclusive access.
|
||||
//
|
||||
//
|
||||
// Note that implementations may choose not to check required fields within
|
||||
// a lazy sub-message. That is, calling IsInitialized() on the outher message
|
||||
// may return true even if the inner message has missing required fields.
|
||||
// This is necessary because otherwise the inner message would have to be
|
||||
// parsed in order to perform the check, defeating the purpose of lazy
|
||||
// parsing. An implementation which chooses not to check required fields
|
||||
// must be consistent about it. That is, for any particular sub-message, the
|
||||
// implementation must either *always* check its required fields, or *never*
|
||||
// check its required fields, regardless of whether or not the message has
|
||||
// been parsed.
|
||||
optional bool lazy = 5 [default=false];
|
||||
|
||||
// Is this field deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for accessors, or it will be completely ignored; in the very least, this
|
||||
// is a formalization for deprecating fields.
|
||||
optional bool deprecated = 3 [default=false];
|
||||
|
||||
// For Google-internal migration only. Do not use.
|
||||
optional bool weak = 10 [default=false];
|
||||
|
||||
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
message EnumOptions {
|
||||
|
||||
// Set this option to true to allow mapping different tag names to the same
|
||||
// value.
|
||||
optional bool allow_alias = 2;
|
||||
|
||||
// Is this enum deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for the enum, or it will be completely ignored; in the very least, this
|
||||
// is a formalization for deprecating enums.
|
||||
optional bool deprecated = 3 [default=false];
|
||||
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
message EnumValueOptions {
|
||||
// Is this enum value deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for the enum value, or it will be completely ignored; in the very least,
|
||||
// this is a formalization for deprecating enum values.
|
||||
optional bool deprecated = 1 [default=false];
|
||||
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
message ServiceOptions {
|
||||
|
||||
// Note: Field numbers 1 through 32 are reserved for Google's internal RPC
|
||||
// framework. We apologize for hoarding these numbers to ourselves, but
|
||||
// we were already using them long before we decided to release Protocol
|
||||
// Buffers.
|
||||
|
||||
// Is this service deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for the service, or it will be completely ignored; in the very least,
|
||||
// this is a formalization for deprecating services.
|
||||
optional bool deprecated = 33 [default=false];
|
||||
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
message MethodOptions {
|
||||
|
||||
// Note: Field numbers 1 through 32 are reserved for Google's internal RPC
|
||||
// framework. We apologize for hoarding these numbers to ourselves, but
|
||||
// we were already using them long before we decided to release Protocol
|
||||
// Buffers.
|
||||
|
||||
// Is this method deprecated?
|
||||
// Depending on the target platform, this can emit Deprecated annotations
|
||||
// for the method, or it will be completely ignored; in the very least,
|
||||
// this is a formalization for deprecating methods.
|
||||
optional bool deprecated = 33 [default=false];
|
||||
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
// Clients can define custom options in extensions of this message. See above.
|
||||
extensions 1000 to max;
|
||||
}
|
||||
|
||||
|
||||
// A message representing a option the parser does not recognize. This only
|
||||
// appears in options protos created by the compiler::Parser class.
|
||||
// DescriptorPool resolves these when building Descriptor objects. Therefore,
|
||||
// options protos in descriptor objects (e.g. returned by Descriptor::options(),
|
||||
// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions
|
||||
// in them.
|
||||
message UninterpretedOption {
|
||||
// The name of the uninterpreted option. Each string represents a segment in
|
||||
// a dot-separated name. is_extension is true iff a segment represents an
|
||||
// extension (denoted with parentheses in options specs in .proto files).
|
||||
// E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents
|
||||
// "foo.(bar.baz).qux".
|
||||
message NamePart {
|
||||
required string name_part = 1;
|
||||
required bool is_extension = 2;
|
||||
}
|
||||
repeated NamePart name = 2;
|
||||
|
||||
// The value of the uninterpreted option, in whatever type the tokenizer
|
||||
// identified it as during parsing. Exactly one of these should be set.
|
||||
optional string identifier_value = 3;
|
||||
optional uint64 positive_int_value = 4;
|
||||
optional int64 negative_int_value = 5;
|
||||
optional double double_value = 6;
|
||||
optional bytes string_value = 7;
|
||||
optional string aggregate_value = 8;
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// Optional source code info
|
||||
|
||||
// Encapsulates information about the original source file from which a
|
||||
// FileDescriptorProto was generated.
|
||||
message SourceCodeInfo {
|
||||
// A Location identifies a piece of source code in a .proto file which
|
||||
// corresponds to a particular definition. This information is intended
|
||||
// to be useful to IDEs, code indexers, documentation generators, and similar
|
||||
// tools.
|
||||
//
|
||||
// For example, say we have a file like:
|
||||
// message Foo {
|
||||
// optional string foo = 1;
|
||||
// }
|
||||
// Let's look at just the field definition:
|
||||
// optional string foo = 1;
|
||||
// ^ ^^ ^^ ^ ^^^
|
||||
// a bc de f ghi
|
||||
// We have the following locations:
|
||||
// span path represents
|
||||
// [a,i) [ 4, 0, 2, 0 ] The whole field definition.
|
||||
// [a,b) [ 4, 0, 2, 0, 4 ] The label (optional).
|
||||
// [c,d) [ 4, 0, 2, 0, 5 ] The type (string).
|
||||
// [e,f) [ 4, 0, 2, 0, 1 ] The name (foo).
|
||||
// [g,h) [ 4, 0, 2, 0, 3 ] The number (1).
|
||||
//
|
||||
// Notes:
|
||||
// - A location may refer to a repeated field itself (i.e. not to any
|
||||
// particular index within it). This is used whenever a set of elements are
|
||||
// logically enclosed in a single code segment. For example, an entire
|
||||
// extend block (possibly containing multiple extension definitions) will
|
||||
// have an outer location whose path refers to the "extensions" repeated
|
||||
// field without an index.
|
||||
// - Multiple locations may have the same path. This happens when a single
|
||||
// logical declaration is spread out across multiple places. The most
|
||||
// obvious example is the "extend" block again -- there may be multiple
|
||||
// extend blocks in the same scope, each of which will have the same path.
|
||||
// - A location's span is not always a subset of its parent's span. For
|
||||
// example, the "extendee" of an extension declaration appears at the
|
||||
// beginning of the "extend" block and is shared by all extensions within
|
||||
// the block.
|
||||
// - Just because a location's span is a subset of some other location's span
|
||||
// does not mean that it is a descendent. For example, a "group" defines
|
||||
// both a type and a field in a single declaration. Thus, the locations
|
||||
// corresponding to the type and field and their components will overlap.
|
||||
// - Code which tries to interpret locations should probably be designed to
|
||||
// ignore those that it doesn't understand, as more types of locations could
|
||||
// be recorded in the future.
|
||||
repeated Location location = 1;
|
||||
message Location {
|
||||
// Identifies which part of the FileDescriptorProto was defined at this
|
||||
// location.
|
||||
//
|
||||
// Each element is a field number or an index. They form a path from
|
||||
// the root FileDescriptorProto to the place where the definition. For
|
||||
// example, this path:
|
||||
// [ 4, 3, 2, 7, 1 ]
|
||||
// refers to:
|
||||
// file.message_type(3) // 4, 3
|
||||
// .field(7) // 2, 7
|
||||
// .name() // 1
|
||||
// This is because FileDescriptorProto.message_type has field number 4:
|
||||
// repeated DescriptorProto message_type = 4;
|
||||
// and DescriptorProto.field has field number 2:
|
||||
// repeated FieldDescriptorProto field = 2;
|
||||
// and FieldDescriptorProto.name has field number 1:
|
||||
// optional string name = 1;
|
||||
//
|
||||
// Thus, the above path gives the location of a field name. If we removed
|
||||
// the last element:
|
||||
// [ 4, 3, 2, 7 ]
|
||||
// this path refers to the whole field declaration (from the beginning
|
||||
// of the label to the terminating semicolon).
|
||||
repeated int32 path = 1 [packed=true];
|
||||
|
||||
// Always has exactly three or four elements: start line, start column,
|
||||
// end line (optional, otherwise assumed same as start line), end column.
|
||||
// These are packed into a single field for efficiency. Note that line
|
||||
// and column numbers are zero-based -- typically you will want to add
|
||||
// 1 to each before displaying to a user.
|
||||
repeated int32 span = 2 [packed=true];
|
||||
|
||||
// If this SourceCodeInfo represents a complete declaration, these are any
|
||||
// comments appearing before and after the declaration which appear to be
|
||||
// attached to the declaration.
|
||||
//
|
||||
// A series of line comments appearing on consecutive lines, with no other
|
||||
// tokens appearing on those lines, will be treated as a single comment.
|
||||
//
|
||||
// leading_detached_comments will keep paragraphs of comments that appear
|
||||
// before (but not connected to) the current element. Each paragraph,
|
||||
// separated by empty lines, will be one comment element in the repeated
|
||||
// field.
|
||||
//
|
||||
// Only the comment content is provided; comment markers (e.g. //) are
|
||||
// stripped out. For block comments, leading whitespace and an asterisk
|
||||
// will be stripped from the beginning of each line other than the first.
|
||||
// Newlines are included in the output.
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// optional int32 foo = 1; // Comment attached to foo.
|
||||
// // Comment attached to bar.
|
||||
// optional int32 bar = 2;
|
||||
//
|
||||
// optional string baz = 3;
|
||||
// // Comment attached to baz.
|
||||
// // Another line attached to baz.
|
||||
//
|
||||
// // Comment attached to qux.
|
||||
// //
|
||||
// // Another line attached to qux.
|
||||
// optional double qux = 4;
|
||||
//
|
||||
// // Detached comment for corge. This is not leading or trailing comments
|
||||
// // to qux or corge because there are blank lines separating it from
|
||||
// // both.
|
||||
//
|
||||
// // Detached comment for corge paragraph 2.
|
||||
//
|
||||
// optional string corge = 5;
|
||||
// /* Block comment attached
|
||||
// * to corge. Leading asterisks
|
||||
// * will be removed. */
|
||||
// /* Block comment attached to
|
||||
// * grault. */
|
||||
// optional int32 grault = 6;
|
||||
//
|
||||
// // ignored detached comments.
|
||||
optional string leading_comments = 3;
|
||||
optional string trailing_comments = 4;
|
||||
repeated string leading_detached_comments = 6;
|
||||
}
|
||||
}
|
571
proto/java/com/test/lalala/Msg.java
Normal file
571
proto/java/com/test/lalala/Msg.java
Normal file
@ -0,0 +1,571 @@
|
||||
// Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
// source: msg.proto
|
||||
|
||||
package com.test.lalala;
|
||||
|
||||
public final class Msg {
|
||||
private Msg() {}
|
||||
public static void registerAllExtensions(
|
||||
com.google.protobuf.ExtensionRegistry registry) {
|
||||
}
|
||||
public interface SearchRequestOrBuilder
|
||||
extends com.google.protobuf.MessageOrBuilder {
|
||||
|
||||
// required string query = 1;
|
||||
boolean hasQuery();
|
||||
String getQuery();
|
||||
|
||||
// required int32 page_number = 2;
|
||||
boolean hasPageNumber();
|
||||
int getPageNumber();
|
||||
|
||||
// required int32 result_per_page = 3;
|
||||
boolean hasResultPerPage();
|
||||
int getResultPerPage();
|
||||
}
|
||||
public static final class SearchRequest extends
|
||||
com.google.protobuf.GeneratedMessage
|
||||
implements SearchRequestOrBuilder {
|
||||
// Use SearchRequest.newBuilder() to construct.
|
||||
private SearchRequest(Builder builder) {
|
||||
super(builder);
|
||||
}
|
||||
private SearchRequest(boolean noInit) {}
|
||||
|
||||
private static final SearchRequest defaultInstance;
|
||||
public static SearchRequest getDefaultInstance() {
|
||||
return defaultInstance;
|
||||
}
|
||||
|
||||
public SearchRequest getDefaultInstanceForType() {
|
||||
return defaultInstance;
|
||||
}
|
||||
|
||||
public static final com.google.protobuf.Descriptors.Descriptor
|
||||
getDescriptor() {
|
||||
return com.test.lalala.Msg.internal_static_com_test_lalala_SearchRequest_descriptor;
|
||||
}
|
||||
|
||||
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
internalGetFieldAccessorTable() {
|
||||
return com.test.lalala.Msg.internal_static_com_test_lalala_SearchRequest_fieldAccessorTable;
|
||||
}
|
||||
|
||||
private int bitField0_;
|
||||
// required string query = 1;
|
||||
public static final int QUERY_FIELD_NUMBER = 1;
|
||||
private java.lang.Object query_;
|
||||
public boolean hasQuery() {
|
||||
return ((bitField0_ & 0x00000001) == 0x00000001);
|
||||
}
|
||||
public String getQuery() {
|
||||
java.lang.Object ref = query_;
|
||||
if (ref instanceof String) {
|
||||
return (String) ref;
|
||||
} else {
|
||||
com.google.protobuf.ByteString bs =
|
||||
(com.google.protobuf.ByteString) ref;
|
||||
String s = bs.toStringUtf8();
|
||||
if (com.google.protobuf.Internal.isValidUtf8(bs)) {
|
||||
query_ = s;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
private com.google.protobuf.ByteString getQueryBytes() {
|
||||
java.lang.Object ref = query_;
|
||||
if (ref instanceof String) {
|
||||
com.google.protobuf.ByteString b =
|
||||
com.google.protobuf.ByteString.copyFromUtf8((String) ref);
|
||||
query_ = b;
|
||||
return b;
|
||||
} else {
|
||||
return (com.google.protobuf.ByteString) ref;
|
||||
}
|
||||
}
|
||||
|
||||
// required int32 page_number = 2;
|
||||
public static final int PAGE_NUMBER_FIELD_NUMBER = 2;
|
||||
private int pageNumber_;
|
||||
public boolean hasPageNumber() {
|
||||
return ((bitField0_ & 0x00000002) == 0x00000002);
|
||||
}
|
||||
public int getPageNumber() {
|
||||
return pageNumber_;
|
||||
}
|
||||
|
||||
// required int32 result_per_page = 3;
|
||||
public static final int RESULT_PER_PAGE_FIELD_NUMBER = 3;
|
||||
private int resultPerPage_;
|
||||
public boolean hasResultPerPage() {
|
||||
return ((bitField0_ & 0x00000004) == 0x00000004);
|
||||
}
|
||||
public int getResultPerPage() {
|
||||
return resultPerPage_;
|
||||
}
|
||||
|
||||
private void initFields() {
|
||||
query_ = "";
|
||||
pageNumber_ = 0;
|
||||
resultPerPage_ = 0;
|
||||
}
|
||||
private byte memoizedIsInitialized = -1;
|
||||
public final boolean isInitialized() {
|
||||
byte isInitialized = memoizedIsInitialized;
|
||||
if (isInitialized != -1) return isInitialized == 1;
|
||||
|
||||
if (!hasQuery()) {
|
||||
memoizedIsInitialized = 0;
|
||||
return false;
|
||||
}
|
||||
if (!hasPageNumber()) {
|
||||
memoizedIsInitialized = 0;
|
||||
return false;
|
||||
}
|
||||
if (!hasResultPerPage()) {
|
||||
memoizedIsInitialized = 0;
|
||||
return false;
|
||||
}
|
||||
memoizedIsInitialized = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void writeTo(com.google.protobuf.CodedOutputStream output)
|
||||
throws java.io.IOException {
|
||||
getSerializedSize();
|
||||
if (((bitField0_ & 0x00000001) == 0x00000001)) {
|
||||
output.writeBytes(1, getQueryBytes());
|
||||
}
|
||||
if (((bitField0_ & 0x00000002) == 0x00000002)) {
|
||||
output.writeInt32(2, pageNumber_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000004) == 0x00000004)) {
|
||||
output.writeInt32(3, resultPerPage_);
|
||||
}
|
||||
getUnknownFields().writeTo(output);
|
||||
}
|
||||
|
||||
private int memoizedSerializedSize = -1;
|
||||
public int getSerializedSize() {
|
||||
int size = memoizedSerializedSize;
|
||||
if (size != -1) return size;
|
||||
|
||||
size = 0;
|
||||
if (((bitField0_ & 0x00000001) == 0x00000001)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeBytesSize(1, getQueryBytes());
|
||||
}
|
||||
if (((bitField0_ & 0x00000002) == 0x00000002)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeInt32Size(2, pageNumber_);
|
||||
}
|
||||
if (((bitField0_ & 0x00000004) == 0x00000004)) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeInt32Size(3, resultPerPage_);
|
||||
}
|
||||
size += getUnknownFields().getSerializedSize();
|
||||
memoizedSerializedSize = size;
|
||||
return size;
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 0L;
|
||||
@java.lang.Override
|
||||
protected java.lang.Object writeReplace()
|
||||
throws java.io.ObjectStreamException {
|
||||
return super.writeReplace();
|
||||
}
|
||||
|
||||
public static com.test.lalala.Msg.SearchRequest parseFrom(
|
||||
com.google.protobuf.ByteString data)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return newBuilder().mergeFrom(data).buildParsed();
|
||||
}
|
||||
public static com.test.lalala.Msg.SearchRequest parseFrom(
|
||||
com.google.protobuf.ByteString data,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return newBuilder().mergeFrom(data, extensionRegistry)
|
||||
.buildParsed();
|
||||
}
|
||||
public static com.test.lalala.Msg.SearchRequest parseFrom(byte[] data)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return newBuilder().mergeFrom(data).buildParsed();
|
||||
}
|
||||
public static com.test.lalala.Msg.SearchRequest parseFrom(
|
||||
byte[] data,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
return newBuilder().mergeFrom(data, extensionRegistry)
|
||||
.buildParsed();
|
||||
}
|
||||
public static com.test.lalala.Msg.SearchRequest parseFrom(java.io.InputStream input)
|
||||
throws java.io.IOException {
|
||||
return newBuilder().mergeFrom(input).buildParsed();
|
||||
}
|
||||
public static com.test.lalala.Msg.SearchRequest parseFrom(
|
||||
java.io.InputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
return newBuilder().mergeFrom(input, extensionRegistry)
|
||||
.buildParsed();
|
||||
}
|
||||
public static com.test.lalala.Msg.SearchRequest parseDelimitedFrom(java.io.InputStream input)
|
||||
throws java.io.IOException {
|
||||
Builder builder = newBuilder();
|
||||
if (builder.mergeDelimitedFrom(input)) {
|
||||
return builder.buildParsed();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public static com.test.lalala.Msg.SearchRequest parseDelimitedFrom(
|
||||
java.io.InputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
Builder builder = newBuilder();
|
||||
if (builder.mergeDelimitedFrom(input, extensionRegistry)) {
|
||||
return builder.buildParsed();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public static com.test.lalala.Msg.SearchRequest parseFrom(
|
||||
com.google.protobuf.CodedInputStream input)
|
||||
throws java.io.IOException {
|
||||
return newBuilder().mergeFrom(input).buildParsed();
|
||||
}
|
||||
public static com.test.lalala.Msg.SearchRequest parseFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
return newBuilder().mergeFrom(input, extensionRegistry)
|
||||
.buildParsed();
|
||||
}
|
||||
|
||||
public static Builder newBuilder() { return Builder.create(); }
|
||||
public Builder newBuilderForType() { return newBuilder(); }
|
||||
public static Builder newBuilder(com.test.lalala.Msg.SearchRequest prototype) {
|
||||
return newBuilder().mergeFrom(prototype);
|
||||
}
|
||||
public Builder toBuilder() { return newBuilder(this); }
|
||||
|
||||
@java.lang.Override
|
||||
protected Builder newBuilderForType(
|
||||
com.google.protobuf.GeneratedMessage.BuilderParent parent) {
|
||||
Builder builder = new Builder(parent);
|
||||
return builder;
|
||||
}
|
||||
public static final class Builder extends
|
||||
com.google.protobuf.GeneratedMessage.Builder<Builder>
|
||||
implements com.test.lalala.Msg.SearchRequestOrBuilder {
|
||||
public static final com.google.protobuf.Descriptors.Descriptor
|
||||
getDescriptor() {
|
||||
return com.test.lalala.Msg.internal_static_com_test_lalala_SearchRequest_descriptor;
|
||||
}
|
||||
|
||||
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
internalGetFieldAccessorTable() {
|
||||
return com.test.lalala.Msg.internal_static_com_test_lalala_SearchRequest_fieldAccessorTable;
|
||||
}
|
||||
|
||||
// Construct using com.test.lalala.Msg.SearchRequest.newBuilder()
|
||||
private Builder() {
|
||||
maybeForceBuilderInitialization();
|
||||
}
|
||||
|
||||
private Builder(BuilderParent parent) {
|
||||
super(parent);
|
||||
maybeForceBuilderInitialization();
|
||||
}
|
||||
private void maybeForceBuilderInitialization() {
|
||||
if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
|
||||
}
|
||||
}
|
||||
private static Builder create() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder clear() {
|
||||
super.clear();
|
||||
query_ = "";
|
||||
bitField0_ = (bitField0_ & ~0x00000001);
|
||||
pageNumber_ = 0;
|
||||
bitField0_ = (bitField0_ & ~0x00000002);
|
||||
resultPerPage_ = 0;
|
||||
bitField0_ = (bitField0_ & ~0x00000004);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder clone() {
|
||||
return create().mergeFrom(buildPartial());
|
||||
}
|
||||
|
||||
public com.google.protobuf.Descriptors.Descriptor
|
||||
getDescriptorForType() {
|
||||
return com.test.lalala.Msg.SearchRequest.getDescriptor();
|
||||
}
|
||||
|
||||
public com.test.lalala.Msg.SearchRequest getDefaultInstanceForType() {
|
||||
return com.test.lalala.Msg.SearchRequest.getDefaultInstance();
|
||||
}
|
||||
|
||||
public com.test.lalala.Msg.SearchRequest build() {
|
||||
com.test.lalala.Msg.SearchRequest result = buildPartial();
|
||||
if (!result.isInitialized()) {
|
||||
throw newUninitializedMessageException(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private com.test.lalala.Msg.SearchRequest buildParsed()
|
||||
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||
com.test.lalala.Msg.SearchRequest result = buildPartial();
|
||||
if (!result.isInitialized()) {
|
||||
throw newUninitializedMessageException(
|
||||
result).asInvalidProtocolBufferException();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public com.test.lalala.Msg.SearchRequest buildPartial() {
|
||||
com.test.lalala.Msg.SearchRequest result = new com.test.lalala.Msg.SearchRequest(this);
|
||||
int from_bitField0_ = bitField0_;
|
||||
int to_bitField0_ = 0;
|
||||
if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
|
||||
to_bitField0_ |= 0x00000001;
|
||||
}
|
||||
result.query_ = query_;
|
||||
if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
|
||||
to_bitField0_ |= 0x00000002;
|
||||
}
|
||||
result.pageNumber_ = pageNumber_;
|
||||
if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
|
||||
to_bitField0_ |= 0x00000004;
|
||||
}
|
||||
result.resultPerPage_ = resultPerPage_;
|
||||
result.bitField0_ = to_bitField0_;
|
||||
onBuilt();
|
||||
return result;
|
||||
}
|
||||
|
||||
public Builder mergeFrom(com.google.protobuf.Message other) {
|
||||
if (other instanceof com.test.lalala.Msg.SearchRequest) {
|
||||
return mergeFrom((com.test.lalala.Msg.SearchRequest)other);
|
||||
} else {
|
||||
super.mergeFrom(other);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public Builder mergeFrom(com.test.lalala.Msg.SearchRequest other) {
|
||||
if (other == com.test.lalala.Msg.SearchRequest.getDefaultInstance()) return this;
|
||||
if (other.hasQuery()) {
|
||||
setQuery(other.getQuery());
|
||||
}
|
||||
if (other.hasPageNumber()) {
|
||||
setPageNumber(other.getPageNumber());
|
||||
}
|
||||
if (other.hasResultPerPage()) {
|
||||
setResultPerPage(other.getResultPerPage());
|
||||
}
|
||||
this.mergeUnknownFields(other.getUnknownFields());
|
||||
return this;
|
||||
}
|
||||
|
||||
public final boolean isInitialized() {
|
||||
if (!hasQuery()) {
|
||||
|
||||
return false;
|
||||
}
|
||||
if (!hasPageNumber()) {
|
||||
|
||||
return false;
|
||||
}
|
||||
if (!hasResultPerPage()) {
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public Builder mergeFrom(
|
||||
com.google.protobuf.CodedInputStream input,
|
||||
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||
throws java.io.IOException {
|
||||
com.google.protobuf.UnknownFieldSet.Builder unknownFields =
|
||||
com.google.protobuf.UnknownFieldSet.newBuilder(
|
||||
this.getUnknownFields());
|
||||
while (true) {
|
||||
int tag = input.readTag();
|
||||
switch (tag) {
|
||||
case 0:
|
||||
this.setUnknownFields(unknownFields.build());
|
||||
onChanged();
|
||||
return this;
|
||||
default: {
|
||||
if (!parseUnknownField(input, unknownFields,
|
||||
extensionRegistry, tag)) {
|
||||
this.setUnknownFields(unknownFields.build());
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 10: {
|
||||
bitField0_ |= 0x00000001;
|
||||
query_ = input.readBytes();
|
||||
break;
|
||||
}
|
||||
case 16: {
|
||||
bitField0_ |= 0x00000002;
|
||||
pageNumber_ = input.readInt32();
|
||||
break;
|
||||
}
|
||||
case 24: {
|
||||
bitField0_ |= 0x00000004;
|
||||
resultPerPage_ = input.readInt32();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int bitField0_;
|
||||
|
||||
// required string query = 1;
|
||||
private java.lang.Object query_ = "";
|
||||
public boolean hasQuery() {
|
||||
return ((bitField0_ & 0x00000001) == 0x00000001);
|
||||
}
|
||||
public String getQuery() {
|
||||
java.lang.Object ref = query_;
|
||||
if (!(ref instanceof String)) {
|
||||
String s = ((com.google.protobuf.ByteString) ref).toStringUtf8();
|
||||
query_ = s;
|
||||
return s;
|
||||
} else {
|
||||
return (String) ref;
|
||||
}
|
||||
}
|
||||
public Builder setQuery(String value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
bitField0_ |= 0x00000001;
|
||||
query_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
public Builder clearQuery() {
|
||||
bitField0_ = (bitField0_ & ~0x00000001);
|
||||
query_ = getDefaultInstance().getQuery();
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
void setQuery(com.google.protobuf.ByteString value) {
|
||||
bitField0_ |= 0x00000001;
|
||||
query_ = value;
|
||||
onChanged();
|
||||
}
|
||||
|
||||
// required int32 page_number = 2;
|
||||
private int pageNumber_ ;
|
||||
public boolean hasPageNumber() {
|
||||
return ((bitField0_ & 0x00000002) == 0x00000002);
|
||||
}
|
||||
public int getPageNumber() {
|
||||
return pageNumber_;
|
||||
}
|
||||
public Builder setPageNumber(int value) {
|
||||
bitField0_ |= 0x00000002;
|
||||
pageNumber_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
public Builder clearPageNumber() {
|
||||
bitField0_ = (bitField0_ & ~0x00000002);
|
||||
pageNumber_ = 0;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
// required int32 result_per_page = 3;
|
||||
private int resultPerPage_ ;
|
||||
public boolean hasResultPerPage() {
|
||||
return ((bitField0_ & 0x00000004) == 0x00000004);
|
||||
}
|
||||
public int getResultPerPage() {
|
||||
return resultPerPage_;
|
||||
}
|
||||
public Builder setResultPerPage(int value) {
|
||||
bitField0_ |= 0x00000004;
|
||||
resultPerPage_ = value;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
public Builder clearResultPerPage() {
|
||||
bitField0_ = (bitField0_ & ~0x00000004);
|
||||
resultPerPage_ = 0;
|
||||
onChanged();
|
||||
return this;
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(builder_scope:com.test.lalala.SearchRequest)
|
||||
}
|
||||
|
||||
static {
|
||||
defaultInstance = new SearchRequest(true);
|
||||
defaultInstance.initFields();
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(class_scope:com.test.lalala.SearchRequest)
|
||||
}
|
||||
|
||||
private static com.google.protobuf.Descriptors.Descriptor
|
||||
internal_static_com_test_lalala_SearchRequest_descriptor;
|
||||
private static
|
||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable
|
||||
internal_static_com_test_lalala_SearchRequest_fieldAccessorTable;
|
||||
|
||||
public static com.google.protobuf.Descriptors.FileDescriptor
|
||||
getDescriptor() {
|
||||
return descriptor;
|
||||
}
|
||||
private static com.google.protobuf.Descriptors.FileDescriptor
|
||||
descriptor;
|
||||
static {
|
||||
java.lang.String[] descriptorData = {
|
||||
"\n\tmsg.proto\022\017com.test.lalala\032\020as3options" +
|
||||
".proto\"L\n\rSearchRequest\022\r\n\005query\030\001 \002(\t\022\023" +
|
||||
"\n\013page_number\030\002 \002(\005\022\027\n\017result_per_page\030\003" +
|
||||
" \002(\005B\034\202\265\030\030com.netease.protocGenAs3"
|
||||
};
|
||||
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
||||
public com.google.protobuf.ExtensionRegistry assignDescriptors(
|
||||
com.google.protobuf.Descriptors.FileDescriptor root) {
|
||||
descriptor = root;
|
||||
internal_static_com_test_lalala_SearchRequest_descriptor =
|
||||
getDescriptor().getMessageTypes().get(0);
|
||||
internal_static_com_test_lalala_SearchRequest_fieldAccessorTable = new
|
||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||
internal_static_com_test_lalala_SearchRequest_descriptor,
|
||||
new java.lang.String[] { "Query", "PageNumber", "ResultPerPage", },
|
||||
com.test.lalala.Msg.SearchRequest.class,
|
||||
com.test.lalala.Msg.SearchRequest.Builder.class);
|
||||
com.google.protobuf.ExtensionRegistry registry =
|
||||
com.google.protobuf.ExtensionRegistry.newInstance();
|
||||
registerAllExtensions(registry);
|
||||
as3.As3Options.registerAllExtensions(registry);
|
||||
return registry;
|
||||
}
|
||||
};
|
||||
com.google.protobuf.Descriptors.FileDescriptor
|
||||
.internalBuildGeneratedFileFrom(descriptorData,
|
||||
new com.google.protobuf.Descriptors.FileDescriptor[] {
|
||||
as3.As3Options.getDescriptor(),
|
||||
}, assigner);
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(outer_class_scope)
|
||||
}
|
8
proto/msg.proto
Normal file
8
proto/msg.proto
Normal file
@ -0,0 +1,8 @@
|
||||
package com.test.lalala;
|
||||
import "as3options.proto";
|
||||
option (as3.f_package) = "com.netease.protocGenAs3";
|
||||
message SearchRequest {
|
||||
required string query = 1;
|
||||
required int32 page_number = 2;
|
||||
required int32 result_per_page = 3;
|
||||
}
|
BIN
proto/protoc.exe
Normal file
BIN
proto/protoc.exe
Normal file
Binary file not shown.
387
server/PBMessageUtils.ts
Normal file
387
server/PBMessageUtils.ts
Normal file
@ -0,0 +1,387 @@
|
||||
///ts:import=ByteArray
|
||||
import ByteArray = require('../../structure/ByteArray'); ///ts:import:generated
|
||||
///ts:import=Endian
|
||||
import Endian = require('../../structure/Endian'); ///ts:import:generated
|
||||
// ///ts:import=PBMessage
|
||||
///ts:import=Int64
|
||||
import Int64 = require('../../structure/Int64'); ///ts:import:generated
|
||||
|
||||
|
||||
const LITTLE_ENDIAN = Endian.LITTLE_ENDIAN;
|
||||
const TYPE_DOUBLE: number = 1;
|
||||
const TYPE_FLOAT: number = 2;
|
||||
const TYPE_INT64: number = 3;
|
||||
const TYPE_UINT64: number = 4;
|
||||
const TYPE_INT32: number = 5;
|
||||
const TYPE_FIXED64: number = 6;
|
||||
const TYPE_FIXED32: number = 7;
|
||||
const TYPE_BOOL: number = 8;
|
||||
const TYPE_STRING: number = 9;
|
||||
const TYPE_GROUP: number = 10;
|
||||
const TYPE_MESSAGE: number = 11;
|
||||
const TYPE_BYTES: number = 12;
|
||||
const TYPE_UINT32: number = 13;
|
||||
const TYPE_ENUM: number = 14;
|
||||
const TYPE_SFIXED32: number = 15;
|
||||
const TYPE_SFIXED64: number = 16;
|
||||
const TYPE_SINT32: number = 17;
|
||||
const TYPE_SINT64: number = 18;
|
||||
/**
|
||||
0 必有 属性名字
|
||||
1 必有 required optional repeated
|
||||
2 必有 数据类型
|
||||
3 可选 消息类型名称
|
||||
4 可选 默认值
|
||||
*/
|
||||
declare type MessageStruct =
|
||||
[/**0 */string, /**1 */number,/**2 */number] |
|
||||
[/**属性名字 */string, /**选项 */number,/**数据类型 */number,/**如果是子消息,消息名称 */string] |
|
||||
[/**属性名字 */string, /**选项 */number,/**数据类型 */number,/**如果是子消息,消息名称 */string, /**默认值 */any]
|
||||
|
||||
/**
|
||||
*
|
||||
* @author 3tion
|
||||
* javascript 只会使用到 varint32->number string boolean
|
||||
*
|
||||
*/
|
||||
class PBMessageUtils {
|
||||
|
||||
/**
|
||||
*
|
||||
* 根据message名字得到的结构数据
|
||||
* @static
|
||||
* @type
|
||||
*/
|
||||
public static structByName: { /**消息名称*/[index: string]:
|
||||
{
|
||||
/**索引 */
|
||||
[index: number]:
|
||||
|
||||
MessageStruct
|
||||
}
|
||||
} = {};
|
||||
|
||||
/**
|
||||
*
|
||||
* 根据message名字绑定的类名,用于读取消息时创建的对象
|
||||
* 如果没有注册,则直接使用{}创建对象
|
||||
* @static
|
||||
* @type {{ [index: string]: { new () } }}
|
||||
*/
|
||||
public static ctorByName: { [index: string]: { new () } } = {};
|
||||
|
||||
public static readFrom(msgType: string, bytes: ByteArray, len = -1): Object {
|
||||
let ctor = PBMessageUtils.ctorByName[msgType];
|
||||
let msg = ctor ? new ctor : {};
|
||||
let afterLen = 0;
|
||||
if (len > -1) {
|
||||
afterLen = bytes.bytesAvailable - len;
|
||||
}
|
||||
let encode = PBMessageUtils.structByName[msgType];
|
||||
if (!encode) {
|
||||
Logger.error(ErrorType.Program, `非法的通信类型[${msgType}],堆栈信息:${new Error().stack}`);
|
||||
return;
|
||||
}
|
||||
//检查处理默认值
|
||||
for (let idx in encode) {
|
||||
let body = encode[idx];
|
||||
//0 key
|
||||
//1 required optional repeated
|
||||
//2 数据类型
|
||||
//3 Message
|
||||
//4 默认值
|
||||
if (4 in body) {//有默认值
|
||||
let key = body[0];
|
||||
//消息中没有对应key的数据,先赋值成默认值,等待后续处理
|
||||
if (!(key in msg)) {
|
||||
msg[key] = body[4];
|
||||
}
|
||||
}
|
||||
}
|
||||
while (bytes.bytesAvailable > afterLen) {
|
||||
let tag = bytes.readVarint();
|
||||
if (tag == 0)
|
||||
continue;
|
||||
let idx = tag >>> 3;
|
||||
let body = encode[idx];
|
||||
if (!body) {
|
||||
Logger.error(ErrorType.Program, `读取消息类型为:${msgType},索引${idx}时数据出现错误,找不到对应的数据结构配置`);
|
||||
return;
|
||||
}
|
||||
let name = body[0];
|
||||
let label = body[1];
|
||||
let type = body[2];
|
||||
let subMsgType = body[3];
|
||||
let value: Object;
|
||||
if (label != 3 || (tag & 0b111) != 7) {//自定义 tag & 0b111 == 7 为 数组中 undefined的情况
|
||||
switch (type) {
|
||||
case TYPE_DOUBLE:
|
||||
value = bytes.readDouble();
|
||||
break;
|
||||
case TYPE_FLOAT:
|
||||
value = bytes.readFloat();
|
||||
break;
|
||||
case TYPE_INT64:
|
||||
case TYPE_UINT64:
|
||||
case TYPE_SINT64:
|
||||
value = bytes.readVarint64();
|
||||
break;
|
||||
case TYPE_INT32:
|
||||
case TYPE_SINT32:
|
||||
value = PBMessageUtils.decodeZigzag32(bytes.readVarint());
|
||||
break;
|
||||
case TYPE_UINT32:
|
||||
case TYPE_ENUM:
|
||||
value = bytes.readVarint();
|
||||
break;
|
||||
case TYPE_FIXED64:
|
||||
case TYPE_SFIXED64:
|
||||
value = PBMessageUtils.readFix64(bytes);//理论上项目不使用
|
||||
break;
|
||||
case TYPE_FIXED32:
|
||||
value = bytes.readUnsignedInt();
|
||||
break;
|
||||
case TYPE_BOOL:
|
||||
value = PBMessageUtils.readBoolean(bytes);
|
||||
break;
|
||||
case TYPE_STRING:
|
||||
value = PBMessageUtils.readString(bytes);
|
||||
break;
|
||||
case TYPE_GROUP://(protobuf 已弃用)
|
||||
value = undefined;
|
||||
Logger.error(ErrorType.Program, `读取消息类型为:${msgType},索引${idx}时数据出现已弃用的GROUP分组类型(${TYPE_GROUP})`);
|
||||
break;
|
||||
case TYPE_MESSAGE://消息
|
||||
value = PBMessageUtils.readMessage(bytes, subMsgType);
|
||||
break;
|
||||
case TYPE_BYTES:
|
||||
value = PBMessageUtils.readBytes(bytes);
|
||||
break;
|
||||
case TYPE_SFIXED32:
|
||||
value = bytes.readInt();
|
||||
break;
|
||||
default:
|
||||
value = PBMessageUtils.readValue(tag, bytes);
|
||||
}
|
||||
}
|
||||
if (label == 3) {//repeated
|
||||
let arr = msg[name];
|
||||
if (!arr) msg[name] = arr = [];
|
||||
arr.push(value);
|
||||
}
|
||||
else {
|
||||
msg[name] = value;
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
private static readValue(tag: number, bytes: ByteArray): any {
|
||||
let wireType: number = tag & 7;
|
||||
let value: any;
|
||||
switch (wireType) {
|
||||
case 0: //Varint int32, int64, uint32, uint64, sint32, sint64, bool, enum
|
||||
value = bytes.readVarint();
|
||||
break;
|
||||
case 2: //Length-delimi string, bytes, embedded messages, packed repeated fields
|
||||
value = PBMessageUtils.readString(bytes);
|
||||
break;
|
||||
case 5: //32-bit fixed32, sfixed32, float
|
||||
value = bytes.readInt();
|
||||
break;
|
||||
case 1: //64-bit fixed64, sfixed64, double
|
||||
value = bytes.readDouble();
|
||||
break;
|
||||
//case 3://Start group Groups (deprecated)
|
||||
//break;
|
||||
//case 4://End group Groups (deprecated)
|
||||
//break;
|
||||
default:
|
||||
Logger.error(ErrorType.Program, "protobuf的wireType未知");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
private static readFix64(bytes: ByteArray): Object {
|
||||
let v: Int64 = new Int64;
|
||||
v.low = bytes.readUnsignedInt();
|
||||
v.high = bytes.readUnsignedInt();
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
private static readBoolean(bytes: ByteArray): Object {
|
||||
return bytes.readVarint() > 0;
|
||||
}
|
||||
|
||||
private static readString(bytes: ByteArray): Object {
|
||||
let blen: number = bytes.readVarint();
|
||||
if (blen > 0) {
|
||||
return bytes.readUTFBytes(blen);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* 读取消息
|
||||
* @private
|
||||
* @static
|
||||
* @param {number} tag 标签
|
||||
* @param {ByteArray} bytes 被处理的字节数组
|
||||
* @param {string} subMsgType 类型标识
|
||||
* @returns {Object}
|
||||
*/
|
||||
private static readMessage(bytes: ByteArray, msgType: string): Object {
|
||||
let blen: number = bytes.readVarint();
|
||||
return PBMessageUtils.readFrom(msgType, bytes, blen);
|
||||
}
|
||||
|
||||
private static readBytes(bytes: ByteArray): Object {
|
||||
let blen: number = bytes.readVarint();
|
||||
return bytes.readByteArray(blen);
|
||||
}
|
||||
|
||||
public static writeTo(msg: Object, msgType: string, bytes?: ByteArray): ByteArray {
|
||||
if (msg == undefined) {
|
||||
return;
|
||||
}
|
||||
let messageEncode = PBMessageUtils.structByName[msgType];// msg.mMessageEncode;
|
||||
if (!messageEncode) {
|
||||
Logger.error(ErrorType.Program, `非法的通信类型[${msgType}],堆栈信息:${new Error().stack}`);
|
||||
return;
|
||||
}
|
||||
if (!bytes) {
|
||||
bytes = new ByteArray;
|
||||
}
|
||||
for (let numberStr in messageEncode) {
|
||||
let num = +numberStr;
|
||||
let body = messageEncode[num];
|
||||
let label = body[1];
|
||||
let name = body[0];
|
||||
if (label == 1 && !(name in msg)) {
|
||||
continue;
|
||||
}
|
||||
let value = msg[name];
|
||||
if (value == undefined || value === body[4]/* 默认值 */) {
|
||||
continue;
|
||||
}
|
||||
let type = body[2];
|
||||
let subMsgType = body[3];
|
||||
let wireType = PBMessageUtils.type2WireType(type);
|
||||
let tag = (num << 3) | wireType;
|
||||
if (label == 3) {
|
||||
for (let key in value) {
|
||||
let element = value[key];
|
||||
// 针对repeated中无法处理空的占位数组做处理,Protobuf 2 中不支持undefined进行占位 由于 wireType 只使用 0 1 2 3 4 5
|
||||
// 现在使用 7 作为 undefined 占位使用
|
||||
PBMessageUtils.writeElementTo(element, type, element == undefined ? ((num << 3) | 7) : tag, bytes, subMsgType);
|
||||
}
|
||||
}
|
||||
else {
|
||||
PBMessageUtils.writeElementTo(value, type, tag, bytes, subMsgType);
|
||||
}
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static writeElementTo(value: any, type: number, tag: number, bytes: ByteArray, subMsgType?: string): void {
|
||||
bytes.writeVarint(tag);
|
||||
switch (type) {
|
||||
case TYPE_FIXED32:
|
||||
bytes.writeUnsignedInt(value as number);
|
||||
break;
|
||||
case TYPE_SFIXED32:
|
||||
bytes.writeInt(value as number);
|
||||
break;
|
||||
case TYPE_FLOAT:
|
||||
bytes.writeFloat(value as number);
|
||||
break;
|
||||
case TYPE_DOUBLE:
|
||||
case TYPE_FIXED64:
|
||||
case TYPE_SFIXED64:
|
||||
bytes.writeDouble(value as number);
|
||||
break;
|
||||
case TYPE_INT32:
|
||||
case TYPE_SINT32:
|
||||
bytes.writeVarint(PBMessageUtils.zigzag32(value as number));
|
||||
break;
|
||||
case TYPE_ENUM:
|
||||
case TYPE_UINT32:
|
||||
bytes.writeVarint(value as number);
|
||||
break;
|
||||
case TYPE_INT64:
|
||||
case TYPE_SINT64:
|
||||
case TYPE_UINT64:
|
||||
bytes.writeVarint64(value as Int64);
|
||||
break;
|
||||
case TYPE_BOOL:
|
||||
bytes.writeVarint(value ? 1 : 0);
|
||||
break;
|
||||
case TYPE_STRING:
|
||||
let length: number = Buffer.byteLength(value);
|
||||
bytes.writeVarint(length);
|
||||
bytes.writeUTFBytes(value);
|
||||
break;
|
||||
case TYPE_BYTES:
|
||||
{
|
||||
let temp: ByteArray = value as ByteArray;
|
||||
let length = temp ? temp.length : 0;
|
||||
bytes.writeVarint(length);
|
||||
if (length > 0) {
|
||||
bytes.writeBytes(temp, 0, length);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TYPE_MESSAGE:
|
||||
{
|
||||
let temp = PBMessageUtils.writeTo(value, subMsgType);
|
||||
let length = temp ? temp.length : 0;
|
||||
bytes.writeVarint(length);
|
||||
if (length > 0) {
|
||||
bytes.writeBytes(temp, 0, length);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static type2WireType(type: number): number {
|
||||
switch (type) {
|
||||
case TYPE_FIXED32:
|
||||
case TYPE_SFIXED32:
|
||||
case TYPE_FLOAT:
|
||||
return 5;
|
||||
case TYPE_DOUBLE:
|
||||
case TYPE_FIXED64:
|
||||
case TYPE_SFIXED64:
|
||||
return 1;
|
||||
case TYPE_INT32:
|
||||
case TYPE_SINT32:
|
||||
case TYPE_ENUM:
|
||||
case TYPE_UINT32:
|
||||
case TYPE_INT64:
|
||||
case TYPE_SINT64:
|
||||
case TYPE_UINT64:
|
||||
case TYPE_BOOL:
|
||||
return 0;
|
||||
case TYPE_STRING:
|
||||
case TYPE_MESSAGE:
|
||||
case TYPE_BYTES:
|
||||
return 2;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
public static zigzag32(n: number) {
|
||||
return (n << 1) ^ (n >> 31);
|
||||
}
|
||||
|
||||
public static decodeZigzag32(n: number) {
|
||||
return n >> 1 ^ (((n & 1) << 31) >> 31);
|
||||
}
|
||||
}
|
||||
|
||||
export = PBMessageUtils;
|
45
src/CookieForPath.ts
Normal file
45
src/CookieForPath.ts
Normal file
@ -0,0 +1,45 @@
|
||||
|
||||
const $g = (id) => { return <HTMLInputElement>document.getElementById(id) };
|
||||
const fs = nodeRequire("fs");
|
||||
|
||||
export default class CookieForPath {
|
||||
private _key: string;
|
||||
constructor(key: string) {
|
||||
this._key = key;
|
||||
}
|
||||
public getPathCookie(id: string) {
|
||||
let sPath = cookie.getCookie(this._key + id);
|
||||
if (sPath) {
|
||||
$g(id).value = sPath;
|
||||
}
|
||||
}
|
||||
|
||||
public setPathCookie(id: string, checkExists = true, checkDirectory = true): string {
|
||||
let v: string = $g(id).value;
|
||||
v = v.trim();
|
||||
$g(id).value = v;
|
||||
let flag = false;
|
||||
if (v) {
|
||||
if (checkExists) {
|
||||
if (fs.existsSync(v)) {
|
||||
let re = fs.statSync(v);
|
||||
if (checkDirectory) {
|
||||
if (re.isDirectory()) {
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
flag = true;
|
||||
}
|
||||
if (flag) {
|
||||
cookie.setCookie(this._key + id, v);
|
||||
return v;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
204
src/Extend.ts
Normal file
204
src/Extend.ts
Normal file
@ -0,0 +1,204 @@
|
||||
|
||||
/**
|
||||
* 文档是否加载好
|
||||
*
|
||||
* @param {{ (e?: UIEvent): void }} fn (description)
|
||||
*/
|
||||
function ready(fn: { (e?: UIEvent): void }) {
|
||||
if (document.readyState != 'loading') {
|
||||
fn();
|
||||
} else {
|
||||
document.addEventListener('DOMContentLoaded', fn);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 对数字进行补0操作
|
||||
* @param value 要补0的数值
|
||||
* @param length 要补的总长度
|
||||
* @return 补0之后的字符串
|
||||
*/
|
||||
function zeroize(value: number | string, length: number = 2): string {
|
||||
let str = "" + value;
|
||||
let zeros = "";
|
||||
for (let i = 0, len = length - str.length; i < len; i++) {
|
||||
zeros += "0";
|
||||
}
|
||||
return zeros + str;
|
||||
}
|
||||
/****************************************扩展Object****************************************/
|
||||
interface Object {
|
||||
/**
|
||||
* 将数据拷贝到 to
|
||||
* @param to 目标
|
||||
*/
|
||||
copyto(to: Object);
|
||||
/**
|
||||
* 获取指定属性的描述,会查找当前数据和原型数据
|
||||
* @param property 指定的属性名字
|
||||
*/
|
||||
getPropertyDescriptor(property: string): PropertyDescriptor;
|
||||
}
|
||||
|
||||
Object.defineProperties(Object.prototype, {
|
||||
"getPropertyDescriptor": {
|
||||
value: function (property: string): any {
|
||||
var data = Object.getOwnPropertyDescriptor(this, property);
|
||||
if (data) {
|
||||
return data;
|
||||
}
|
||||
var prototype = Object.getPrototypeOf(this);
|
||||
if (prototype) {
|
||||
return prototype.getPropertyDescriptor(property);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
enumerable: false
|
||||
},
|
||||
"copyto": {
|
||||
value: function (to: Object) {
|
||||
for (let p in this) {
|
||||
var data: PropertyDescriptor = to.getPropertyDescriptor(p);
|
||||
if (data && data.set) {
|
||||
to[p] = this[p];
|
||||
}
|
||||
}
|
||||
},
|
||||
enumerable: false
|
||||
}
|
||||
});
|
||||
|
||||
/****************************************扩展Math****************************************/
|
||||
interface Math {
|
||||
/**
|
||||
* 让数值处于指定的最大值和最小值之间,低于最小值取最小值,高于最大值取最大值
|
||||
* @param value 要处理的数值
|
||||
* @param min 最小值
|
||||
* @param max 最大值
|
||||
*/
|
||||
clamp: (value: number, min: number, max: number) => number;
|
||||
|
||||
}
|
||||
|
||||
Math.clamp = (value, min, max) => {
|
||||
if (value < min) {
|
||||
value = min;
|
||||
}
|
||||
if (value > max) {
|
||||
value = max;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/****************************************扩展Number********************************************/
|
||||
interface Number {
|
||||
/**
|
||||
* 对数字进行补0操作
|
||||
* @param length 要补的总长度
|
||||
* @return 补0之后的字符串
|
||||
*/
|
||||
zeroize(length: number): string;
|
||||
}
|
||||
|
||||
Object.defineProperties(Number.prototype, {
|
||||
"zeroize": {
|
||||
value: function (length) { return zeroize(this, length) },
|
||||
enumerable: false
|
||||
}
|
||||
});
|
||||
|
||||
/****************************************扩展String****************************************/
|
||||
interface String {
|
||||
/**
|
||||
* 替换字符串中{0}{1}{2}{a} {b}这样的数据,用obj对应key替换,或者是数组中对应key的数据替换
|
||||
*/
|
||||
substitute(...args): string;
|
||||
/**
|
||||
* 对数字进行补0操作
|
||||
* @param length 要补的总长度
|
||||
* @return 补0之后的字符串
|
||||
*/
|
||||
zeroize(length: number): string;
|
||||
}
|
||||
|
||||
|
||||
Object.defineProperties(String.prototype, {
|
||||
"zeroize": {
|
||||
value: function (length) { return zeroize(this, length) },
|
||||
enumerable: false
|
||||
},
|
||||
"substitute": {
|
||||
value: function () {
|
||||
var len = arguments.length;
|
||||
if (len > 0) {
|
||||
var obj;
|
||||
if (len == 1) {
|
||||
obj = arguments[0];
|
||||
if (typeof obj !== "object") {
|
||||
obj = arguments;
|
||||
}
|
||||
} else {
|
||||
obj = arguments;
|
||||
}
|
||||
|
||||
if ((obj instanceof Object) && !(obj instanceof RegExp)) {
|
||||
return this.replace(/\{([^{}]+)\}/g, function (match, key) {
|
||||
var value = obj[key];
|
||||
return (value !== undefined) ? '' + value : '';
|
||||
});
|
||||
}
|
||||
}
|
||||
return this;
|
||||
},
|
||||
enumerable: false
|
||||
}
|
||||
});
|
||||
interface StringConstructor {
|
||||
/**
|
||||
* 对数字进行补0操作
|
||||
* @param value 要补0的数值
|
||||
* @param length 要补的总长度
|
||||
* @return 补0之后的字符串
|
||||
*/
|
||||
zeroize: (value: number, length: number) => string;
|
||||
|
||||
}
|
||||
|
||||
String["zeroize"] = zeroize;
|
||||
|
||||
/****************************************扩展Date****************************************/
|
||||
|
||||
|
||||
interface Date {
|
||||
/**
|
||||
* 格式化日期
|
||||
*/
|
||||
format(mask: string): string;
|
||||
}
|
||||
|
||||
Object.defineProperties(Date.prototype, {
|
||||
"format": {
|
||||
value: function (mask) {
|
||||
let d = this;
|
||||
return mask.replace(/"[^"]*"|'[^']*'|(?:d{1,2}|m{1,2}|yy(?:yy)?|([hHMs])\1?)/g, function ($0) {
|
||||
switch ($0) {
|
||||
case "d": return d.getDate();
|
||||
case "dd": return zeroize(d.getDate());
|
||||
case "M": return d.getMonth() + 1;
|
||||
case "MM": return zeroize(d.getMonth() + 1);
|
||||
case "yy": return String(d.getFullYear()).substr(2);
|
||||
case "yyyy": return d.getFullYear();
|
||||
case "h": return d.getHours() % 12 || 12;
|
||||
case "hh": return zeroize(d.getHours() % 12 || 12);
|
||||
case "H": return d.getHours();
|
||||
case "HH": return zeroize(d.getHours());
|
||||
case "m": return d.getMinutes();
|
||||
case "mm": return zeroize(d.getMinutes());
|
||||
case "s": return d.getSeconds();
|
||||
case "ss": return zeroize(d.getSeconds());
|
||||
default: return $0.substr(1, $0.length - 2);
|
||||
}
|
||||
});
|
||||
},
|
||||
enumerable: false
|
||||
}
|
||||
});
|
53
src/FsExtra.ts
Normal file
53
src/FsExtra.ts
Normal file
@ -0,0 +1,53 @@
|
||||
|
||||
var nodeRequire = nodeRequire || require;
|
||||
var FsExtra = (function () {
|
||||
const fs = nodeRequire("fs");
|
||||
const path = nodeRequire("path");
|
||||
function mkdirs(paths: string[]) {
|
||||
var len = paths.length;
|
||||
if (len == 0) {
|
||||
throw Error("路径无效" + paths);
|
||||
}
|
||||
var p = paths[0];
|
||||
if (!p) {
|
||||
p = '/';
|
||||
}
|
||||
|
||||
for (var i = 1, len = paths.length; i < len; i++) {
|
||||
p = path.join(p, paths[i]);
|
||||
if (fs.existsSync(p)) {
|
||||
var ret = fs.statSync(p);
|
||||
if (!ret.isDirectory()) {
|
||||
throw Error("无法创建文件夹" + p);
|
||||
}
|
||||
} else {
|
||||
fs.mkdirSync(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
var xfs = {
|
||||
/**
|
||||
* 将文件夹拆分
|
||||
*/
|
||||
split: function (filePath: string): string[] {
|
||||
return path.normalize(filePath).split(path.sep);
|
||||
},
|
||||
/**
|
||||
* 同步创建文件夹
|
||||
*/
|
||||
mkdirs: function (filePath: string) {
|
||||
mkdirs(xfs.split(filePath));
|
||||
},
|
||||
/**
|
||||
* 写文件
|
||||
*/
|
||||
writeFileSync: function (filePath: string, data: string | Buffer, isCorver: boolean = true, options?: Object | string) {
|
||||
var re = path.parse(filePath);
|
||||
mkdirs(xfs.split(re.dir));
|
||||
if(isCorver || !fs.existsSync(filePath)){
|
||||
fs.writeFileSync(filePath, data, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
return xfs;
|
||||
} ());
|
63
src/PBMsgDictTemplate.ts
Normal file
63
src/PBMsgDictTemplate.ts
Normal file
@ -0,0 +1,63 @@
|
||||
import _fs = require("fs");
|
||||
const fs: typeof _fs = nodeRequire("fs");
|
||||
const regValue = /(([a-zA-Z_0-9]+)\s*:\s*{.*?}),?/g;
|
||||
/**
|
||||
* 服务端前缀
|
||||
*/
|
||||
const serverPrefix = "export = {\n";
|
||||
/**
|
||||
* 客户端前缀
|
||||
*/
|
||||
const clientPrefix = "const PBMsgDict = {\n";
|
||||
/**
|
||||
*
|
||||
* 用于创建服务端用的消息字典的常量文件
|
||||
* @export
|
||||
* @class PBMsgDictTemplate
|
||||
*/
|
||||
export default class PBMsgDictTemplate {
|
||||
|
||||
public getKeys(file: string)
|
||||
{
|
||||
let valueDic: Map<string, string> = new Map();
|
||||
if (!fs.existsSync(file) || !fs.statSync(file).isFile()) {
|
||||
return valueDic;
|
||||
}
|
||||
let content = fs.readFileSync(file, "utf8");
|
||||
regValue.lastIndex = 0;
|
||||
while (true) {
|
||||
let res = regValue.exec(content);
|
||||
if (res) {
|
||||
valueDic.set(res[2], res[1]);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return valueDic;
|
||||
}
|
||||
|
||||
public addToFile(file: string, dict: { [index: string]: string }, isServer: boolean) {
|
||||
let valueDic: Map<string, string> = this.getKeys(file);
|
||||
return this.addContent(dict, valueDic, isServer);
|
||||
}
|
||||
|
||||
private addContent(dict: { [index: string]: string }, valueDic: Map<string, string>, isServer: boolean) {
|
||||
let added = false;
|
||||
let code = isServer ? serverPrefix : clientPrefix;
|
||||
let arr = [];
|
||||
for (let k of valueDic.keys()) {
|
||||
if (!(k in dict)) {
|
||||
arr.push([k, "\t" + valueDic.get(k)]);
|
||||
}
|
||||
}
|
||||
//附加字典中的内容
|
||||
for (let k in dict) {
|
||||
arr.push([k, `\t${k}: ${dict[k]}`]);
|
||||
}
|
||||
arr.sort((a, b) => a > b ? 1 : -1);
|
||||
arr.map((item, idx) => arr[idx] = item[1]);
|
||||
code += arr.join(",\n");
|
||||
code += "\n}";
|
||||
return code;
|
||||
}
|
||||
}
|
55
src/ServiceNameTemplate.ts
Normal file
55
src/ServiceNameTemplate.ts
Normal file
@ -0,0 +1,55 @@
|
||||
import _fs = require("fs");
|
||||
const fs: typeof _fs = nodeRequire("fs");
|
||||
/**
|
||||
* 客户端前缀
|
||||
*/
|
||||
const clientPrefix = "const enum ServiceName {\n\t";
|
||||
|
||||
/**
|
||||
* 用于创建服务名字的常量文件
|
||||
*/
|
||||
export default class ServiceNameTemplate
|
||||
{
|
||||
public addToFile(file: string, serviceName: string)
|
||||
{
|
||||
let valueDic: string[] = [];
|
||||
if (!fs.existsSync(file) || !fs.statSync(file).isFile()) {
|
||||
valueDic = ["$ = 0",serviceName];
|
||||
return this.addContent(serviceName, valueDic);
|
||||
}
|
||||
let temp = fs.readFileSync(file, "utf8");
|
||||
let content = temp;
|
||||
content = content.substring(clientPrefix.length, content.lastIndexOf("}"));
|
||||
content = content.replace(/\r\t/g, "").replace(/\n/g, "").replace(/\t/g, "").replace(/\r/g, "");
|
||||
valueDic = content.split(",");
|
||||
console.log("valueDic", valueDic);
|
||||
if (valueDic.indexOf(serviceName) == -1){
|
||||
valueDic.push(serviceName);
|
||||
return this.addContent(serviceName, valueDic);
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
private addContent(serviceName: string, valueDic: string[]) {
|
||||
let added = false;
|
||||
let code = clientPrefix;
|
||||
//附加字典中的内容
|
||||
valueDic.sort((a: string, b: string)=>{
|
||||
let l = a.length > b.length ? b.length: a.length;
|
||||
if (a.charAt(0) == "$") return -1;
|
||||
if (b.charAt(0) == "$") return 1;
|
||||
for (let i = 0; i < l; i++)
|
||||
{
|
||||
let ai = a.charAt(i).toLocaleLowerCase().charCodeAt(0);
|
||||
let bi = b.charAt(i).toLocaleLowerCase().charCodeAt(0);
|
||||
if (ai > bi) return 1;
|
||||
else if (ai < bi) return -1;
|
||||
}
|
||||
return l == a.length ? -1 : 1;
|
||||
});
|
||||
code += valueDic.join(",\r\t");
|
||||
code += "\n}";
|
||||
console.log("code=====", code);
|
||||
return code;
|
||||
}
|
||||
}
|
856
src/app2.ts
Normal file
856
src/app2.ts
Normal file
@ -0,0 +1,856 @@
|
||||
"use strict";
|
||||
import * as pbjs from "protobuf";
|
||||
import ServiceNameTemplate from "ServiceNameTemplate";
|
||||
import PBMsgDictTemplate from "PBMsgDictTemplate";
|
||||
import CookieForPath from "CookieForPath";
|
||||
|
||||
const fs = nodeRequire("fs");
|
||||
const path = nodeRequire("path");
|
||||
const http = nodeRequire("http");
|
||||
const process = nodeRequire('child_process');
|
||||
const clipboard = nodeRequire('electron').clipboard;
|
||||
|
||||
const $g = (id) => { return <HTMLInputElement>document.getElementById(id) };
|
||||
/**
|
||||
* 输出日志
|
||||
*/
|
||||
function log(msg: string) {
|
||||
let txtLog = $g("txtLog");
|
||||
if (txtLog) {
|
||||
txtLog.innerHTML += `[${new Date().format("HH:mm:ss")}] ${msg} <br/>`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 输出错误
|
||||
*/
|
||||
function error(msg: string) {
|
||||
log(`<font color="#f00">${msg}</font>`);
|
||||
}
|
||||
|
||||
const Options = {
|
||||
/**
|
||||
* 服务名称
|
||||
*/
|
||||
ServiceName: "(service)",
|
||||
/**
|
||||
* 客户端模块
|
||||
*/
|
||||
ClientModule: "(cmodule)",
|
||||
/**
|
||||
* 客户端路径,和前缀路径拼接得到文件生成路径地址
|
||||
*/
|
||||
ClientPath: "(cpath)",
|
||||
/**
|
||||
* 统一协议号请求间隔时间
|
||||
*/
|
||||
Limit: "(limit)",
|
||||
}
|
||||
|
||||
interface GlobalCfg
|
||||
{
|
||||
/**
|
||||
* 客户端项目路径
|
||||
*/
|
||||
cprefix: string;
|
||||
/**
|
||||
* 生成时,使用的wiki地址
|
||||
*/
|
||||
url?: string;
|
||||
/**
|
||||
* ServiceName常量文件的文件相对路径
|
||||
*/
|
||||
serviceName?: string;
|
||||
/**
|
||||
* PB消息字典的文件相对路径
|
||||
*/
|
||||
pBMsgDictName?: string;
|
||||
}
|
||||
|
||||
const TYPE_DOUBLE: number = 1;
|
||||
const TYPE_FLOAT: number = 2;
|
||||
const TYPE_INT64: number = 3;
|
||||
const TYPE_UINT64: number = 4;
|
||||
const TYPE_INT32: number = 5;
|
||||
const TYPE_FIXED64: number = 6;
|
||||
const TYPE_FIXED32: number = 7;
|
||||
const TYPE_BOOL: number = 8;
|
||||
const TYPE_STRING: number = 9;
|
||||
const TYPE_GROUP: number = 10;
|
||||
const TYPE_MESSAGE: number = 11;
|
||||
const TYPE_BYTES: number = 12;
|
||||
const TYPE_UINT32: number = 13;
|
||||
const TYPE_ENUM: number = 14;
|
||||
const TYPE_SFIXED32: number = 15;
|
||||
const TYPE_SFIXED64: number = 16;
|
||||
const TYPE_SINT32: number = 17;
|
||||
const TYPE_SINT64: number = 18;
|
||||
|
||||
const type2number = (function ()
|
||||
{
|
||||
let t = {};
|
||||
t["double"] = TYPE_DOUBLE;
|
||||
t["float"] = TYPE_FLOAT;
|
||||
t["int64"] = TYPE_INT64;
|
||||
t["uint64"] = TYPE_UINT64;
|
||||
t["int32"] = TYPE_INT32;
|
||||
t["fixed64"] = TYPE_FIXED64;
|
||||
t["fixed32"] = TYPE_FIXED32;
|
||||
t["bool"] = TYPE_BOOL;
|
||||
t["string"] = TYPE_STRING;
|
||||
t["group"] = TYPE_GROUP;
|
||||
t["message"] = TYPE_MESSAGE;
|
||||
t["bytes"] = TYPE_BYTES;
|
||||
t["uint32"] = TYPE_UINT32;
|
||||
t["enum"] = TYPE_ENUM;
|
||||
t["sfixed32"] = TYPE_SFIXED32;
|
||||
t["sfixed64"] = TYPE_SFIXED64;
|
||||
t["sint32"] = TYPE_SINT32;
|
||||
t["sint64"] = TYPE_SINT64;
|
||||
return t;
|
||||
})();
|
||||
|
||||
const rule2number =
|
||||
{
|
||||
"optional": 1,
|
||||
"required": 2,
|
||||
"repeated": 3
|
||||
};
|
||||
|
||||
const Type_Null = 0;
|
||||
const Type_Boolean = 1;
|
||||
const Type_String = 2;
|
||||
const Type_Bytes = 4;
|
||||
const Type_Double = 5;
|
||||
const Type_Int32 = 6;
|
||||
const Type_Uint32 = 7;
|
||||
|
||||
function field2type(field: pbjs.ProtoField): [string, boolean, string | number, boolean]
|
||||
{
|
||||
let type = field.type;
|
||||
let isMsg = false;
|
||||
let ttype: string | number;
|
||||
switch (type) {
|
||||
case "int32":
|
||||
case "sint32":
|
||||
case "sfixed32":
|
||||
type = "number";
|
||||
ttype = Type_Int32;
|
||||
break;
|
||||
case "enum":
|
||||
case "fixed32":
|
||||
case "uint32":
|
||||
type = "number";
|
||||
ttype = Type_Uint32;
|
||||
case "int64":
|
||||
case "uint64":
|
||||
case "sint64":
|
||||
case "double":
|
||||
case "float":
|
||||
type = "number";
|
||||
ttype = Type_Double;
|
||||
break;
|
||||
case "bool":
|
||||
type = "boolean";
|
||||
ttype = Type_Boolean;
|
||||
break;
|
||||
case "bytes":
|
||||
type = "Byte";
|
||||
ttype = Type_Bytes;
|
||||
break;
|
||||
case "fixed64":
|
||||
case "sfixed64":
|
||||
// 项目理论上不使用
|
||||
type = "Int64";
|
||||
break;
|
||||
case "message":
|
||||
type = field.type;
|
||||
isMsg = true;
|
||||
ttype = `"${type}"`;
|
||||
break;
|
||||
case "string":
|
||||
type = "string";
|
||||
ttype = Type_String;
|
||||
break;
|
||||
default:
|
||||
type = field.type;
|
||||
ttype = `"${type}"`;
|
||||
break;
|
||||
}
|
||||
if (field.rule == "repeated") { // 数组赋值
|
||||
return [type + "[]", isMsg, ttype, true];
|
||||
}
|
||||
return [type, isMsg, ttype, false];
|
||||
}
|
||||
|
||||
|
||||
function getVariable(field: pbjs.ProtoField, variables: string[]): FieldData
|
||||
{
|
||||
let comment = field.comment;// 调整protobuf.js代码 让其记录注释
|
||||
let fname = field.name;
|
||||
let def = "";//改成不赋值默认值,这样typescript->js能减少字符串输出,将默认值记入mMessageEncode,也方便传输时做判断
|
||||
let [fieldType, isMsg, tType, repeated] = field2type(field);
|
||||
if (field.rule == "required") { // 必选参数
|
||||
variables.push(`/**`);
|
||||
variables.push(` * ${comment}`);
|
||||
variables.push(` */`);
|
||||
variables.push(`${fname}: ${fieldType};`);
|
||||
} else {
|
||||
variables.push(`/**`);
|
||||
variables.push(` * 可选参数 ${comment}`);
|
||||
variables.push(` */`);
|
||||
variables.push(`${fname}?: ${fieldType};`);
|
||||
}
|
||||
return { fieldName: fname, fieldType: fieldType, isMsg: isMsg, tType: tType, repeated: repeated };
|
||||
}
|
||||
|
||||
declare type FieldData =
|
||||
{
|
||||
/**
|
||||
* 字段名称
|
||||
*/
|
||||
fieldName: string;
|
||||
/**
|
||||
* 字段类型
|
||||
*/
|
||||
fieldType: string;
|
||||
/**
|
||||
* 是否为消息类型
|
||||
*/
|
||||
isMsg: boolean;
|
||||
/**
|
||||
* 用于注册typeScript的类型
|
||||
*/
|
||||
tType: number | string;
|
||||
/**
|
||||
* 是否为repeated
|
||||
*/
|
||||
repeated: boolean;
|
||||
}
|
||||
|
||||
function parseProto(proto: string, gcfg?: GlobalCfg)
|
||||
{
|
||||
let url: string = gcfg ? gcfg.url : "";
|
||||
url = url || "[文本框中,复制粘贴]";
|
||||
let cprefix = gcfg ? gcfg.cprefix || "" : "";
|
||||
let serviceName = gcfg ? gcfg.serviceName : null;
|
||||
let PBMsgDictName = gcfg ? gcfg.pBMsgDictName : null;
|
||||
let p = pbjs.DotProto.Parser.parse(proto);
|
||||
let options = p.options;
|
||||
let fcpath: string = options[Options.ClientPath];
|
||||
let fcmodule: string = options[Options.ClientModule];
|
||||
let service: string = options[Options.ServiceName];
|
||||
let now = new Date().format("yyyy-MM-dd HH:mm:ss");
|
||||
let idx = 0;
|
||||
let hasService = false;
|
||||
let msgEncDict: { [index: string]: string } = {};
|
||||
var msgTypeNameMap = {};
|
||||
// 客户端和服务端的Service收发数组
|
||||
let cSends: string[] = [], cRecvs: string[] = [], cRegs: string[] = [], sSends: string[] = [], sRecvs: string[] = [], sRegs: string[] = [];
|
||||
|
||||
let pbMsgDictTemplate = new PBMsgDictTemplate();
|
||||
let pbMsgFilePath: string;
|
||||
let pbKeysDict: Map<string, string> = new Map();
|
||||
if (PBMsgDictName) {
|
||||
pbMsgFilePath = path.join(cprefix, PBMsgDictName);
|
||||
pbKeysDict = pbMsgDictTemplate.getKeys(pbMsgFilePath);
|
||||
}
|
||||
|
||||
for (let msg of p.messages) {
|
||||
if (msg.name.indexOf('S2C') > 0 || msg.name.indexOf('C2S') > 0) {
|
||||
var key = msg.name.substring(0, msg.name.length - 8);
|
||||
if (msgTypeNameMap[key]) {
|
||||
msgTypeNameMap[key] = msgTypeNameMap[key] + 1;
|
||||
}
|
||||
else {
|
||||
msgTypeNameMap[key] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (let msg of p.messages) {
|
||||
// 所有的变量
|
||||
// 一行一个
|
||||
let variables: string[] = [];
|
||||
let messageEncodes: string[] = [];
|
||||
// 如果有消息体的同名 Option,覆盖
|
||||
let options = msg.options;
|
||||
let cpath: string = options[Options.ClientPath] || fcpath;
|
||||
let cmodule: string = options[Options.ClientModule] || fcmodule;
|
||||
let limit: any = options[Options.Limit];
|
||||
var comment = msg.comment;
|
||||
let cmds: number[] = [];
|
||||
let requireds: FieldData[] = [];
|
||||
let repeateds: FieldData[] = [];
|
||||
let optionals: FieldData[] = [];
|
||||
|
||||
if (comment.indexOf('=') > 0) {
|
||||
if (comment.indexOf('|') > 0) {
|
||||
cmds = [comment.split('|')[0].split('=')[1]];
|
||||
}
|
||||
else {
|
||||
cmds = [comment.split('=')[1]];
|
||||
}
|
||||
}
|
||||
|
||||
let fieldids = [0];
|
||||
let paramCount = 0;
|
||||
for (let field of msg.fields)
|
||||
{
|
||||
let rule: string = field.rule;
|
||||
let fnumber = type2number[field.type];
|
||||
let MType = "";
|
||||
let def = field.options.default;
|
||||
if (def !== undefined) {
|
||||
let t = typeof def;
|
||||
if (t === "string") {
|
||||
def = `"${def}"`;
|
||||
} else if (t === "object") {//不支持对象类型默认值
|
||||
def = undefined;
|
||||
}
|
||||
}
|
||||
if (fnumber == undefined) {// message类型不支持默认值
|
||||
fnumber = 11;// message
|
||||
MType = `, "${field.type}"`;
|
||||
} else if (def !== undefined) {
|
||||
MType = `, , ${def}`;
|
||||
}
|
||||
fieldids.push(~~field.id);
|
||||
messageEncodes.push(`${field.id}: ["${field.name}", ${rule2number[rule]}, ${fnumber}${MType}]`);
|
||||
let data = getVariable(field, variables);
|
||||
if (rule == "required") {
|
||||
requireds.push(data);
|
||||
} else if (rule == "repeated") {
|
||||
repeateds.push(data);
|
||||
} else {
|
||||
optionals.push(data);
|
||||
}
|
||||
}
|
||||
|
||||
fieldids.sort((a,b)=>{return a - b});
|
||||
for (let i=0, l=fieldids.length-1; i < l; i++){
|
||||
let a = fieldids[i];
|
||||
let b = fieldids[i+1];
|
||||
if (b - a != 1){
|
||||
alert(`${msg.name} 中 value 可能定义有错误。顺序为从1开始,或未连续。此错误可能导致前后端协议值解析不正确`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 根据CMD 生成通信代码
|
||||
// 生成代码
|
||||
let className: string = msg.name;
|
||||
let classNameFileName = path.join(cprefix, cpath, className + ".ts");
|
||||
let isExistsSync = fs.existsSync(classNameFileName);
|
||||
if ((!isExistsSync && pbKeysDict.has(className))){
|
||||
alert(`少年,${className} 已经在其他功能模块中存在了,请更换一个名字吧,当前文件未保存`);
|
||||
continue;
|
||||
}
|
||||
if (msgEncDict[className]){
|
||||
alert(`少年,好粗心啊,当前wiki地址中 ${className} 重名了,当前文件未保存`);
|
||||
continue;
|
||||
}
|
||||
|
||||
msgEncDict[className] = `{ ${messageEncodes.join(", ")} }`;
|
||||
var typeVar = '';
|
||||
if (className.indexOf('S2C') > 0 || className.indexOf('C2S') > 0) {
|
||||
typeVar = className.substr(-7, 3);
|
||||
}
|
||||
let type = typeVar;
|
||||
let handlerName = className[0].toLowerCase() + className.substring(1, className.length - 4);
|
||||
let p = requireds.concat(repeateds, optionals);
|
||||
hasService = true;
|
||||
if (type == "C2S") { // client to server
|
||||
makeCSendFunction(p, className, handlerName, cSends, cmds[0], limit);
|
||||
// makeReciveFunc(className, handlerName + s2c, sRegs, sRecvs, cmds, p, true);
|
||||
} else if (type == "S2C") { // server to client
|
||||
makeReciveFunc(className, handlerName, cRegs, cRecvs, cmds, p, false);
|
||||
// if (messageEncodes.length == 1){
|
||||
// if (messageEncodes[0].indexOf("Code") == -1){
|
||||
// alert(`警告:${className} 协议接受服务器一个参数,可能导致前端解析不正确,随便增加一个参数吧`);
|
||||
// }
|
||||
// }
|
||||
} else {
|
||||
makeCSendFunction(p, className, handlerName + "_C2S", cSends, cmds[0], limit);
|
||||
makeReciveFunc(className, handlerName + "_S2C", cRegs, cRecvs, cmds, p, false);
|
||||
}
|
||||
let fleng = msg.fields.length;
|
||||
let clientCode = getClientCode(now, url, className, cmodule, variables);
|
||||
if (cprefix) {let outpath = path.join(cprefix, cpath, className + ".ts");
|
||||
let cdir = path.join(cprefix, cpath);
|
||||
let out = writeFile(className + ".ts", cdir, clientCode);
|
||||
if (out) {
|
||||
log(`<font color="#0c0">成功生成代码,${out}</font>`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//处理PBMsgDict文件
|
||||
if (pbMsgFilePath) {
|
||||
let crout = pbMsgDictTemplate.addToFile(pbMsgFilePath, msgEncDict, false);
|
||||
let out = writeFile(PBMsgDictName, cprefix, crout);
|
||||
if (out) {
|
||||
log(`<font color="#0c0">生成PBMsgDict代码成功,${out}</font>`);
|
||||
}
|
||||
}
|
||||
|
||||
if (service && hasService) {
|
||||
//预处理Service
|
||||
//检查是否有客户端Service文件
|
||||
let cdir = path.join(cprefix, fcpath);
|
||||
let sfileName = service + ".ts";
|
||||
let cpath = path.join(cdir, sfileName);
|
||||
let ccode = getCServiceCode(now, url, service, fcmodule, cSends, cRecvs, cRegs, getManualCodeInfo(cpath));
|
||||
//检查是否有服务端Service文件
|
||||
// 创建客户端Service
|
||||
if (cprefix) {
|
||||
let out = writeFile(sfileName, cdir, ccode);
|
||||
if (out) {
|
||||
log(`<font color="#0c0">${service}代码成功生成,${out}</font>`);
|
||||
}
|
||||
}
|
||||
// 创建ServiceName常量文件
|
||||
if (serviceName) {
|
||||
let ctemp = new ServiceNameTemplate();
|
||||
let cnPath = path.join(cprefix, serviceName);
|
||||
let code = ctemp.addToFile(cnPath, service);
|
||||
let out = writeFile(serviceName, cprefix, code);
|
||||
if (out) {
|
||||
log(`<font color="#0c0">ServiceName代码成功生成,${out}</font>`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function makeCSendFunction(fnames: FieldData[], className: string, handlerName: string, sends: string[], cmd: number, limit?: number) {
|
||||
let len = fnames.length;
|
||||
let time = limit ? ", "+ limit : "";
|
||||
if (len == 0) { //没有参数
|
||||
sends.push(`public ${handlerName}() {`);
|
||||
sends.push(`\tthis.send(${cmd}, null, ""${time})`);
|
||||
} else {
|
||||
sends.push(`public ${handlerName}(_${className}: ${className}) {`);
|
||||
sends.push(`\tthis.send(${cmd}, _${className}, "${className}"${time});`);
|
||||
}
|
||||
sends.push(`}`)
|
||||
}
|
||||
|
||||
function makeReciveFunc(className: string, handlerName: string, regs: string[], recvs: string[], cmds: number[], fnames: FieldData[], isServer: boolean) {
|
||||
let len = fnames.length;
|
||||
let strCMD = cmds.join(",");
|
||||
var p: FieldData;
|
||||
if (len == 0) {//为null
|
||||
regs.push(`self.regMsg(${Type_Null}, ${strCMD});`);
|
||||
}else {
|
||||
regs.push(`self.regMsg("${className}", ${strCMD});`);
|
||||
}
|
||||
regs.push(`self.regHandler(self.${handlerName}, ${strCMD});`);
|
||||
let pp = isServer ? "async " : "";
|
||||
recvs.push(`protected ${handlerName} = ${pp}(data:NetData) => {`);
|
||||
recvs.push(`\tlet msg:${className} = <${className}>data.data;`);
|
||||
recvs.push(`/*|$${handlerName}|*/`);
|
||||
recvs.push(`}`);
|
||||
}
|
||||
|
||||
function writeFile(fname: string, directory: string, data: string, corver = true): string {
|
||||
let outpath = path.join(directory, fname);
|
||||
try {
|
||||
FsExtra.writeFileSync(outpath, data, corver);
|
||||
} catch (e) {
|
||||
error(`写入文件时失败,路径:"${directory}",文件名:"${fname}",错误信息:${e.message}\n${e.stack}`);
|
||||
return null;
|
||||
}
|
||||
return outpath;
|
||||
}
|
||||
|
||||
function getClientCode(createTime: string, url: string, className: string, module: string, variables: string[])
|
||||
{
|
||||
// let clientTemplatePath = "template/msg.template"//path.join("D:/workspace/bitbucket/miniprojects/h5workspace/ProtoTools/dist/", "template", "msg.template");
|
||||
// if (fs.existsSync(clientTemplatePath)) {
|
||||
//读取文件内容
|
||||
let content = clientMsgTemplate;//fs.readFileSync(clientTemplatePath, "utf8");
|
||||
|
||||
content = content.replace(/\{path\}/g, url);
|
||||
content = content.replace(/\{createTime\}/g, createTime);
|
||||
content = content.replace(/\{className\}/g, className);
|
||||
content = content.replace(/\{vars\}/g, variables.join(`\n `));
|
||||
|
||||
return content;
|
||||
// }
|
||||
// return "";
|
||||
}
|
||||
|
||||
function getCServiceCode(createTime: string, url: string, className: string, module: string, sends: string[], recvs: string[], regs: string[], cinfo: { [index: string]: string })
|
||||
{
|
||||
// let clientTemplatePath = "template/client.template";
|
||||
// if (fs.existsSync(clientTemplatePath)) {
|
||||
//读取文件内容
|
||||
let content = clientServiceTemplate;//fs.readFileSync(clientTemplatePath, "utf8");
|
||||
|
||||
let area1 = genManualAreaCode("$area1", cinfo);
|
||||
let area2 = genManualAreaCode("$area2", cinfo);
|
||||
let area3 = genManualAreaCode("$area3", cinfo);
|
||||
let onRegister = genManualAreaCode("$onRegister", cinfo);
|
||||
|
||||
content = content.replace(/\{path\}/g, url);
|
||||
content = content.replace(/\{createTime\}/g, createTime);
|
||||
content = content.replace(/\{className\}/g, className);
|
||||
content = content.replace(/\{c2sfunctions\}/g, sends.join(`\n\t\t`));
|
||||
content = content.replace(/\{s2cfunctions\}/g, parseRecvs(recvs, cinfo));
|
||||
content = content.replace(/\{onRegister\}/g, onRegister);
|
||||
content = content.replace(/\{regMsg\}/g, regs.join(`\n\t\t\t`));
|
||||
content = content.replace(/\{area1\}/g, area1);
|
||||
content = content.replace(/\{area2\}/g, area2);
|
||||
content = content.replace(/\{area3\}/g, area3);
|
||||
|
||||
return content;
|
||||
// }
|
||||
// return "the template file load failed";
|
||||
}
|
||||
|
||||
function parseRecvs(recvs: string[], cinfo)
|
||||
{
|
||||
return recvs.map(recv => {
|
||||
return recv.replace(/[/][*][|]([$_a-zA-Z0-9]+)[|][*][/]/, (rep, hander) => {
|
||||
console.log(rep, hander);
|
||||
return genManualAreaCode(hander, cinfo);
|
||||
})
|
||||
}).join(`\n\t\t`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取http数据
|
||||
*/
|
||||
function getHttpData(url: string, gcfg?: GlobalCfg)
|
||||
{
|
||||
let promise = new Promise((resolve, reject) => {
|
||||
let req = http.get(url, res => {
|
||||
let size = 0;
|
||||
let chunks: Buffer[] = [];
|
||||
res.on("data", (chunk: Buffer) => {
|
||||
size += chunk.length;
|
||||
chunks.push(chunk);
|
||||
});
|
||||
res.on("end", () => {
|
||||
let data = Buffer.concat(chunks, size);
|
||||
resolve({ content: data.toString("utf8"), gcfg: gcfg, url: url });
|
||||
});
|
||||
});
|
||||
req.on("error", (err) => {
|
||||
reject(err.message);
|
||||
});
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提取Proto数据
|
||||
*/
|
||||
function getProtoData(data: { content: string, gcfg?: GlobalCfg, url: string })
|
||||
{
|
||||
let content = escapeHTML(data.content);
|
||||
// 从HTML流中截取 message {} 或者 option (xxxx) = "xxxx" 这样的数据
|
||||
let reg: RegExp = /<pre class="code">([^>]*?message[ ]+[A-Z][a-zA-Z0-9_$]*[ ]*[{][^]*?[}][^]*?|[^>]*?option[ ]+[(]\w+[)][ ]*=[ ]*".*?";[^]*?)<\/pre>/mg;
|
||||
let proto = "";
|
||||
while (true) {
|
||||
let result = reg.exec(content);
|
||||
if (result) {
|
||||
proto += result[1] + "\n";
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
proto =proto.substring(proto.indexOf("option "));
|
||||
$g("txtProto").value = proto;
|
||||
parseProto(proto, data.gcfg);
|
||||
}
|
||||
|
||||
const escChars = { "<": "<", ">": ">", """: "\"", "'": "\'", "&": "&", " ": " ", "
": "\n", "'": "\'", "\\n": "\n"};
|
||||
function escapeHTML(content: string) {
|
||||
return content.replace(/<|>|"|'|&| |
/g, substring => {
|
||||
return escChars[substring];
|
||||
});
|
||||
}
|
||||
|
||||
function escapeString(content: string) {
|
||||
return content.replace(/<|>|"|'|&| |
|'|\\n/g, substring => {
|
||||
return escChars[substring];
|
||||
});
|
||||
}
|
||||
|
||||
function getProtoFromHttp(url: string, gcfg?: GlobalCfg)
|
||||
{
|
||||
let promise = getHttpData(url, gcfg);
|
||||
promise.then(getProtoData, error).catch(error);
|
||||
}
|
||||
|
||||
function getUrlErrorCode(data) {
|
||||
let clientConst = [];
|
||||
//先尝试读取客户端的常量文件
|
||||
const FileName = "MsgConst.ts";
|
||||
let gcfg = data.gcfg;
|
||||
let tsDict:{[title:string]: {code: string, desc: string}[]} = {};
|
||||
let url;
|
||||
let titles = [];
|
||||
let content = escapeHTML(data.content);
|
||||
let reg = /<h\d+\sclass="sectionedit\d+"\sid=".*?">(.*?)[|](.*?)<\/h\d+>\s+<div\sclass="level\d+">\s+<pre\sclass="code">([\s\S]*?)<\/pre>/mg;
|
||||
let titleComments = {};
|
||||
let retdata: {[code: string]: string} = {};
|
||||
const tempChars = { "\\n": "\n"};
|
||||
|
||||
while (true) {
|
||||
let result = reg.exec(content);
|
||||
if (result) {
|
||||
let [,titleComment, title, code] = result;
|
||||
if (code) {
|
||||
if (!~titles.indexOf(title)) {
|
||||
titles.push(title);
|
||||
titleComments[title] = titleComment;
|
||||
let codes:{code: string, desc: string}[] = [];
|
||||
tsDict[title] = codes;
|
||||
let data = code.replace(/\r/g, "").split(/\n/g);
|
||||
data.forEach(str=>{
|
||||
let temp = str.split(/\s+/);
|
||||
let c = temp[0];
|
||||
let d = escapeString(str.substring(c.length + 1));
|
||||
if (c){
|
||||
if (isNaN(Number(c))){
|
||||
error(`【定义错误】${title}中Code码key[${c}]必须是数字`)
|
||||
}
|
||||
else if (retdata[c]) {
|
||||
error(`【定义重复】${title}中Code码key[${c}]已经定义`)
|
||||
}else{
|
||||
retdata[c] = d;
|
||||
codes.push({code: c, desc: d});
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
titles.forEach(title => {
|
||||
let map = tsDict[title];
|
||||
if (map.length > 0) {
|
||||
clientConst.push(`/** ${titleComments[title]} */`);
|
||||
clientConst.push(`const enum $${title} {`);
|
||||
map.forEach(item => {
|
||||
clientConst.push(`\t/** ${item.desc} */`);
|
||||
clientConst.push(`\t$${item.code} = ${item.code},`);
|
||||
});
|
||||
clientConst.push(`}`);
|
||||
}
|
||||
});
|
||||
let clientCode = clientConst.join("\n");
|
||||
if (gcfg.cprefix) {
|
||||
url = path.join(gcfg.cprefix, FileName);
|
||||
fs.writeFileSync(url, clientCode);
|
||||
} else {
|
||||
error(`没有【客户端项目根目录(src)】地址,保存客户端代码失败`);
|
||||
}
|
||||
console.log(clientCode);
|
||||
log(`<font color="#0c0">开始生成errorcode</font>`);
|
||||
let txtLocalCodePath = cookieForPath.setPathCookie("txtLocalCodePath", false, false);
|
||||
if (txtLocalCodePath){
|
||||
let codedata = JSON.stringify(retdata);
|
||||
url = path.join(txtLocalCodePath, "code.json");
|
||||
fs.writeFileSync(url, codedata);
|
||||
// url = path.join(txtLocalCodePath, "code.js");
|
||||
// fs.writeFileSync(url, "var $errorcode =" + codedata);
|
||||
}
|
||||
else {
|
||||
error("保存code.js数据文件失败,没有填写存储地址");
|
||||
}
|
||||
log(`<font color="#0c0">生成errorcode结束</font>`);
|
||||
}
|
||||
|
||||
const cookieForPath = new CookieForPath("protocal_history_");
|
||||
|
||||
ready(() =>
|
||||
{
|
||||
cookieForPath.getPathCookie("txtClientPath");
|
||||
cookieForPath.getPathCookie("txtServerServiceNamePath");
|
||||
cookieForPath.getPathCookie("txtPBMsgDictName");
|
||||
cookieForPath.getPathCookie("txtUrl");
|
||||
cookieForPath.getPathCookie("txtWikiCodePath");
|
||||
cookieForPath.getPathCookie("txtLocalCodePath");
|
||||
$g("btnGen").addEventListener("click", (ev) => {
|
||||
let cPath = cookieForPath.setPathCookie("txtClientPath");
|
||||
let serviceName = cookieForPath.setPathCookie("txtServerServiceNamePath", false, false) || "ServiceName.ts";
|
||||
let pBMsgDictName = cookieForPath.setPathCookie("txtPBMsgDictName", false, false) || "PBMsgDict.ts";
|
||||
let url: string = cookieForPath.setPathCookie("txtUrl", false, false);
|
||||
url = url ? url.trim() : "";
|
||||
if (!url){
|
||||
error("请输入wiki protocol地址");
|
||||
return;
|
||||
}
|
||||
// 检查url路径
|
||||
let gcfg: GlobalCfg = { cprefix: cPath, url: url, serviceName: serviceName, pBMsgDictName: pBMsgDictName };
|
||||
getProtoFromHttp(url, gcfg);
|
||||
});
|
||||
$g("btnCode").addEventListener("click", (ev) => {
|
||||
let cPath = cookieForPath.setPathCookie("txtClientPath");
|
||||
let txtWikiCodePath = cookieForPath.setPathCookie("txtWikiCodePath", false, false);
|
||||
let txtLocalCodePath = cookieForPath.setPathCookie("txtLocalCodePath", false, false);
|
||||
if (!txtWikiCodePath) {
|
||||
error(`code wiki url 不能为空`);
|
||||
return;
|
||||
}
|
||||
if (!txtLocalCodePath) {
|
||||
error(`code 存储 url 不能为空`);
|
||||
return ;
|
||||
}
|
||||
// if (!cPath) {
|
||||
// error(`code 存储 url 为空, 没有保存客户端代码文件`);
|
||||
// }
|
||||
// 检查url路径
|
||||
let gcfg: GlobalCfg = { cprefix: cPath };
|
||||
let urlErrorPromise = getHttpData(txtWikiCodePath, gcfg);
|
||||
urlErrorPromise.then(getUrlErrorCode, error).catch(error);
|
||||
})
|
||||
});
|
||||
|
||||
/**
|
||||
* 创建一个代码区
|
||||
*/
|
||||
// function createContent(parent: HTMLElement, filename: string, idx: number, ccode: string) {
|
||||
// let pane = document.createElement("div");
|
||||
// pane.style.border = "#000 solid 1px";
|
||||
// let idCopyClient = "btnCopyClient" + idx;
|
||||
// let template = `<div>${filename}</div>
|
||||
// <div style="width:50%;height:50%;float:left;background:#eef">
|
||||
// 客户端代码:<input type="button" value="复制客户端代码" id="${idCopyClient}" />
|
||||
// <textarea style="width:100%;height:200px;border:#ccf solid 1px;background:#eee" contenteditable="false">${ccode}</textarea>
|
||||
// </div>`
|
||||
// pane.innerHTML = template;
|
||||
// parent.appendChild(pane);
|
||||
// $g(idCopyClient).addEventListener("click", e => {
|
||||
// clipboard.writeText(ccode);
|
||||
// });
|
||||
// }
|
||||
|
||||
/** 手写代码的默认提示 */
|
||||
const ManualCodeDefaultComment =
|
||||
{
|
||||
/** 这里手写类上方的内容 */
|
||||
$area1: "@这里手写的内容,请在注释begin 和 end 之间编写自己的代码,不可更改此注释@",
|
||||
/** 这里手写类里面的内容 */
|
||||
$area2: "@这里手写的内容,请在注释begin 和 end 之间编写自己的代码,不可更改此注释@",
|
||||
/** 这里手写类下的内容 */
|
||||
$area3: "@这里手写的内容,请在注释begin 和 end 之间编写自己的代码,不可更改此注释@",
|
||||
/** 这里手写onRegister中内容 */
|
||||
$onRegister: "@这里手写的内容,请在注释begin 和 end 之间编写自己的代码,不可更改此注释@",
|
||||
/** 这里手写方法中的内容 */
|
||||
$handler: "@这里手写的内容,请在注释begin 和 end 之间编写自己的代码,不可更改此注释@",
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成手动代码区域的文本
|
||||
*/
|
||||
function genManualAreaCode(key: string, cinfo: { [index: string]: string })
|
||||
{
|
||||
let manual = cinfo[key];
|
||||
let tab = "\t";
|
||||
let btab = "";
|
||||
let desc = ManualCodeDefaultComment[key] || ManualCodeDefaultComment.$handler;
|
||||
if (key in ManualCodeDefaultComment) {
|
||||
if (key == "$onRegister") tab = "\t\t\t";
|
||||
else if (key == "$area2") tab = "\t\t";
|
||||
} else {
|
||||
tab = "\t\t\t";
|
||||
btab = "\t";
|
||||
}
|
||||
return `${btab}/*-*begin ${key} ${desc}*-*/
|
||||
${tab}${manual ? manual : ""}
|
||||
${tab}/*-*end ${key}*-*/`
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取手动写的代码信息
|
||||
*/
|
||||
function getManualCodeInfo(file: string) {
|
||||
let dict: { [index: string]: string } = {};
|
||||
if (file && fs.existsSync(file)) {
|
||||
//读取文件内容
|
||||
let content = fs.readFileSync(file, "utf8");
|
||||
//找到手写内容
|
||||
let reg = /[/][*]-[*]begin[ ]([$_a-zA-Z0-9]+)[ ](.*?)[*]-[*][/]([^]*?)[/][*]-[*]end[ ]([$_a-zA-Z0-9]+)[*]-[*][/]/g
|
||||
console.log("*****************************start");
|
||||
while (true) {
|
||||
let result = reg.exec(content);
|
||||
if (result) {
|
||||
let key = result[1];
|
||||
let manual = result[3].trim();
|
||||
console.log(key, manual);
|
||||
if (!manual) {//没有注释
|
||||
continue;
|
||||
}
|
||||
dict[key] = manual;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log("=================================");
|
||||
console.log(dict);
|
||||
console.log("=================================");
|
||||
return dict;
|
||||
}
|
||||
|
||||
////////////////////////template///////////////////
|
||||
|
||||
var clientServiceTemplate = `
|
||||
/**
|
||||
* 来源: {path}
|
||||
*/
|
||||
module giant.chuanqi
|
||||
{
|
||||
{area1}
|
||||
|
||||
export class {className} extends Service
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
super(ServiceName.{className});
|
||||
}
|
||||
|
||||
onRegister()
|
||||
{
|
||||
super.onRegister();
|
||||
|
||||
let self = this;
|
||||
|
||||
{regMsg}
|
||||
|
||||
{onRegister}
|
||||
}
|
||||
|
||||
{c2sfunctions}
|
||||
|
||||
{s2cfunctions}
|
||||
|
||||
{area2}
|
||||
|
||||
}
|
||||
|
||||
{area3}
|
||||
|
||||
}
|
||||
`;
|
||||
|
||||
var clientMsgTemplate = `
|
||||
/**
|
||||
* 源地址: {path}
|
||||
*/
|
||||
module giant.chuanqi
|
||||
{
|
||||
export interface {className}
|
||||
{
|
||||
|
||||
{vars}
|
||||
|
||||
}
|
||||
}
|
||||
`;
|
5361
src/protobuf.js
Normal file
5361
src/protobuf.js
Normal file
File diff suppressed because it is too large
Load Diff
16
test/client/src/PBMsgDict.ts
Normal file
16
test/client/src/PBMsgDict.ts
Normal file
@ -0,0 +1,16 @@
|
||||
const PBMsgDict = {
|
||||
LoginCreate_C2S_Msg: { 1: ["userId", 2, 9], 2: ["name", 2, 9], 3: ["job", 2, 9], 4: ["pid", 2, 9], 5: ["serverId", 2, 5], 6: ["gender", 2, 5] },
|
||||
LoginCreate_S2C_Msg: { 1: ["code", 2, 11, "Code"], 2: ["roleDTO", 1, 11, "RoleDTO"] },
|
||||
LoginGetList_C2S_Msg: { 1: ["userId", 2, 9], 2: ["serverId", 2, 5], 3: ["pid", 2, 9], 4: ["loginType", 2, 5] },
|
||||
LoginGetList_S2C_Msg: { 1: ["code", 2, 11, "Code"], 2: ["roleDTO", 1, 11, "RoleDTO"], 3: ["serverInfoDTO", 1, 11, "ServerInfoDTO"] },
|
||||
LoginRoleKicked_S2C_Msg: { 1: ["code", 2, 11, "Code"] },
|
||||
LoginRole_C2S_Msg: { 1: ["roleId", 2, 3] },
|
||||
LoginRole_S2C_Msg: { 1: ["code", 2, 11, "Code"] },
|
||||
RoleCreate_C2S_Msg: { 1: ["userId", 2, 9], 2: ["name", 2, 9], 3: ["job", 2, 9], 4: ["pid", 2, 9], 5: ["serverId", 2, 5] },
|
||||
RoleCreate_S2C_Msg: { 1: ["code", 2, 11, "Code"], 2: ["roleDTO", 1, 11, "RoleDTO"] },
|
||||
RoleGetList_C2S_Msg: { 1: ["userId", 2, 9], 2: ["serverId", 2, 5] },
|
||||
RoleGetList_S2C_Msg: { 1: ["code", 2, 11, "Code"], 2: ["roleDTO", 1, 11, "RoleDTO"] },
|
||||
RoleKicked_S2C_Msg: { 1: ["code", 2, 11, "Code"] },
|
||||
RoleLogin_C2S_Msg: { 1: ["roleId", 2, 3] },
|
||||
RoleLogin_S2C_Msg: { 1: ["code", 2, 11, "Code"] }
|
||||
}
|
3
test/client/src/ServiceName.ts
Normal file
3
test/client/src/ServiceName.ts
Normal file
@ -0,0 +1,3 @@
|
||||
const enum ServiceName {
|
||||
$ = 0,
abLoginService,
bLoginService,
dfLoginService,
dLoginService,
LoginService
|
||||
}
|
36
test/client/src/chuanqi/login/LoginCreate_C2S_Msg.ts
Normal file
36
test/client/src/chuanqi/login/LoginCreate_C2S_Msg.ts
Normal file
@ -0,0 +1,36 @@
|
||||
|
||||
/**
|
||||
* 源地址: http://192.168.116.77/dokuwiki/doku.php?id=%E7%99%BB%E5%BD%95_1001-1100
|
||||
*/
|
||||
module giant.chuanqi
|
||||
{
|
||||
export interface LoginCreate_C2S_Msg
|
||||
{
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
userId: string;
|
||||
/**
|
||||
* 角色名
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* 职业
|
||||
*/
|
||||
job: string;
|
||||
/**
|
||||
* 平台id
|
||||
*/
|
||||
pid: string;
|
||||
/**
|
||||
* 服务器id
|
||||
*/
|
||||
serverId: number;
|
||||
/**
|
||||
* 性别
|
||||
*/
|
||||
gender: number;
|
||||
|
||||
}
|
||||
}
|
20
test/client/src/chuanqi/login/LoginCreate_S2C_Msg.ts
Normal file
20
test/client/src/chuanqi/login/LoginCreate_S2C_Msg.ts
Normal file
@ -0,0 +1,20 @@
|
||||
|
||||
/**
|
||||
* 源地址: http://192.168.116.77/dokuwiki/doku.php?id=%E7%99%BB%E5%BD%95_1001-1100
|
||||
*/
|
||||
module giant.chuanqi
|
||||
{
|
||||
export interface LoginCreate_S2C_Msg
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
code: Code;
|
||||
/**
|
||||
* 可选参数
|
||||
*/
|
||||
roleDTO?: RoleDTO;
|
||||
|
||||
}
|
||||
}
|
28
test/client/src/chuanqi/login/LoginGetList_C2S_Msg.ts
Normal file
28
test/client/src/chuanqi/login/LoginGetList_C2S_Msg.ts
Normal file
@ -0,0 +1,28 @@
|
||||
|
||||
/**
|
||||
* 源地址: http://192.168.116.77/dokuwiki/doku.php?id=%E7%99%BB%E5%BD%95_1001-1100
|
||||
*/
|
||||
module giant.chuanqi
|
||||
{
|
||||
export interface LoginGetList_C2S_Msg
|
||||
{
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
userId: string;
|
||||
/**
|
||||
* 服务器id
|
||||
*/
|
||||
serverId: number;
|
||||
/**
|
||||
* 平台id
|
||||
*/
|
||||
pid: string;
|
||||
/**
|
||||
* 登录类型
|
||||
*/
|
||||
loginType: number;
|
||||
|
||||
}
|
||||
}
|
24
test/client/src/chuanqi/login/LoginGetList_S2C_Msg.ts
Normal file
24
test/client/src/chuanqi/login/LoginGetList_S2C_Msg.ts
Normal file
@ -0,0 +1,24 @@
|
||||
|
||||
/**
|
||||
* 源地址: http://192.168.116.77/dokuwiki/doku.php?id=%E7%99%BB%E5%BD%95_1001-1100
|
||||
*/
|
||||
module giant.chuanqi
|
||||
{
|
||||
export interface LoginGetList_S2C_Msg
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
code: Code;
|
||||
/**
|
||||
* 可选参数
|
||||
*/
|
||||
roleDTO?: RoleDTO;
|
||||
/**
|
||||
* 可选参数
|
||||
*/
|
||||
serverInfoDTO?: ServerInfoDTO;
|
||||
|
||||
}
|
||||
}
|
16
test/client/src/chuanqi/login/LoginRoleKicked_S2C_Msg.ts
Normal file
16
test/client/src/chuanqi/login/LoginRoleKicked_S2C_Msg.ts
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
/**
|
||||
* 源地址: http://192.168.116.77/dokuwiki/doku.php?id=%E7%99%BB%E5%BD%95_1001-1100
|
||||
*/
|
||||
module giant.chuanqi
|
||||
{
|
||||
export interface LoginRoleKicked_S2C_Msg
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
code: Code;
|
||||
|
||||
}
|
||||
}
|
16
test/client/src/chuanqi/login/LoginRole_C2S_Msg.ts
Normal file
16
test/client/src/chuanqi/login/LoginRole_C2S_Msg.ts
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
/**
|
||||
* 源地址: http://192.168.116.77/dokuwiki/doku.php?id=%E7%99%BB%E5%BD%95_1001-1100
|
||||
*/
|
||||
module giant.chuanqi
|
||||
{
|
||||
export interface LoginRole_C2S_Msg
|
||||
{
|
||||
|
||||
/**
|
||||
* 角色id
|
||||
*/
|
||||
roleId: number;
|
||||
|
||||
}
|
||||
}
|
16
test/client/src/chuanqi/login/LoginRole_S2C_Msg.ts
Normal file
16
test/client/src/chuanqi/login/LoginRole_S2C_Msg.ts
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
/**
|
||||
* 源地址: http://192.168.116.77/dokuwiki/doku.php?id=%E7%99%BB%E5%BD%95_1001-1100
|
||||
*/
|
||||
module giant.chuanqi
|
||||
{
|
||||
export interface LoginRole_S2C_Msg
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
code: Code;
|
||||
|
||||
}
|
||||
}
|
87
test/client/src/chuanqi/login/LoginService.ts
Normal file
87
test/client/src/chuanqi/login/LoginService.ts
Normal file
@ -0,0 +1,87 @@
|
||||
|
||||
/**
|
||||
* 来源: http://192.168.116.77/dokuwiki/doku.php?id=%E7%99%BB%E5%BD%95_1001-1100
|
||||
*/
|
||||
module giant.chuanqi
|
||||
{
|
||||
/*-*begin $area1 @这里手写的内容,请在注释begin 和 end 之间编写自己的代码,不可更改此注释@*-*/
|
||||
//area1
|
||||
/*-*end $area1*-*/
|
||||
|
||||
export class LoginService extends Service
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
super(ServiceName.LoginService);
|
||||
}
|
||||
|
||||
onRegister()
|
||||
{
|
||||
super.onRegister();
|
||||
|
||||
this.regMsg("LoginGetList_S2C_Msg", 1001);
|
||||
this.regHandler(this.loginGetList_S2C, 1001);
|
||||
this.regMsg("LoginCreate_S2C_Msg", 1002);
|
||||
this.regHandler(this.loginCreate_S2C, 1002);
|
||||
this.regMsg("LoginRole_S2C_Msg", 1003);
|
||||
this.regHandler(this.loginRole_S2C, 1003);
|
||||
this.regMsg("LoginRoleKicked_S2C_Msg", 1004);
|
||||
this.regHandler(this.loginRoleKicked_S2C, 1004);
|
||||
|
||||
/*-*begin $onRegister @这里手写的内容,请在注释begin 和 end 之间编写自己的代码,不可更改此注释@*-*/
|
||||
this.regMsg("LoginRoleKickesd_S2C_Msg", 1006);
|
||||
this.regHandler(this.loginRoleKickesd_S2C, 1006);
|
||||
/*-*end $onRegister*-*/
|
||||
}
|
||||
|
||||
public loginGetList_C2S(_LoginGetList_C2S_Msg: LoginGetList_C2S_Msg) {
|
||||
this.send(1001, _LoginGetList_C2S_Msg, "LoginGetList_C2S_Msg");
|
||||
}
|
||||
public loginCreate_C2S(_LoginCreate_C2S_Msg: LoginCreate_C2S_Msg) {
|
||||
this.send(1002, _LoginCreate_C2S_Msg, "LoginCreate_C2S_Msg");
|
||||
}
|
||||
public loginRole_C2S(_LoginRole_C2S_Msg: LoginRole_C2S_Msg) {
|
||||
this.send(1003, _LoginRole_C2S_Msg, "LoginRole_C2S_Msg");
|
||||
}
|
||||
|
||||
protected loginGetList_S2C = (data:NetData) => {
|
||||
let msg:LoginGetList_S2C_Msg = <LoginGetList_S2C_Msg>data.data;
|
||||
/*-*begin $loginGetList_S2C @这里手写的内容,请在注释begin 和 end 之间编写自己的代码,不可更改此注释@*-*/
|
||||
//loginGetList_S2C
|
||||
if (!checkSuccess(msg)) return ;
|
||||
/*-*end $loginGetList_S2C*-*/
|
||||
}
|
||||
protected loginCreate_S2C = (data:NetData) => {
|
||||
let msg:LoginCreate_S2C_Msg = <LoginCreate_S2C_Msg>data.data;
|
||||
/*-*begin $loginCreate_S2C @这里手写的内容,请在注释begin 和 end 之间编写自己的代码,不可更改此注释@*-*/
|
||||
//loginCreate_S2C
|
||||
if (!checkSuccess(msg)) return ;
|
||||
/*-*end $loginCreate_S2C*-*/
|
||||
}
|
||||
protected loginRole_S2C = (data:NetData) => {
|
||||
let msg:LoginRole_S2C_Msg = <LoginRole_S2C_Msg>data.data;
|
||||
/*-*begin $loginRole_S2C @这里手写的内容,请在注释begin 和 end 之间编写自己的代码,不可更改此注释@*-*/
|
||||
//loginRole_S2C
|
||||
if (!checkSuccess(msg)) return ;
|
||||
/*-*end $loginRole_S2C*-*/
|
||||
}
|
||||
protected loginRoleKicked_S2C = (data:NetData) => {
|
||||
let msg:LoginRoleKicked_S2C_Msg = <LoginRoleKicked_S2C_Msg>data.data;
|
||||
/*-*begin $loginRoleKicked_S2C @这里手写的内容,请在注释begin 和 end 之间编写自己的代码,不可更改此注释@*-*/
|
||||
//loginRoleKicked_S2C
|
||||
if (!checkSuccess(msg)) return ;
|
||||
/*-*end $loginRoleKicked_S2C*-*/
|
||||
}
|
||||
|
||||
/*-*begin $area2 @这里手写的内容,请在注释begin 和 end 之间编写自己的代码,不可更改此注释@*-*/
|
||||
//area2
|
||||
private testVar = 10;
|
||||
/*-*end $area2*-*/
|
||||
|
||||
}
|
||||
|
||||
/*-*begin $area3 @这里手写的内容,请在注释begin 和 end 之间编写自己的代码,不可更改此注释@*-*/
|
||||
//area3
|
||||
/*-*end $area3*-*/
|
||||
|
||||
}
|
16
test/client/src/chuanqi/map/msgs/ChangeStage_C2S_Msg.ts
Normal file
16
test/client/src/chuanqi/map/msgs/ChangeStage_C2S_Msg.ts
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
/**
|
||||
* 源地址: http://legend.uclub.xyz/dokuwiki/doku.php?id=%E7%8E%A9%E5%AE%B6%E5%9C%BA%E6%99%AF%E6%8C%87%E4%BB%A4_1201-1250
|
||||
*/
|
||||
module giant.chuanqi
|
||||
{
|
||||
export interface ChangeStage_C2S_Msg
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
mapId: number;
|
||||
|
||||
}
|
||||
}
|
36
test/client/src/chuanqi/map/msgs/ChangeStage_S2C_Msg.ts
Normal file
36
test/client/src/chuanqi/map/msgs/ChangeStage_S2C_Msg.ts
Normal file
@ -0,0 +1,36 @@
|
||||
|
||||
/**
|
||||
* 源地址: http://legend.uclub.xyz/dokuwiki/doku.php?id=%E7%8E%A9%E5%AE%B6%E5%9C%BA%E6%99%AF%E6%8C%87%E4%BB%A4_1201-1250
|
||||
*/
|
||||
module giant.chuanqi
|
||||
{
|
||||
export interface ChangeStage_S2C_Msg
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
code: Code;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
mapId: number;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
line: number;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
x: number;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
y: number;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
mapType: number;
|
||||
|
||||
}
|
||||
}
|
73
test/client/src/chuanqi/map/msgs/MapService.ts
Normal file
73
test/client/src/chuanqi/map/msgs/MapService.ts
Normal file
@ -0,0 +1,73 @@
|
||||
|
||||
/**
|
||||
* 来源: http://legend.uclub.xyz/dokuwiki/doku.php?id=%E7%8E%A9%E5%AE%B6%E5%9C%BA%E6%99%AF%E6%8C%87%E4%BB%A4_1201-1250
|
||||
*/
|
||||
module giant.chuanqi
|
||||
{
|
||||
/*-*begin $area1 @这里手写的内容,请在注释begin 和 end 之间编写自己的代码,不可更改此注释@*-*/
|
||||
|
||||
/*-*end $area1*-*/
|
||||
|
||||
export class MapService extends Service
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
super(ServiceName.MapService);
|
||||
}
|
||||
|
||||
onRegister()
|
||||
{
|
||||
super.onRegister();
|
||||
|
||||
this.regMsg("ChangeStage_S2C_Msg", 1201);
|
||||
this.regHandler(this.changeStage_S2C, 1201);
|
||||
this.regMsg("Move_Msg", 1202);
|
||||
this.regHandler(this.move_S2C, 1202);
|
||||
this.regMsg("Teleport_Msg", 1203);
|
||||
this.regHandler(this.teleport_S2C, 1203);
|
||||
|
||||
/*-*begin $onRegister @这里手写的内容,请在注释begin 和 end 之间编写自己的代码,不可更改此注释@*-*/
|
||||
|
||||
/*-*end $onRegister*-*/
|
||||
}
|
||||
|
||||
public changeStage_C2S(_ChangeStage_C2S_Msg: ChangeStage_C2S_Msg) {
|
||||
this.send(1201, _ChangeStage_C2S_Msg, "ChangeStage_C2S_Msg");
|
||||
}
|
||||
public move_C2S(_Move_Msg: Move_Msg) {
|
||||
this.send(1202, _Move_Msg, "Move_Msg");
|
||||
}
|
||||
public teleport_C2S(_Teleport_Msg: Teleport_Msg) {
|
||||
this.send(1203, _Teleport_Msg, "Teleport_Msg");
|
||||
}
|
||||
|
||||
protected changeStage_S2C = (data:NetData) => {
|
||||
let msg:ChangeStage_S2C_Msg = <ChangeStage_S2C_Msg>data.data;
|
||||
/*-*begin $changeStage_S2C @这里手写的内容,请在注释begin 和 end 之间编写自己的代码,不可更改此注释@*-*/
|
||||
|
||||
/*-*end $changeStage_S2C*-*/
|
||||
}
|
||||
protected move_S2C = (data:NetData) => {
|
||||
let msg:Move_Msg = <Move_Msg>data.data;
|
||||
/*-*begin $move_S2C @这里手写的内容,请在注释begin 和 end 之间编写自己的代码,不可更改此注释@*-*/
|
||||
|
||||
/*-*end $move_S2C*-*/
|
||||
}
|
||||
protected teleport_S2C = (data:NetData) => {
|
||||
let msg:Teleport_Msg = <Teleport_Msg>data.data;
|
||||
/*-*begin $teleport_S2C @这里手写的内容,请在注释begin 和 end 之间编写自己的代码,不可更改此注释@*-*/
|
||||
|
||||
/*-*end $teleport_S2C*-*/
|
||||
}
|
||||
|
||||
/*-*begin $area2 @这里手写的内容,请在注释begin 和 end 之间编写自己的代码,不可更改此注释@*-*/
|
||||
|
||||
/*-*end $area2*-*/
|
||||
|
||||
}
|
||||
|
||||
/*-*begin $area3 @这里手写的内容,请在注释begin 和 end 之间编写自己的代码,不可更改此注释@*-*/
|
||||
|
||||
/*-*end $area3*-*/
|
||||
|
||||
}
|
36
test/client/src/chuanqi/map/msgs/Move_Msg.ts
Normal file
36
test/client/src/chuanqi/map/msgs/Move_Msg.ts
Normal file
@ -0,0 +1,36 @@
|
||||
|
||||
/**
|
||||
* 源地址: http://legend.uclub.xyz/dokuwiki/doku.php?id=%E7%8E%A9%E5%AE%B6%E5%9C%BA%E6%99%AF%E6%8C%87%E4%BB%A4_1201-1250
|
||||
*/
|
||||
module giant.chuanqi
|
||||
{
|
||||
export interface Move_Msg
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
id: number;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
fromX: number;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
fromY: number;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
toX: number;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
toY: number;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
faceTo: number;
|
||||
|
||||
}
|
||||
}
|
24
test/client/src/chuanqi/map/msgs/Teleport_Msg.ts
Normal file
24
test/client/src/chuanqi/map/msgs/Teleport_Msg.ts
Normal file
@ -0,0 +1,24 @@
|
||||
|
||||
/**
|
||||
* 源地址: http://legend.uclub.xyz/dokuwiki/doku.php?id=%E7%8E%A9%E5%AE%B6%E5%9C%BA%E6%99%AF%E6%8C%87%E4%BB%A4_1201-1250
|
||||
*/
|
||||
module giant.chuanqi
|
||||
{
|
||||
export interface Teleport_Msg
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
id: number;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
x: number;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
y: number;
|
||||
|
||||
}
|
||||
}
|
81
test/client/src/code/service/LoginService.ts
Normal file
81
test/client/src/code/service/LoginService.ts
Normal file
@ -0,0 +1,81 @@
|
||||
|
||||
/**
|
||||
* 来源: http://192.168.116.77/dokuwiki/doku.php?id=%E7%99%BB%E5%BD%95_1001-1100
|
||||
*/
|
||||
module giant.chuanqi
|
||||
{
|
||||
/*-*begin $area1 @这里手写的内容,请在注释begin 和 end 之间编写自己的代码,不可更改此注释@*-*/
|
||||
|
||||
/*-*end $area1*-*/
|
||||
|
||||
export class LoginService extends Service
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
super(ServiceName.LoginService);
|
||||
}
|
||||
|
||||
onRegister()
|
||||
{
|
||||
super.onRegister();
|
||||
|
||||
this.regMsg("RoleGetList_S2C_Msg", );
|
||||
this.regHandler(this.roleGetList_S2C, );
|
||||
this.regMsg("RoleCreate_S2C_Msg", );
|
||||
this.regHandler(this.roleCreate_S2C, );
|
||||
this.regMsg("Code", );
|
||||
this.regHandler(this.roleLogin_S2C, );
|
||||
this.regMsg("Code", 1004);
|
||||
this.regHandler(this.roleKicked_S2C, 1004);
|
||||
|
||||
/*-*begin $onRegister @这里手写的内容,请在注释begin 和 end 之间编写自己的代码,不可更改此注释@*-*/
|
||||
|
||||
/*-*end $onRegister*-*/
|
||||
}
|
||||
|
||||
public roleGetList_C2S(_RoleGetList_C2S_Msg: RoleGetList_C2S_Msg) {
|
||||
this.send(1001, _RoleGetList_C2S_Msg, "RoleGetList_C2S_Msg");
|
||||
}
|
||||
public roleCreate_C2S(_RoleCreate_C2S_Msg: RoleCreate_C2S_Msg) {
|
||||
this.send(1002, _RoleCreate_C2S_Msg, "RoleCreate_C2S_Msg");
|
||||
}
|
||||
public roleLogin_C2S(_roleId: number) {
|
||||
this.send(1003, _roleId, 5);
|
||||
}
|
||||
|
||||
protected roleGetList_S2C = (data:NetData) => {
|
||||
let msg:RoleGetList_S2C_Msg = <RoleGetList_S2C_Msg>data.data;
|
||||
/*-*begin roleGetList_S2C undefined*-*/
|
||||
|
||||
/*-*end roleGetList_S2C*-*/
|
||||
}
|
||||
protected roleCreate_S2C = (data:NetData) => {
|
||||
let msg:RoleCreate_S2C_Msg = <RoleCreate_S2C_Msg>data.data;
|
||||
/*-*begin roleCreate_S2C undefined*-*/
|
||||
|
||||
/*-*end roleCreate_S2C*-*/
|
||||
}
|
||||
protected roleLogin_S2C = (data:NetData) => {
|
||||
let _code: Code = <any>data.data;
|
||||
/*-*begin roleLogin_S2C undefined*-*/
|
||||
|
||||
/*-*end roleLogin_S2C*-*/
|
||||
}
|
||||
protected roleKicked_S2C = (data:NetData) => {
|
||||
let _code: Code = <any>data.data;
|
||||
/*-*begin roleKicked_S2C undefined*-*/
|
||||
|
||||
/*-*end roleKicked_S2C*-*/
|
||||
}
|
||||
|
||||
/*-*begin $area2 @这里手写的内容,请在注释begin 和 end 之间编写自己的代码,不可更改此注释@*-*/
|
||||
|
||||
/*-*end $area2*-*/
|
||||
|
||||
}
|
||||
|
||||
/*-*begin $area3 @这里手写的内容,请在注释begin 和 end 之间编写自己的代码,不可更改此注释@*-*/
|
||||
|
||||
/*-*end $area3*-*/
|
||||
|
||||
}
|
32
test/client/src/code/service/RoleCreate_C2S_Msg.ts
Normal file
32
test/client/src/code/service/RoleCreate_C2S_Msg.ts
Normal file
@ -0,0 +1,32 @@
|
||||
|
||||
/**
|
||||
* 源地址: http://192.168.116.77/dokuwiki/doku.php?id=%E7%99%BB%E5%BD%95_1001-1100
|
||||
*/
|
||||
module giant.chuanqi
|
||||
{
|
||||
export interface RoleCreate_C2S_Msg
|
||||
{
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
userId: string;
|
||||
/**
|
||||
* 角色名
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* 职业
|
||||
*/
|
||||
job: string;
|
||||
/**
|
||||
* 平台id
|
||||
*/
|
||||
pid: string;
|
||||
/**
|
||||
* 服务器id
|
||||
*/
|
||||
serverId: number;
|
||||
|
||||
}
|
||||
}
|
20
test/client/src/code/service/RoleCreate_S2C_Msg.ts
Normal file
20
test/client/src/code/service/RoleCreate_S2C_Msg.ts
Normal file
@ -0,0 +1,20 @@
|
||||
|
||||
/**
|
||||
* 源地址: http://192.168.116.77/dokuwiki/doku.php?id=%E7%99%BB%E5%BD%95_1001-1100
|
||||
*/
|
||||
module giant.chuanqi
|
||||
{
|
||||
export interface RoleCreate_S2C_Msg
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
code: Code;
|
||||
/**
|
||||
* 可选参数
|
||||
*/
|
||||
roleDTO?: RoleDTO;
|
||||
|
||||
}
|
||||
}
|
20
test/client/src/code/service/RoleGetList_C2S_Msg.ts
Normal file
20
test/client/src/code/service/RoleGetList_C2S_Msg.ts
Normal file
@ -0,0 +1,20 @@
|
||||
|
||||
/**
|
||||
* 源地址: http://192.168.116.77/dokuwiki/doku.php?id=%E7%99%BB%E5%BD%95_1001-1100
|
||||
*/
|
||||
module giant.chuanqi
|
||||
{
|
||||
export interface RoleGetList_C2S_Msg
|
||||
{
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
userId: string;
|
||||
/**
|
||||
* 服务器id
|
||||
*/
|
||||
serverId: number;
|
||||
|
||||
}
|
||||
}
|
20
test/client/src/code/service/RoleGetList_S2C_Msg.ts
Normal file
20
test/client/src/code/service/RoleGetList_S2C_Msg.ts
Normal file
@ -0,0 +1,20 @@
|
||||
|
||||
/**
|
||||
* 源地址: http://192.168.116.77/dokuwiki/doku.php?id=%E7%99%BB%E5%BD%95_1001-1100
|
||||
*/
|
||||
module giant.chuanqi
|
||||
{
|
||||
export interface RoleGetList_S2C_Msg
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
code: Code;
|
||||
/**
|
||||
* 可选参数
|
||||
*/
|
||||
roleDTO?: RoleDTO;
|
||||
|
||||
}
|
||||
}
|
0
test/client/src/code/service/RoleLogin_S2C_Msg.ts
Normal file
0
test/client/src/code/service/RoleLogin_S2C_Msg.ts
Normal file
17
tsconfig.json
Normal file
17
tsconfig.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "amd",
|
||||
"target": "es2015",
|
||||
"noImplicitAny": false,
|
||||
"sourceMap": false,
|
||||
"sourceRoot": "src",
|
||||
"outDir": "dist"
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"server",
|
||||
"ProtoTools",
|
||||
"client",
|
||||
"test"
|
||||
]
|
||||
}
|
43
typings/browser.d.ts
vendored
Normal file
43
typings/browser.d.ts
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
/// <reference path="browser/ambient/node/index.d.ts" />
|
||||
/// <reference path="browser/ambient/protobufjs/index.d.ts" />
|
||||
interface String {
|
||||
/**
|
||||
* 替换字符串中{0}{1}{2}{a} {b}这样的数据,用obj对应key替换,或者是数组中对应key的数据替换
|
||||
*/
|
||||
substitute(...args): string;
|
||||
}
|
||||
interface Date {
|
||||
/**
|
||||
* 格式化日期
|
||||
*/
|
||||
format(mask: string): string;
|
||||
}
|
||||
|
||||
// declare function ready(hander: () => void): void;
|
||||
declare var nodeRequire: any;
|
||||
|
||||
|
||||
interface cookiesUtils {
|
||||
/**
|
||||
* 设置cookie
|
||||
*
|
||||
* @param name
|
||||
* @param value
|
||||
*/
|
||||
setCookie(name: string, value: string);
|
||||
/**
|
||||
* 获取cookie
|
||||
*
|
||||
* @param name
|
||||
* @returns
|
||||
*/
|
||||
getCookie(name: string);
|
||||
/**
|
||||
* 删除cookie
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
delCookie(name: string);
|
||||
}
|
||||
|
||||
declare var cookie: cookiesUtils;
|
2346
typings/browser/ambient/node/index.d.ts
vendored
Normal file
2346
typings/browser/ambient/node/index.d.ts
vendored
Normal file
File diff suppressed because it is too large
Load Diff
390
typings/browser/ambient/protobufjs/index.d.ts
vendored
Normal file
390
typings/browser/ambient/protobufjs/index.d.ts
vendored
Normal file
@ -0,0 +1,390 @@
|
||||
// Generated by typings
|
||||
// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/protobufjs/protobufjs.d.ts
|
||||
// Type definitions for ProtoBuf.js
|
||||
// Project: https://github.com/dcodeIO/ProtoBuf.js
|
||||
// Definitions by: Panu Horsmalahti <https://github.com/panuhorsmalahti>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
|
||||
|
||||
declare namespace ProtoBuf {
|
||||
// ==========
|
||||
// protobufjs/src/ProtoBuf.js
|
||||
|
||||
var Builder: Builder;
|
||||
// var ByteBuffer: Buffer;
|
||||
var Long: LongStatic;
|
||||
var DotProto: DotProto;
|
||||
var Reflect: Reflect;
|
||||
|
||||
// var Lang: Lang; TODO: implement interface Lang
|
||||
// var Util: Util; TODO: implement interface Util
|
||||
|
||||
export function loadJson(json: string, builder?: ProtoBuilder,
|
||||
filename?: string): ProtoBuilder;
|
||||
|
||||
export function loadJsonFile(filename: string,
|
||||
callback?: (error: any, builder: ProtoBuilder) => void,
|
||||
builder?: ProtoBuilder): ProtoBuilder;
|
||||
|
||||
export function loadProto(proto: string, builder?: ProtoBuilder,
|
||||
filename?: string): ProtoBuilder;
|
||||
|
||||
export function loadProtoFile(filePath: string,
|
||||
callback?: (error: any, builder: ProtoBuilder) => void,
|
||||
builder?: ProtoBuilder): ProtoBuilder;
|
||||
|
||||
export function newBuilder(options?: {[key: string]: any}): ProtoBuilder;
|
||||
|
||||
export interface LongStatic {
|
||||
new(low?: number, high?: number, unsigned?:boolean): Long;
|
||||
|
||||
MAX_UNSIGNED_VALUE: Long;
|
||||
MAX_VALUE: Long;
|
||||
MIN_VALUE: Long;
|
||||
NEG_ONE: Long;
|
||||
ONE: Long;
|
||||
UONE: Long;
|
||||
UZERO: Long;
|
||||
ZERO: Long;
|
||||
|
||||
fromBits(lowBits: number, highBits: number, unsigned?: boolean): Long;
|
||||
fromInt(value: number, unsigned?: boolean): Long;
|
||||
fromNumber(value: number, unsigned?: boolean): Long;
|
||||
fromString(str: string, unsigned?: boolean | number, radix?: number): Long;
|
||||
fromValue(val: Long | number | string): Long;
|
||||
|
||||
isLong(obj: any): boolean;
|
||||
}
|
||||
|
||||
// Based on https://github.com/dcodeIO/Long.js and https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/long/long.d.ts
|
||||
export interface Long {
|
||||
high: number;
|
||||
low: number;
|
||||
unsigned :boolean;
|
||||
|
||||
add(other: Long | number | string): Long;
|
||||
and(other: Long | number | string): Long;
|
||||
compare(other: Long | number | string): number;
|
||||
div(divisor: Long | number | string): Long;
|
||||
equals(other: Long | number | string): boolean;
|
||||
getHighBits(): number;
|
||||
getHighBitsUnsigned(): number;
|
||||
getLowBits(): number;
|
||||
getLowBitsUnsigned(): number;
|
||||
getNumBitsAbs(): number;
|
||||
greaterThan(other: Long | number | string): boolean;
|
||||
greaterThanOrEqual(other: Long | number | string): boolean;
|
||||
isEven(): boolean;
|
||||
isNegative(): boolean;
|
||||
isOdd(): boolean;
|
||||
isPositive(): boolean;
|
||||
isZero(): boolean;
|
||||
lessThan(other: Long | number | string): boolean;
|
||||
lessThanOrEqual(other: Long | number | string): boolean;
|
||||
modulo(divisor: Long | number | string): Long;
|
||||
multiply(multiplier: Long | number | string): Long;
|
||||
negate(): Long;
|
||||
not(): Long;
|
||||
notEquals(other: Long | number | string): boolean;
|
||||
or(other: Long | number | string): Long;
|
||||
shiftLeft(numBits: number | Long): Long;
|
||||
shiftRight(numBits: number | Long): Long;
|
||||
shiftRightUnsigned(numBits: number | Long): Long;
|
||||
subtract(other: Long | number | string): Long;
|
||||
toInt(): number;
|
||||
toNumber(): number;
|
||||
toSigned(): Long;
|
||||
toString(radix?: number): string;
|
||||
toUnsigned(): Long;
|
||||
xor(other: Long | number | string): Long;
|
||||
}
|
||||
|
||||
// ==========
|
||||
// protobufjs/src/ProtoBuf/Builder.js
|
||||
|
||||
export interface Builder {
|
||||
new(options?: {[key: string]: any}): ProtoBuilder;
|
||||
Message: Message;
|
||||
Service: Service;
|
||||
isValidMessage(def: {[key: string]: any}): boolean;
|
||||
isValidMessageField(def: {[key: string]: any}): boolean;
|
||||
isValidEnum(def: {[key: string]: any}): boolean;
|
||||
isValidService(def: {[key: string]: any}): boolean;
|
||||
isValidExtend(def: {[key: string]: any}): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Confirm that message needs no further implementation
|
||||
*/
|
||||
export interface Message {
|
||||
new(values?: {[key: string]: any}, var_args?: string[]): Message;
|
||||
[field: string]: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Implement service interface
|
||||
*/
|
||||
export interface Service {
|
||||
new(rpcImpl?: Function): Service;
|
||||
}
|
||||
|
||||
|
||||
// ==========
|
||||
// meta objects for constructing protobufs
|
||||
|
||||
export interface ProtoBuilder {
|
||||
ns: ReflectNamespace;
|
||||
ptr: ReflectNamespace;
|
||||
resolved: boolean;
|
||||
result: ProtoBuf;
|
||||
files: string[];
|
||||
importRoot: string;
|
||||
options: {[key: string]: any};
|
||||
syntax: string;
|
||||
reset(): void;
|
||||
define(pkg: string, options?: {[key: string]: any}): ProtoBuilder;
|
||||
create(defs?: {[key: string]: any}[]): ProtoBuilder;
|
||||
resolveAll(): void;
|
||||
build(path?: string): ProtoBuf;
|
||||
lookup(path?: string): ReflectT;
|
||||
}
|
||||
|
||||
export interface ProtoBuf {
|
||||
[package: string]: {[key: string]: MetaMessage | any};
|
||||
}
|
||||
|
||||
export interface MetaMessage {
|
||||
new(values?: {[key: string]: any}, var_args?: string[]): Message;
|
||||
decode(buffer?: Buffer, enc?: string): Message;
|
||||
decodeDelimited(buffer?: Buffer, enc?: string): Message;
|
||||
decode64(str: string): Message;
|
||||
decodeHex(str: string): Message;
|
||||
}
|
||||
|
||||
// ==========
|
||||
// protobufjs/src/ProtoBuf/DotProto.js
|
||||
|
||||
export interface DotProto {
|
||||
Parser: Parser;
|
||||
Tokenizer: Tokenizer;
|
||||
}
|
||||
|
||||
export interface Parser {
|
||||
new(proto: string): Parser;
|
||||
tn: Tokenizer;
|
||||
parse(): MetaProto;
|
||||
toString(): string;
|
||||
}
|
||||
|
||||
export interface Tokenizer {
|
||||
new(proto: string): Tokenizer;
|
||||
source: string;
|
||||
index: number;
|
||||
line: number;
|
||||
stack: string[];
|
||||
readingString: boolean;
|
||||
stringEndsWith: string;
|
||||
next(): string;
|
||||
peek(): string;
|
||||
toString(): string;
|
||||
}
|
||||
|
||||
// ==========
|
||||
// proto meta information returned by the Parser
|
||||
|
||||
export interface MetaProto {
|
||||
package: string;
|
||||
messages: ProtoMessage[];
|
||||
enums: ProtoEnum[];
|
||||
imports: string[];
|
||||
options: {[key: string]: any};
|
||||
services: ProtoService[];
|
||||
}
|
||||
|
||||
export interface ProtoEnum {
|
||||
name: string;
|
||||
values: ProtoEnumValue;
|
||||
options: {[key: string]: any};
|
||||
}
|
||||
|
||||
export interface ProtoEnumValue {
|
||||
name: string;
|
||||
id: string;
|
||||
}
|
||||
|
||||
export interface ProtoField {
|
||||
rule: string;
|
||||
options: {[key: string]: any};
|
||||
type: string;
|
||||
name: string;
|
||||
id: number;
|
||||
oneof?: string;
|
||||
}
|
||||
|
||||
export interface ProtoMessage {
|
||||
name: string;
|
||||
isGroup?: boolean;
|
||||
fields: ProtoField[];
|
||||
enums: ProtoEnum[];
|
||||
messages: ProtoMessage[];
|
||||
options: {[key: string]: any};
|
||||
oneofs: {[key: string]:number[]};
|
||||
}
|
||||
|
||||
export interface ProtoRpcService {
|
||||
request: string;
|
||||
response: string;
|
||||
options: {[key: string]: any};
|
||||
}
|
||||
|
||||
export interface ProtoService {
|
||||
name: string;
|
||||
rpc: {[key: string]:ProtoRpcService};
|
||||
options: {[key: string]: any};
|
||||
}
|
||||
|
||||
|
||||
// ==========
|
||||
// protobufjs/src/ProtoBuf/Reflect.js
|
||||
|
||||
export interface Reflect {
|
||||
T: ReflectT;
|
||||
Namespace: ReflectNamespace;
|
||||
Message: ReflectMessage;
|
||||
Enum: ReflectEnum;
|
||||
Extension: ReflectExtension;
|
||||
Service: ReflectService;
|
||||
}
|
||||
|
||||
export interface ReflectT {
|
||||
new(builder?: ProtoBuilder, parent?: ReflectT, name?: string): ReflectT;
|
||||
builder: ProtoBuilder;
|
||||
parent: ReflectT;
|
||||
name: string;
|
||||
fqn(): string;
|
||||
toString(includeClass?: boolean): string;
|
||||
}
|
||||
|
||||
export interface ReflectNamespace extends ReflectT {
|
||||
new(builder?: ProtoBuilder, parent?: ReflectNamespace, name?: string,
|
||||
options?: {[key: string]: any}): ReflectNamespace;
|
||||
className: string;
|
||||
children: ReflectT[];
|
||||
options: {[key: string]: any};
|
||||
syntax: string;
|
||||
getChildren(type?: ReflectT): ReflectT[];
|
||||
addChild(child: ReflectT): void;
|
||||
getChild(nameOrId?: string | number): ReflectT;
|
||||
resolve(qn: string, excludeFields?: boolean): ReflectNamespace;
|
||||
build(): ProtoBuf;
|
||||
buildOpt(): {[key: string]: any};
|
||||
getOption(name?: string): any;
|
||||
}
|
||||
|
||||
export interface ReflectMessage extends ReflectNamespace {
|
||||
new(builder?: ProtoBuilder, parent?: ReflectNamespace, name?: string,
|
||||
options?: {[key: string]: any}, isGroup?: boolean): ReflectMessage;
|
||||
Field: ReflectField; // NOTE: only for new ProtoBuf.Reflect.Message.Field();
|
||||
ExtensionField: ReflectExtensionField; // NOTE: only for
|
||||
// new ProtoBuf.Reflect.Message.ExtensionField();
|
||||
OneOf: ReflectOneOf; // NOTE: only for new ProtoBuf.Reflect.Message.OneOf();
|
||||
extensions: number[];
|
||||
clazz(): MetaMessage;
|
||||
isGroup: boolean;
|
||||
build(rebuild?: boolean): MetaMessage|any;
|
||||
encode(message: Message, buffer: Buffer, noVerify?: boolean): Buffer;
|
||||
calculate(message: Message): number;
|
||||
decode(buffer: Buffer, length?: number, expectedGroupEndId?: number): Message;
|
||||
}
|
||||
|
||||
export interface ReflectEnum extends ReflectNamespace {
|
||||
new(builder?: ProtoBuilder, parent?: ReflectT, name?: string,
|
||||
options?: {[key: string]: any}): ReflectEnum;
|
||||
Value: ReflectValue; // NOTE: only for new ProtoBuf.Reflect.Enum.Value();
|
||||
object: {[key: string]:number};
|
||||
build(): {[key: string]: any};
|
||||
}
|
||||
|
||||
export interface ReflectExtension extends ReflectT {
|
||||
new(builder?: ProtoBuilder, parent?: ReflectT, name?: string,
|
||||
field?: ReflectField): ReflectExtension;
|
||||
field: ReflectField;
|
||||
}
|
||||
|
||||
export interface ReflectService extends ReflectNamespace {
|
||||
new(): ReflectService;
|
||||
Method: ReflectMethod; // NOTE: only for new ProtoBuf.Reflect.Service.Method();
|
||||
RPCMethod: ReflectRPCMethod; // NOTE: only for new ProtoBuf.Reflect.Service.RPCMethod();
|
||||
clazz(): Function;
|
||||
build(rebuild?: boolean): Function|any;
|
||||
}
|
||||
|
||||
// TODO: check that the runtime instance of this type reflects this definition
|
||||
export interface ReflectField extends ReflectT {
|
||||
new(builder: ProtoBuilder, message: ReflectMessage, rule: string, type: string,
|
||||
name: string, id: number, options: {[key: string]: any}, oneof: ReflectOneOf): ReflectField;
|
||||
className: string;
|
||||
required: boolean;
|
||||
repeated: boolean;
|
||||
type: string | WireTuple;
|
||||
resolvedType: ReflectT;
|
||||
id: number;
|
||||
options: {[key: string]: any};
|
||||
defaultValue: any;
|
||||
oneof: ReflectOneOf;
|
||||
originalName: string;
|
||||
build(): {[key: string]: any};
|
||||
mkLong(value: any, unsigned?: boolean): number;
|
||||
verifyValue(value: any, skipRepeated?: boolean): any;
|
||||
encode(value: any, buffer: Buffer): Buffer;
|
||||
encodeValue(value: any, buffer: Buffer): Buffer;
|
||||
calculate(value: any): number;
|
||||
calculateValue(value: any): number;
|
||||
decode(wireType: number, buffer: Buffer, skipRepeated?: boolean): any;
|
||||
}
|
||||
|
||||
export interface WireTuple {
|
||||
name: string;
|
||||
wireType: number;
|
||||
}
|
||||
|
||||
// TODO: check that the runtime instance of this type reflects this definition
|
||||
export interface ReflectExtensionField extends ReflectField {
|
||||
new(builder: ProtoBuilder, message: ReflectMessage, rule: string, type: string,
|
||||
name: string, id: number, options: {[key: string]: any}): ReflectExtensionField;
|
||||
extension: ReflectExtension;
|
||||
}
|
||||
|
||||
export interface ReflectOneOf extends ReflectT {
|
||||
new(builder?: ProtoBuilder, message?: ReflectMessage, name?: string): ReflectOneOf;
|
||||
fields: ReflectField[];
|
||||
}
|
||||
|
||||
export interface ReflectValue extends ReflectT {
|
||||
new(builder?: ProtoBuilder, enm?: ReflectEnum, name?: string, id?: number): ReflectValue;
|
||||
className: string;
|
||||
id: number;
|
||||
}
|
||||
|
||||
export interface ReflectMethod extends ReflectT {
|
||||
new(builder?: ProtoBuilder, svc?: ReflectService, name?: string,
|
||||
options?: {[key: string]: any}): ReflectMethod;
|
||||
className: string;
|
||||
options: {[key: string]: any};
|
||||
buildOpt(): {[key: string]: any};
|
||||
}
|
||||
|
||||
export interface ReflectRPCMethod extends ReflectMethod {
|
||||
new(builder?: ProtoBuilder, svc?: ReflectService, name?: string, request?: string,
|
||||
response?: string, options?: {[key: string]: any}): ReflectRPCMethod;
|
||||
requestName: string;
|
||||
responseName: string;
|
||||
resolvedRequestType: ReflectMessage;
|
||||
resolvedResponseType: ReflectMessage;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
declare module "protobufjs" {
|
||||
export = ProtoBuf;
|
||||
}
|
64
web.js
Normal file
64
web.js
Normal file
@ -0,0 +1,64 @@
|
||||
var PORT = 12345;
|
||||
|
||||
var http = require('http');
|
||||
var url = require('url');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
const mime = {
|
||||
"css": "text/css",
|
||||
"gif": "image/gif",
|
||||
"html": "text/html",
|
||||
"ico": "image/x-icon",
|
||||
"jpeg": "image/jpeg",
|
||||
"jpg": "image/jpeg",
|
||||
"js": "text/javascript",
|
||||
"json": "application/json",
|
||||
"pdf": "application/pdf",
|
||||
"png": "image/png",
|
||||
"svg": "image/svg+xml",
|
||||
"swf": "application/x-shockwave-flash",
|
||||
"tiff": "image/tiff",
|
||||
"txt": "text/plain",
|
||||
"wav": "audio/x-wav",
|
||||
"wma": "audio/x-ms-wma",
|
||||
"wmv": "video/x-ms-wmv",
|
||||
"xml": "text/xml"
|
||||
};
|
||||
|
||||
var server = http.createServer(function (request, response) {
|
||||
var realPath = url.parse(request.url).pathname.trim();
|
||||
if (!realPath || realPath == "/") {
|
||||
realPath = "/index.html";
|
||||
}
|
||||
realPath = path.join(__dirname, "dist", realPath);
|
||||
console.log(realPath);
|
||||
var ext = path.extname(realPath);
|
||||
ext = ext ? ext.slice(1) : 'unknown';
|
||||
fs.exists(realPath, function (exists) {
|
||||
if (!exists) {
|
||||
response.writeHead(404, {
|
||||
'Content-Type': 'text/plain'
|
||||
});
|
||||
|
||||
response.write(`无法找到文件${realPath}`);
|
||||
response.end();
|
||||
} else {
|
||||
fs.readFile(realPath, "binary", function (err, file) {
|
||||
if (err) {
|
||||
response.writeHead(500, {
|
||||
'Content-Type': 'text/plain'
|
||||
});
|
||||
response.end(err);
|
||||
} else {
|
||||
var contentType = mime[ext] || "text/plain";
|
||||
response.writeHead(200, {
|
||||
'Content-Type': contentType
|
||||
});
|
||||
response.write(file, "binary");
|
||||
response.end();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
server.listen(PORT);
|
Loading…
x
Reference in New Issue
Block a user