qianzhuqing 3 years ago
parent
commit
a0119f2ff0
5 changed files with 1125 additions and 49 deletions
  1. 521 5
      cs/Lobby.cs
  2. 287 11
      cs/Room.cs
  3. 249 30
      cs/Sync.cs
  4. 60 3
      cs/User.cs
  5. 8 0
      protos/front.proto

+ 521 - 5
cs/Lobby.cs

@@ -22,14 +22,24 @@ namespace Protos {
     static LobbyReflection() {
       byte[] descriptorData = global::System.Convert.FromBase64String(
           string.Concat(
-            "Cgtsb2JieS5wcm90bxIGcHJvdG9zGg51c2VyaW5mby5wcm90byIzCg1Mb2Ji",
-            "eUpvaW5QdXNoEiIKCFVzZXJJbmZvGAEgASgLMhAucHJvdG9zLlVzZXJJbmZv",
-            "IiAKDkxvYmJ5TGVhdmVQdXNoEg4KBlVzZXJJRBgBIAEoDWIGcHJvdG8z"));
+            "Cgtsb2JieS5wcm90bxIGcHJvdG9zGg51c2VyaW5mby5wcm90bxoMcmVzdWx0",
+            "LnByb3RvIjMKDUxvYmJ5Sm9pblB1c2gSIgoIVXNlckluZm8YASABKAsyEC5w",
+            "cm90b3MuVXNlckluZm8iIAoOTG9iYnlMZWF2ZVB1c2gSDgoGVXNlcklEGAEg",
+            "ASgNIhYKFExvYmJ5VXNlckxpc3RSZXF1ZXN0IlgKFUxvYmJ5VXNlckxpc3RS",
+            "ZXNwb25zZRIeCgZSZXN1bHQYASABKAsyDi5wcm90b3MuUmVzdWx0Eh8KBVVz",
+            "ZXJzGAIgAygLMhAucHJvdG9zLlVzZXJJbmZvIiUKE0xvYmJ5R2V0VXNlclJl",
+            "cXVlc3QSDgoGVXNlcklEGAEgASgNIlYKFExvYmJ5R2V0VXNlclJlc3BvbnNl",
+            "Eh4KBlJlc3VsdBgBIAEoCzIOLnByb3Rvcy5SZXN1bHQSHgoEVXNlchgCIAEo",
+            "CzIQLnByb3Rvcy5Vc2VySW5mb2IGcHJvdG8z"));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
-          new pbr::FileDescriptor[] { global::Protos.UserinfoReflection.Descriptor, },
+          new pbr::FileDescriptor[] { global::Protos.UserinfoReflection.Descriptor, global::Protos.ResultReflection.Descriptor, },
           new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
             new pbr::GeneratedClrTypeInfo(typeof(global::Protos.LobbyJoinPush), global::Protos.LobbyJoinPush.Parser, new[]{ "UserInfo" }, null, null, null),
-            new pbr::GeneratedClrTypeInfo(typeof(global::Protos.LobbyLeavePush), global::Protos.LobbyLeavePush.Parser, new[]{ "UserID" }, null, null, null)
+            new pbr::GeneratedClrTypeInfo(typeof(global::Protos.LobbyLeavePush), global::Protos.LobbyLeavePush.Parser, new[]{ "UserID" }, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Protos.LobbyUserListRequest), global::Protos.LobbyUserListRequest.Parser, null, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Protos.LobbyUserListResponse), global::Protos.LobbyUserListResponse.Parser, new[]{ "Result", "Users" }, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Protos.LobbyGetUserRequest), global::Protos.LobbyGetUserRequest.Parser, new[]{ "UserID" }, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Protos.LobbyGetUserResponse), global::Protos.LobbyGetUserResponse.Parser, new[]{ "Result", "User" }, null, null, null)
           }));
     }
     #endregion
@@ -282,6 +292,512 @@ namespace Protos {
 
   }
 
+  public sealed partial class LobbyUserListRequest : pb::IMessage<LobbyUserListRequest> {
+    private static readonly pb::MessageParser<LobbyUserListRequest> _parser = new pb::MessageParser<LobbyUserListRequest>(() => new LobbyUserListRequest());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<LobbyUserListRequest> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Protos.LobbyReflection.Descriptor.MessageTypes[2]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public LobbyUserListRequest() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public LobbyUserListRequest(LobbyUserListRequest other) : this() {
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public LobbyUserListRequest Clone() {
+      return new LobbyUserListRequest(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as LobbyUserListRequest);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(LobbyUserListRequest other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(LobbyUserListRequest other) {
+      if (other == null) {
+        return;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+        }
+      }
+    }
+
+  }
+
+  public sealed partial class LobbyUserListResponse : pb::IMessage<LobbyUserListResponse> {
+    private static readonly pb::MessageParser<LobbyUserListResponse> _parser = new pb::MessageParser<LobbyUserListResponse>(() => new LobbyUserListResponse());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<LobbyUserListResponse> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Protos.LobbyReflection.Descriptor.MessageTypes[3]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public LobbyUserListResponse() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public LobbyUserListResponse(LobbyUserListResponse other) : this() {
+      Result = other.result_ != null ? other.Result.Clone() : null;
+      users_ = other.users_.Clone();
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public LobbyUserListResponse Clone() {
+      return new LobbyUserListResponse(this);
+    }
+
+    /// <summary>Field number for the "Result" field.</summary>
+    public const int ResultFieldNumber = 1;
+    private global::Protos.Result result_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public global::Protos.Result Result {
+      get { return result_; }
+      set {
+        result_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "Users" field.</summary>
+    public const int UsersFieldNumber = 2;
+    private static readonly pb::FieldCodec<global::Protos.UserInfo> _repeated_users_codec
+        = pb::FieldCodec.ForMessage(18, global::Protos.UserInfo.Parser);
+    private readonly pbc::RepeatedField<global::Protos.UserInfo> users_ = new pbc::RepeatedField<global::Protos.UserInfo>();
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public pbc::RepeatedField<global::Protos.UserInfo> Users {
+      get { return users_; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as LobbyUserListResponse);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(LobbyUserListResponse other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (!object.Equals(Result, other.Result)) return false;
+      if(!users_.Equals(other.users_)) return false;
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (result_ != null) hash ^= Result.GetHashCode();
+      hash ^= users_.GetHashCode();
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (result_ != null) {
+        output.WriteRawTag(10);
+        output.WriteMessage(Result);
+      }
+      users_.WriteTo(output, _repeated_users_codec);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (result_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Result);
+      }
+      size += users_.CalculateSize(_repeated_users_codec);
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(LobbyUserListResponse other) {
+      if (other == null) {
+        return;
+      }
+      if (other.result_ != null) {
+        if (result_ == null) {
+          result_ = new global::Protos.Result();
+        }
+        Result.MergeFrom(other.Result);
+      }
+      users_.Add(other.users_);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            if (result_ == null) {
+              result_ = new global::Protos.Result();
+            }
+            input.ReadMessage(result_);
+            break;
+          }
+          case 18: {
+            users_.AddEntriesFrom(input, _repeated_users_codec);
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  public sealed partial class LobbyGetUserRequest : pb::IMessage<LobbyGetUserRequest> {
+    private static readonly pb::MessageParser<LobbyGetUserRequest> _parser = new pb::MessageParser<LobbyGetUserRequest>(() => new LobbyGetUserRequest());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<LobbyGetUserRequest> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Protos.LobbyReflection.Descriptor.MessageTypes[4]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public LobbyGetUserRequest() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public LobbyGetUserRequest(LobbyGetUserRequest other) : this() {
+      userID_ = other.userID_;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public LobbyGetUserRequest Clone() {
+      return new LobbyGetUserRequest(this);
+    }
+
+    /// <summary>Field number for the "UserID" field.</summary>
+    public const int UserIDFieldNumber = 1;
+    private uint userID_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public uint UserID {
+      get { return userID_; }
+      set {
+        userID_ = value;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as LobbyGetUserRequest);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(LobbyGetUserRequest other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (UserID != other.UserID) return false;
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (UserID != 0) hash ^= UserID.GetHashCode();
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (UserID != 0) {
+        output.WriteRawTag(8);
+        output.WriteUInt32(UserID);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (UserID != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeUInt32Size(UserID);
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(LobbyGetUserRequest other) {
+      if (other == null) {
+        return;
+      }
+      if (other.UserID != 0) {
+        UserID = other.UserID;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 8: {
+            UserID = input.ReadUInt32();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  public sealed partial class LobbyGetUserResponse : pb::IMessage<LobbyGetUserResponse> {
+    private static readonly pb::MessageParser<LobbyGetUserResponse> _parser = new pb::MessageParser<LobbyGetUserResponse>(() => new LobbyGetUserResponse());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<LobbyGetUserResponse> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Protos.LobbyReflection.Descriptor.MessageTypes[5]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public LobbyGetUserResponse() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public LobbyGetUserResponse(LobbyGetUserResponse other) : this() {
+      Result = other.result_ != null ? other.Result.Clone() : null;
+      User = other.user_ != null ? other.User.Clone() : null;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public LobbyGetUserResponse Clone() {
+      return new LobbyGetUserResponse(this);
+    }
+
+    /// <summary>Field number for the "Result" field.</summary>
+    public const int ResultFieldNumber = 1;
+    private global::Protos.Result result_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public global::Protos.Result Result {
+      get { return result_; }
+      set {
+        result_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "User" field.</summary>
+    public const int UserFieldNumber = 2;
+    private global::Protos.UserInfo user_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public global::Protos.UserInfo User {
+      get { return user_; }
+      set {
+        user_ = value;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as LobbyGetUserResponse);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(LobbyGetUserResponse other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (!object.Equals(Result, other.Result)) return false;
+      if (!object.Equals(User, other.User)) return false;
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (result_ != null) hash ^= Result.GetHashCode();
+      if (user_ != null) hash ^= User.GetHashCode();
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (result_ != null) {
+        output.WriteRawTag(10);
+        output.WriteMessage(Result);
+      }
+      if (user_ != null) {
+        output.WriteRawTag(18);
+        output.WriteMessage(User);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (result_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Result);
+      }
+      if (user_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(User);
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(LobbyGetUserResponse other) {
+      if (other == null) {
+        return;
+      }
+      if (other.result_ != null) {
+        if (result_ == null) {
+          result_ = new global::Protos.Result();
+        }
+        Result.MergeFrom(other.Result);
+      }
+      if (other.user_ != null) {
+        if (user_ == null) {
+          user_ = new global::Protos.UserInfo();
+        }
+        User.MergeFrom(other.User);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            if (result_ == null) {
+              result_ = new global::Protos.Result();
+            }
+            input.ReadMessage(result_);
+            break;
+          }
+          case 18: {
+            if (user_ == null) {
+              user_ = new global::Protos.UserInfo();
+            }
+            input.ReadMessage(user_);
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
   #endregion
 
 }

+ 287 - 11
cs/Room.cs

@@ -24,20 +24,25 @@ namespace Protos {
           string.Concat(
             "Cgpyb29tLnByb3RvEgZwcm90b3MaDnVzZXJpbmZvLnByb3RvGgxyZXN1bHQu",
             "cHJvdG8iEwoRUm9vbUNyZWF0ZVJlcXVlc3QiFAoSUm9vbUNyZWF0ZVJlc3Bv",
-            "bnNlIiEKD1Jvb21Kb2luUmVxdWVzdBIOCgZSb29tSUQYASABKA0iQgoQUm9v",
-            "bUpvaW5SZXNwb25zZRIeCgZSZXN1bHQYASABKAsyDi5wcm90b3MuUmVzdWx0",
-            "Eg4KBlJvb21JRBgCIAEoDSIyCgxSb29tSm9pblB1c2gSIgoIVXNlckluZm8Y",
-            "ASABKAsyEC5wcm90b3MuVXNlckluZm8iHwoNUm9vbUxlYXZlUHVzaBIOCgZV",
-            "c2VySUQYASABKA0iEQoPUm9vbURpc21pc3NQdXNoIiYKFFJvb21Td2l0Y2hN",
-            "YXN0ZXJQdXNoEg4KBlVzZXJJRBgBIAEoDWIGcHJvdG8z"));
+            "bnNlIjMKD1Jvb21Kb2luUmVxdWVzdBIOCgZSb29tSUQYASABKA0SEAoIUm9v",
+            "bVR5cGUYAiABKAUiUgoQUm9vbUpvaW5SZXNwb25zZRIeCgZSZXN1bHQYASAB",
+            "KAsyDi5wcm90b3MuUmVzdWx0Eg4KBlJvb21JRBgCIAEoDRIOCgZNQVNURVIY",
+            "AyABKAgiMgoMUm9vbUpvaW5QdXNoEiIKCFVzZXJJbmZvGAEgASgLMhAucHJv",
+            "dG9zLlVzZXJJbmZvIhIKEFJvb21MZWF2ZVJlcXVlc3QiMwoRUm9vbUxlYXZl",
+            "UmVzcG9uc2USHgoGUmVzdWx0GAEgASgLMg4ucHJvdG9zLlJlc3VsdCIfCg1S",
+            "b29tTGVhdmVQdXNoEg4KBlVzZXJJRBgBIAEoDSIRCg9Sb29tRGlzbWlzc1B1",
+            "c2giJgoUUm9vbVN3aXRjaE1hc3RlclB1c2gSDgoGVXNlcklEGAEgASgNYgZw",
+            "cm90bzM="));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { global::Protos.UserinfoReflection.Descriptor, global::Protos.ResultReflection.Descriptor, },
           new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
             new pbr::GeneratedClrTypeInfo(typeof(global::Protos.RoomCreateRequest), global::Protos.RoomCreateRequest.Parser, null, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Protos.RoomCreateResponse), global::Protos.RoomCreateResponse.Parser, null, null, null, null),
-            new pbr::GeneratedClrTypeInfo(typeof(global::Protos.RoomJoinRequest), global::Protos.RoomJoinRequest.Parser, new[]{ "RoomID" }, null, null, null),
-            new pbr::GeneratedClrTypeInfo(typeof(global::Protos.RoomJoinResponse), global::Protos.RoomJoinResponse.Parser, new[]{ "Result", "RoomID" }, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Protos.RoomJoinRequest), global::Protos.RoomJoinRequest.Parser, new[]{ "RoomID", "RoomType" }, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Protos.RoomJoinResponse), global::Protos.RoomJoinResponse.Parser, new[]{ "Result", "RoomID", "MASTER" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Protos.RoomJoinPush), global::Protos.RoomJoinPush.Parser, new[]{ "UserInfo" }, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Protos.RoomLeaveRequest), global::Protos.RoomLeaveRequest.Parser, null, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Protos.RoomLeaveResponse), global::Protos.RoomLeaveResponse.Parser, new[]{ "Result" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Protos.RoomLeavePush), global::Protos.RoomLeavePush.Parser, new[]{ "UserID" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Protos.RoomDismissPush), global::Protos.RoomDismissPush.Parser, null, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Protos.RoomSwitchMasterPush), global::Protos.RoomSwitchMasterPush.Parser, new[]{ "UserID" }, null, null, null)
@@ -250,6 +255,7 @@ namespace Protos {
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public RoomJoinRequest(RoomJoinRequest other) : this() {
       roomID_ = other.roomID_;
+      roomType_ = other.roomType_;
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -268,6 +274,20 @@ namespace Protos {
       }
     }
 
+    /// <summary>Field number for the "RoomType" field.</summary>
+    public const int RoomTypeFieldNumber = 2;
+    private int roomType_;
+    /// <summary>
+    /// 0 = 游戏; 1=糖豆人
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int RoomType {
+      get { return roomType_; }
+      set {
+        roomType_ = value;
+      }
+    }
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as RoomJoinRequest);
@@ -282,6 +302,7 @@ namespace Protos {
         return true;
       }
       if (RoomID != other.RoomID) return false;
+      if (RoomType != other.RoomType) return false;
       return true;
     }
 
@@ -289,6 +310,7 @@ namespace Protos {
     public override int GetHashCode() {
       int hash = 1;
       if (RoomID != 0) hash ^= RoomID.GetHashCode();
+      if (RoomType != 0) hash ^= RoomType.GetHashCode();
       return hash;
     }
 
@@ -303,6 +325,10 @@ namespace Protos {
         output.WriteRawTag(8);
         output.WriteUInt32(RoomID);
       }
+      if (RoomType != 0) {
+        output.WriteRawTag(16);
+        output.WriteInt32(RoomType);
+      }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -311,6 +337,9 @@ namespace Protos {
       if (RoomID != 0) {
         size += 1 + pb::CodedOutputStream.ComputeUInt32Size(RoomID);
       }
+      if (RoomType != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(RoomType);
+      }
       return size;
     }
 
@@ -322,6 +351,9 @@ namespace Protos {
       if (other.RoomID != 0) {
         RoomID = other.RoomID;
       }
+      if (other.RoomType != 0) {
+        RoomType = other.RoomType;
+      }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -336,6 +368,10 @@ namespace Protos {
             RoomID = input.ReadUInt32();
             break;
           }
+          case 16: {
+            RoomType = input.ReadInt32();
+            break;
+          }
         }
       }
     }
@@ -368,6 +404,7 @@ namespace Protos {
     public RoomJoinResponse(RoomJoinResponse other) : this() {
       Result = other.result_ != null ? other.Result.Clone() : null;
       roomID_ = other.roomID_;
+      mASTER_ = other.mASTER_;
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -397,6 +434,17 @@ namespace Protos {
       }
     }
 
+    /// <summary>Field number for the "MASTER" field.</summary>
+    public const int MASTERFieldNumber = 3;
+    private bool mASTER_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool MASTER {
+      get { return mASTER_; }
+      set {
+        mASTER_ = value;
+      }
+    }
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as RoomJoinResponse);
@@ -412,6 +460,7 @@ namespace Protos {
       }
       if (!object.Equals(Result, other.Result)) return false;
       if (RoomID != other.RoomID) return false;
+      if (MASTER != other.MASTER) return false;
       return true;
     }
 
@@ -420,6 +469,7 @@ namespace Protos {
       int hash = 1;
       if (result_ != null) hash ^= Result.GetHashCode();
       if (RoomID != 0) hash ^= RoomID.GetHashCode();
+      if (MASTER != false) hash ^= MASTER.GetHashCode();
       return hash;
     }
 
@@ -438,6 +488,10 @@ namespace Protos {
         output.WriteRawTag(16);
         output.WriteUInt32(RoomID);
       }
+      if (MASTER != false) {
+        output.WriteRawTag(24);
+        output.WriteBool(MASTER);
+      }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -449,6 +503,9 @@ namespace Protos {
       if (RoomID != 0) {
         size += 1 + pb::CodedOutputStream.ComputeUInt32Size(RoomID);
       }
+      if (MASTER != false) {
+        size += 1 + 1;
+      }
       return size;
     }
 
@@ -466,6 +523,9 @@ namespace Protos {
       if (other.RoomID != 0) {
         RoomID = other.RoomID;
       }
+      if (other.MASTER != false) {
+        MASTER = other.MASTER;
+      }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -487,6 +547,10 @@ namespace Protos {
             RoomID = input.ReadUInt32();
             break;
           }
+          case 24: {
+            MASTER = input.ReadBool();
+            break;
+          }
         }
       }
     }
@@ -616,6 +680,218 @@ namespace Protos {
 
   }
 
+  public sealed partial class RoomLeaveRequest : pb::IMessage<RoomLeaveRequest> {
+    private static readonly pb::MessageParser<RoomLeaveRequest> _parser = new pb::MessageParser<RoomLeaveRequest>(() => new RoomLeaveRequest());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<RoomLeaveRequest> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Protos.RoomReflection.Descriptor.MessageTypes[5]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public RoomLeaveRequest() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public RoomLeaveRequest(RoomLeaveRequest other) : this() {
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public RoomLeaveRequest Clone() {
+      return new RoomLeaveRequest(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as RoomLeaveRequest);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(RoomLeaveRequest other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(RoomLeaveRequest other) {
+      if (other == null) {
+        return;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+        }
+      }
+    }
+
+  }
+
+  public sealed partial class RoomLeaveResponse : pb::IMessage<RoomLeaveResponse> {
+    private static readonly pb::MessageParser<RoomLeaveResponse> _parser = new pb::MessageParser<RoomLeaveResponse>(() => new RoomLeaveResponse());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<RoomLeaveResponse> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Protos.RoomReflection.Descriptor.MessageTypes[6]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public RoomLeaveResponse() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public RoomLeaveResponse(RoomLeaveResponse other) : this() {
+      Result = other.result_ != null ? other.Result.Clone() : null;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public RoomLeaveResponse Clone() {
+      return new RoomLeaveResponse(this);
+    }
+
+    /// <summary>Field number for the "Result" field.</summary>
+    public const int ResultFieldNumber = 1;
+    private global::Protos.Result result_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public global::Protos.Result Result {
+      get { return result_; }
+      set {
+        result_ = value;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as RoomLeaveResponse);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(RoomLeaveResponse other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (!object.Equals(Result, other.Result)) return false;
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (result_ != null) hash ^= Result.GetHashCode();
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (result_ != null) {
+        output.WriteRawTag(10);
+        output.WriteMessage(Result);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (result_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Result);
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(RoomLeaveResponse other) {
+      if (other == null) {
+        return;
+      }
+      if (other.result_ != null) {
+        if (result_ == null) {
+          result_ = new global::Protos.Result();
+        }
+        Result.MergeFrom(other.Result);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            if (result_ == null) {
+              result_ = new global::Protos.Result();
+            }
+            input.ReadMessage(result_);
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
   public sealed partial class RoomLeavePush : pb::IMessage<RoomLeavePush> {
     private static readonly pb::MessageParser<RoomLeavePush> _parser = new pb::MessageParser<RoomLeavePush>(() => new RoomLeavePush());
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -623,7 +899,7 @@ namespace Protos {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Protos.RoomReflection.Descriptor.MessageTypes[5]; }
+      get { return global::Protos.RoomReflection.Descriptor.MessageTypes[7]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -740,7 +1016,7 @@ namespace Protos {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Protos.RoomReflection.Descriptor.MessageTypes[6]; }
+      get { return global::Protos.RoomReflection.Descriptor.MessageTypes[8]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -829,7 +1105,7 @@ namespace Protos {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Protos.RoomReflection.Descriptor.MessageTypes[7]; }
+      get { return global::Protos.RoomReflection.Descriptor.MessageTypes[9]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]

+ 249 - 30
cs/Sync.cs

@@ -29,45 +29,48 @@ namespace Protos {
             "ZUVudHJ5GiwKClN0YXRlRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIg",
             "ASgMOgI4ASJ7CgtTeW5jUmVxdWVzdBIMCgRTdGVwGAEgASgEEi8KBlZhbHVl",
             "cxgCIAMoCzIfLnByb3Rvcy5TeW5jUmVxdWVzdC5WYWx1ZXNFbnRyeRotCgtW",
-            "YWx1ZXNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAw6AjgBIo0B",
+            "YWx1ZXNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAw6AjgBIpgB",
             "CgxTeW5jUmVzcG9uc2USDgoGU3RhdHVzGAEgASgIEgwKBFN0ZXAYAiABKAQS",
             "MAoGVmFsdWVzGAMgAygLMiAucHJvdG9zLlN5bmNSZXNwb25zZS5WYWx1ZXNF",
-            "bnRyeRotCgtWYWx1ZXNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiAB",
-            "KAw6AjgBIoYBCg9ETWVzc2FnZVJlcXVlc3QSDwoHVXNlcklEcxgBIAMoDRIz",
-            "CgZWYWx1ZXMYAiADKAsyIy5wcm90b3MuRE1lc3NhZ2VSZXF1ZXN0LlZhbHVl",
-            "c0VudHJ5Gi0KC1ZhbHVlc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgC",
-            "IAEoDDoCOAEiMgoQRE1lc3NhZ2VSZXNwb25zZRIeCgZSZXN1bHQYASABKAsy",
-            "Di5wcm90b3MuUmVzdWx0Im8KDERNZXNzYWdlUHVzaBIwCgZWYWx1ZXMYASAD",
-            "KAsyIC5wcm90b3MuRE1lc3NhZ2VQdXNoLlZhbHVlc0VudHJ5Gi0KC1ZhbHVl",
-            "c0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoDDoCOAEidQoIU3lu",
-            "Y1B1c2gSDAoEU3RlcBgBIAEoBBIsCgZWYWx1ZXMYAiADKAsyHC5wcm90b3Mu",
-            "U3luY1B1c2guVmFsdWVzRW50cnkaLQoLVmFsdWVzRW50cnkSCwoDa2V5GAEg",
-            "ASgJEg0KBXZhbHVlGAIgASgMOgI4ASJ5CgpNYXN0ZXJQdXNoEgwKBFN0ZXAY",
-            "ASABKAQSLgoGVmFsdWVzGAIgAygLMh4ucHJvdG9zLk1hc3RlclB1c2guVmFs",
-            "dWVzRW50cnkaLQoLVmFsdWVzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVl",
-            "GAIgASgMOgI4ASJ9CgxNYXN0ZXJOb3RpZnkSDAoEU3RlcBgBIAEoBBIwCgZW",
-            "YWx1ZXMYAiADKAsyIC5wcm90b3MuTWFzdGVyTm90aWZ5LlZhbHVlc0VudHJ5",
-            "Gi0KC1ZhbHVlc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoDDoC",
-            "OAEieQoRTWFzdGVyU3RvcmVOb3RpZnkSNQoGVmFsdWVzGAEgAygLMiUucHJv",
-            "dG9zLk1hc3RlclN0b3JlTm90aWZ5LlZhbHVlc0VudHJ5Gi0KC1ZhbHVlc0Vu",
-            "dHJ5EgsKA2tleRgBIAEoCRINCgV2YWx1ZRgCIAEoDDoCOAEiEwoRTWFzdGVy",
-            "TG9hZFJlcXVlc3QimwEKEk1hc3RlckxvYWRSZXNwb25zZRIeCgZSZXN1bHQY",
-            "ASABKAsyDi5wcm90b3MuUmVzdWx0EjYKBlZhbHVlcxgCIAMoCzImLnByb3Rv",
-            "cy5NYXN0ZXJMb2FkUmVzcG9uc2UuVmFsdWVzRW50cnkaLQoLVmFsdWVzRW50",
-            "cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgMOgI4AWIGcHJvdG8z"));
+            "bnRyeRIJCgFUGAQgASgEGi0KC1ZhbHVlc0VudHJ5EgsKA2tleRgBIAEoCRIN",
+            "CgV2YWx1ZRgCIAEoDDoCOAEihgEKD0RNZXNzYWdlUmVxdWVzdBIPCgdVc2Vy",
+            "SURzGAEgAygNEjMKBlZhbHVlcxgCIAMoCzIjLnByb3Rvcy5ETWVzc2FnZVJl",
+            "cXVlc3QuVmFsdWVzRW50cnkaLQoLVmFsdWVzRW50cnkSCwoDa2V5GAEgASgJ",
+            "Eg0KBXZhbHVlGAIgASgMOgI4ASIyChBETWVzc2FnZVJlc3BvbnNlEh4KBlJl",
+            "c3VsdBgBIAEoCzIOLnByb3Rvcy5SZXN1bHQibwoMRE1lc3NhZ2VQdXNoEjAK",
+            "BlZhbHVlcxgBIAMoCzIgLnByb3Rvcy5ETWVzc2FnZVB1c2guVmFsdWVzRW50",
+            "cnkaLQoLVmFsdWVzRW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgM",
+            "OgI4ASKAAQoIU3luY1B1c2gSDAoEU3RlcBgBIAEoBBIsCgZWYWx1ZXMYAiAD",
+            "KAsyHC5wcm90b3MuU3luY1B1c2guVmFsdWVzRW50cnkSCQoBVBgDIAEoBBot",
+            "CgtWYWx1ZXNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAw6AjgB",
+            "IoQBCgpNYXN0ZXJQdXNoEgwKBFN0ZXAYASABKAQSLgoGVmFsdWVzGAIgAygL",
+            "Mh4ucHJvdG9zLk1hc3RlclB1c2guVmFsdWVzRW50cnkSCQoBVBgDIAEoBBot",
+            "CgtWYWx1ZXNFbnRyeRILCgNrZXkYASABKAkSDQoFdmFsdWUYAiABKAw6AjgB",
+            "In0KDE1hc3Rlck5vdGlmeRIMCgRTdGVwGAEgASgEEjAKBlZhbHVlcxgCIAMo",
+            "CzIgLnByb3Rvcy5NYXN0ZXJOb3RpZnkuVmFsdWVzRW50cnkaLQoLVmFsdWVz",
+            "RW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgMOgI4ASIhChRNYXN0",
+            "ZXJOb3RpZnlSZXNwb25zZRIJCgFUGAEgASgEInkKEU1hc3RlclN0b3JlTm90",
+            "aWZ5EjUKBlZhbHVlcxgBIAMoCzIlLnByb3Rvcy5NYXN0ZXJTdG9yZU5vdGlm",
+            "eS5WYWx1ZXNFbnRyeRotCgtWYWx1ZXNFbnRyeRILCgNrZXkYASABKAkSDQoF",
+            "dmFsdWUYAiABKAw6AjgBIhMKEU1hc3RlckxvYWRSZXF1ZXN0IpsBChJNYXN0",
+            "ZXJMb2FkUmVzcG9uc2USHgoGUmVzdWx0GAEgASgLMg4ucHJvdG9zLlJlc3Vs",
+            "dBI2CgZWYWx1ZXMYAiADKAsyJi5wcm90b3MuTWFzdGVyTG9hZFJlc3BvbnNl",
+            "LlZhbHVlc0VudHJ5Gi0KC1ZhbHVlc0VudHJ5EgsKA2tleRgBIAEoCRINCgV2",
+            "YWx1ZRgCIAEoDDoCOAFiBnByb3RvMw=="));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { global::Protos.UserinfoReflection.Descriptor, global::Protos.ResultReflection.Descriptor, },
           new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
             new pbr::GeneratedClrTypeInfo(typeof(global::Protos.RestoreRequest), global::Protos.RestoreRequest.Parser, null, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Protos.RestoreResponse), global::Protos.RestoreResponse.Parser, new[]{ "Users", "Step", "State" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, }),
             new pbr::GeneratedClrTypeInfo(typeof(global::Protos.SyncRequest), global::Protos.SyncRequest.Parser, new[]{ "Step", "Values" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, }),
-            new pbr::GeneratedClrTypeInfo(typeof(global::Protos.SyncResponse), global::Protos.SyncResponse.Parser, new[]{ "Status", "Step", "Values" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, }),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Protos.SyncResponse), global::Protos.SyncResponse.Parser, new[]{ "Status", "Step", "Values", "T" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, }),
             new pbr::GeneratedClrTypeInfo(typeof(global::Protos.DMessageRequest), global::Protos.DMessageRequest.Parser, new[]{ "UserIDs", "Values" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, }),
             new pbr::GeneratedClrTypeInfo(typeof(global::Protos.DMessageResponse), global::Protos.DMessageResponse.Parser, new[]{ "Result" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Protos.DMessagePush), global::Protos.DMessagePush.Parser, new[]{ "Values" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, }),
-            new pbr::GeneratedClrTypeInfo(typeof(global::Protos.SyncPush), global::Protos.SyncPush.Parser, new[]{ "Step", "Values" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, }),
-            new pbr::GeneratedClrTypeInfo(typeof(global::Protos.MasterPush), global::Protos.MasterPush.Parser, new[]{ "Step", "Values" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, }),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Protos.SyncPush), global::Protos.SyncPush.Parser, new[]{ "Step", "Values", "T" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, }),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Protos.MasterPush), global::Protos.MasterPush.Parser, new[]{ "Step", "Values", "T" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, }),
             new pbr::GeneratedClrTypeInfo(typeof(global::Protos.MasterNotify), global::Protos.MasterNotify.Parser, new[]{ "Step", "Values" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, }),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Protos.MasterNotifyResponse), global::Protos.MasterNotifyResponse.Parser, new[]{ "T" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Protos.MasterStoreNotify), global::Protos.MasterStoreNotify.Parser, new[]{ "Values" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, }),
             new pbr::GeneratedClrTypeInfo(typeof(global::Protos.MasterLoadRequest), global::Protos.MasterLoadRequest.Parser, null, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Protos.MasterLoadResponse), global::Protos.MasterLoadResponse.Parser, new[]{ "Result", "Values" }, null, null, new pbr::GeneratedClrTypeInfo[] { null, })
@@ -499,6 +502,7 @@ namespace Protos {
       status_ = other.status_;
       step_ = other.step_;
       values_ = other.values_.Clone();
+      t_ = other.t_;
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -544,6 +548,20 @@ namespace Protos {
       get { return values_; }
     }
 
+    /// <summary>Field number for the "T" field.</summary>
+    public const int TFieldNumber = 4;
+    private ulong t_;
+    /// <summary>
+    /// 服务器收到sync request的时间戳(毫秒)
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ulong T {
+      get { return t_; }
+      set {
+        t_ = value;
+      }
+    }
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as SyncResponse);
@@ -560,6 +578,7 @@ namespace Protos {
       if (Status != other.Status) return false;
       if (Step != other.Step) return false;
       if (!Values.Equals(other.Values)) return false;
+      if (T != other.T) return false;
       return true;
     }
 
@@ -569,6 +588,7 @@ namespace Protos {
       if (Status != false) hash ^= Status.GetHashCode();
       if (Step != 0UL) hash ^= Step.GetHashCode();
       hash ^= Values.GetHashCode();
+      if (T != 0UL) hash ^= T.GetHashCode();
       return hash;
     }
 
@@ -588,6 +608,10 @@ namespace Protos {
         output.WriteUInt64(Step);
       }
       values_.WriteTo(output, _map_values_codec);
+      if (T != 0UL) {
+        output.WriteRawTag(32);
+        output.WriteUInt64(T);
+      }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -600,6 +624,9 @@ namespace Protos {
         size += 1 + pb::CodedOutputStream.ComputeUInt64Size(Step);
       }
       size += values_.CalculateSize(_map_values_codec);
+      if (T != 0UL) {
+        size += 1 + pb::CodedOutputStream.ComputeUInt64Size(T);
+      }
       return size;
     }
 
@@ -615,6 +642,9 @@ namespace Protos {
         Step = other.Step;
       }
       values_.Add(other.values_);
+      if (other.T != 0UL) {
+        T = other.T;
+      }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -637,6 +667,10 @@ namespace Protos {
             values_.AddEntriesFrom(input, _map_values_codec);
             break;
           }
+          case 32: {
+            T = input.ReadUInt64();
+            break;
+          }
         }
       }
     }
@@ -1043,6 +1077,7 @@ namespace Protos {
     public SyncPush(SyncPush other) : this() {
       step_ = other.step_;
       values_ = other.values_.Clone();
+      t_ = other.t_;
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1071,6 +1106,20 @@ namespace Protos {
       get { return values_; }
     }
 
+    /// <summary>Field number for the "T" field.</summary>
+    public const int TFieldNumber = 3;
+    private ulong t_;
+    /// <summary>
+    /// 服务器开始推送时间戳
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ulong T {
+      get { return t_; }
+      set {
+        t_ = value;
+      }
+    }
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as SyncPush);
@@ -1086,6 +1135,7 @@ namespace Protos {
       }
       if (Step != other.Step) return false;
       if (!Values.Equals(other.Values)) return false;
+      if (T != other.T) return false;
       return true;
     }
 
@@ -1094,6 +1144,7 @@ namespace Protos {
       int hash = 1;
       if (Step != 0UL) hash ^= Step.GetHashCode();
       hash ^= Values.GetHashCode();
+      if (T != 0UL) hash ^= T.GetHashCode();
       return hash;
     }
 
@@ -1109,6 +1160,10 @@ namespace Protos {
         output.WriteUInt64(Step);
       }
       values_.WriteTo(output, _map_values_codec);
+      if (T != 0UL) {
+        output.WriteRawTag(24);
+        output.WriteUInt64(T);
+      }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1118,6 +1173,9 @@ namespace Protos {
         size += 1 + pb::CodedOutputStream.ComputeUInt64Size(Step);
       }
       size += values_.CalculateSize(_map_values_codec);
+      if (T != 0UL) {
+        size += 1 + pb::CodedOutputStream.ComputeUInt64Size(T);
+      }
       return size;
     }
 
@@ -1130,6 +1188,9 @@ namespace Protos {
         Step = other.Step;
       }
       values_.Add(other.values_);
+      if (other.T != 0UL) {
+        T = other.T;
+      }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1148,6 +1209,10 @@ namespace Protos {
             values_.AddEntriesFrom(input, _map_values_codec);
             break;
           }
+          case 24: {
+            T = input.ReadUInt64();
+            break;
+          }
         }
       }
     }
@@ -1183,6 +1248,7 @@ namespace Protos {
     public MasterPush(MasterPush other) : this() {
       step_ = other.step_;
       values_ = other.values_.Clone();
+      t_ = other.t_;
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1211,6 +1277,20 @@ namespace Protos {
       get { return values_; }
     }
 
+    /// <summary>Field number for the "T" field.</summary>
+    public const int TFieldNumber = 3;
+    private ulong t_;
+    /// <summary>
+    /// 服务器开始推送时间戳
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ulong T {
+      get { return t_; }
+      set {
+        t_ = value;
+      }
+    }
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as MasterPush);
@@ -1226,6 +1306,7 @@ namespace Protos {
       }
       if (Step != other.Step) return false;
       if (!Values.Equals(other.Values)) return false;
+      if (T != other.T) return false;
       return true;
     }
 
@@ -1234,6 +1315,7 @@ namespace Protos {
       int hash = 1;
       if (Step != 0UL) hash ^= Step.GetHashCode();
       hash ^= Values.GetHashCode();
+      if (T != 0UL) hash ^= T.GetHashCode();
       return hash;
     }
 
@@ -1249,6 +1331,10 @@ namespace Protos {
         output.WriteUInt64(Step);
       }
       values_.WriteTo(output, _map_values_codec);
+      if (T != 0UL) {
+        output.WriteRawTag(24);
+        output.WriteUInt64(T);
+      }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1258,6 +1344,9 @@ namespace Protos {
         size += 1 + pb::CodedOutputStream.ComputeUInt64Size(Step);
       }
       size += values_.CalculateSize(_map_values_codec);
+      if (T != 0UL) {
+        size += 1 + pb::CodedOutputStream.ComputeUInt64Size(T);
+      }
       return size;
     }
 
@@ -1270,6 +1359,9 @@ namespace Protos {
         Step = other.Step;
       }
       values_.Add(other.values_);
+      if (other.T != 0UL) {
+        T = other.T;
+      }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1288,6 +1380,10 @@ namespace Protos {
             values_.AddEntriesFrom(input, _map_values_codec);
             break;
           }
+          case 24: {
+            T = input.ReadUInt64();
+            break;
+          }
         }
       }
     }
@@ -1435,6 +1531,129 @@ namespace Protos {
   }
 
   /// <summary>
+  /// 主机广播消息给flower
+  /// </summary>
+  public sealed partial class MasterNotifyResponse : pb::IMessage<MasterNotifyResponse> {
+    private static readonly pb::MessageParser<MasterNotifyResponse> _parser = new pb::MessageParser<MasterNotifyResponse>(() => new MasterNotifyResponse());
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<MasterNotifyResponse> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Protos.SyncReflection.Descriptor.MessageTypes[10]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public MasterNotifyResponse() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public MasterNotifyResponse(MasterNotifyResponse other) : this() {
+      t_ = other.t_;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public MasterNotifyResponse Clone() {
+      return new MasterNotifyResponse(this);
+    }
+
+    /// <summary>Field number for the "T" field.</summary>
+    public const int TFieldNumber = 1;
+    private ulong t_;
+    /// <summary>
+    /// 服务器收到MasterNotify的时间戳(毫秒)
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ulong T {
+      get { return t_; }
+      set {
+        t_ = value;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as MasterNotifyResponse);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(MasterNotifyResponse other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (T != other.T) return false;
+      return true;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (T != 0UL) hash ^= T.GetHashCode();
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (T != 0UL) {
+        output.WriteRawTag(8);
+        output.WriteUInt64(T);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (T != 0UL) {
+        size += 1 + pb::CodedOutputStream.ComputeUInt64Size(T);
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(MasterNotifyResponse other) {
+      if (other == null) {
+        return;
+      }
+      if (other.T != 0UL) {
+        T = other.T;
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 8: {
+            T = input.ReadUInt64();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  /// <summary>
   /// 主机存储状态
   /// </summary>
   public sealed partial class MasterStoreNotify : pb::IMessage<MasterStoreNotify> {
@@ -1444,7 +1663,7 @@ namespace Protos {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Protos.SyncReflection.Descriptor.MessageTypes[10]; }
+      get { return global::Protos.SyncReflection.Descriptor.MessageTypes[11]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1556,7 +1775,7 @@ namespace Protos {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Protos.SyncReflection.Descriptor.MessageTypes[11]; }
+      get { return global::Protos.SyncReflection.Descriptor.MessageTypes[12]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -1648,7 +1867,7 @@ namespace Protos {
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pbr::MessageDescriptor Descriptor {
-      get { return global::Protos.SyncReflection.Descriptor.MessageTypes[12]; }
+      get { return global::Protos.SyncReflection.Descriptor.MessageTypes[13]; }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]

+ 60 - 3
cs/User.cs

@@ -27,10 +27,11 @@ namespace Protos {
             "ZWFzb24YASABKAUiIAoQSGVhcnRiZWF0UmVxdWVzdBIMCgRQaW5nGAEgASgN",
             "IjMKEUhlYXJ0YmVhdFJlc3BvbnNlEh4KBlJlc3VsdBgBIAEoCzIOLnByb3Rv",
             "cy5SZXN1bHQiMgoMTG9naW5SZXF1ZXN0EiIKCFVzZXJJbmZvGAEgASgLMhAu",
-            "cHJvdG9zLlVzZXJJbmZvIoEBCg1Mb2dpblJlc3BvbnNlEh4KBlJlc3VsdBgB",
+            "cHJvdG9zLlVzZXJJbmZvIpwBCg1Mb2dpblJlc3BvbnNlEh4KBlJlc3VsdBgB",
             "IAEoCzIOLnByb3Rvcy5SZXN1bHQSDwoHTG9iYnlJRBgCIAEoDRIOCgZSb29t",
             "SUQYAyABKA0SFAoMU3luY0ludGVydmFsGAQgASgNEgkKAU4YBSABKA0SDgoG",
-            "RXJybXNnGAYgASgJYgZwcm90bzM="));
+            "RXJybXNnGAYgASgJEgkKAVQYByABKAQSDgoGTWFzdGVyGAggASgIYgZwcm90",
+            "bzM="));
       descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
           new pbr::FileDescriptor[] { global::Protos.UserinfoReflection.Descriptor, global::Protos.ResultReflection.Descriptor, },
           new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
@@ -40,7 +41,7 @@ namespace Protos {
             new pbr::GeneratedClrTypeInfo(typeof(global::Protos.HeartbeatRequest), global::Protos.HeartbeatRequest.Parser, new[]{ "Ping" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Protos.HeartbeatResponse), global::Protos.HeartbeatResponse.Parser, new[]{ "Result" }, null, null, null),
             new pbr::GeneratedClrTypeInfo(typeof(global::Protos.LoginRequest), global::Protos.LoginRequest.Parser, new[]{ "UserInfo" }, null, null, null),
-            new pbr::GeneratedClrTypeInfo(typeof(global::Protos.LoginResponse), global::Protos.LoginResponse.Parser, new[]{ "Result", "LobbyID", "RoomID", "SyncInterval", "N", "Errmsg" }, null, null, null)
+            new pbr::GeneratedClrTypeInfo(typeof(global::Protos.LoginResponse), global::Protos.LoginResponse.Parser, new[]{ "Result", "LobbyID", "RoomID", "SyncInterval", "N", "Errmsg", "T", "Master" }, null, null, null)
           }));
     }
     #endregion
@@ -741,6 +742,8 @@ namespace Protos {
       syncInterval_ = other.syncInterval_;
       n_ = other.n_;
       errmsg_ = other.errmsg_;
+      t_ = other.t_;
+      master_ = other.master_;
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -814,6 +817,28 @@ namespace Protos {
       }
     }
 
+    /// <summary>Field number for the "T" field.</summary>
+    public const int TFieldNumber = 7;
+    private ulong t_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ulong T {
+      get { return t_; }
+      set {
+        t_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "Master" field.</summary>
+    public const int MasterFieldNumber = 8;
+    private bool master_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Master {
+      get { return master_; }
+      set {
+        master_ = value;
+      }
+    }
+
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public override bool Equals(object other) {
       return Equals(other as LoginResponse);
@@ -833,6 +858,8 @@ namespace Protos {
       if (SyncInterval != other.SyncInterval) return false;
       if (N != other.N) return false;
       if (Errmsg != other.Errmsg) return false;
+      if (T != other.T) return false;
+      if (Master != other.Master) return false;
       return true;
     }
 
@@ -845,6 +872,8 @@ namespace Protos {
       if (SyncInterval != 0) hash ^= SyncInterval.GetHashCode();
       if (N != 0) hash ^= N.GetHashCode();
       if (Errmsg.Length != 0) hash ^= Errmsg.GetHashCode();
+      if (T != 0UL) hash ^= T.GetHashCode();
+      if (Master != false) hash ^= Master.GetHashCode();
       return hash;
     }
 
@@ -879,6 +908,14 @@ namespace Protos {
         output.WriteRawTag(50);
         output.WriteString(Errmsg);
       }
+      if (T != 0UL) {
+        output.WriteRawTag(56);
+        output.WriteUInt64(T);
+      }
+      if (Master != false) {
+        output.WriteRawTag(64);
+        output.WriteBool(Master);
+      }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -902,6 +939,12 @@ namespace Protos {
       if (Errmsg.Length != 0) {
         size += 1 + pb::CodedOutputStream.ComputeStringSize(Errmsg);
       }
+      if (T != 0UL) {
+        size += 1 + pb::CodedOutputStream.ComputeUInt64Size(T);
+      }
+      if (Master != false) {
+        size += 1 + 1;
+      }
       return size;
     }
 
@@ -931,6 +974,12 @@ namespace Protos {
       if (other.Errmsg.Length != 0) {
         Errmsg = other.Errmsg;
       }
+      if (other.T != 0UL) {
+        T = other.T;
+      }
+      if (other.Master != false) {
+        Master = other.Master;
+      }
     }
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
@@ -968,6 +1017,14 @@ namespace Protos {
             Errmsg = input.ReadString();
             break;
           }
+          case 56: {
+            T = input.ReadUInt64();
+            break;
+          }
+          case 64: {
+            Master = input.ReadBool();
+            break;
+          }
         }
       }
     }

+ 8 - 0
protos/front.proto

@@ -47,4 +47,12 @@ message EventPackage{
          int32 eventcode=1;
          bool isshow=2;
          string extraParams=3;
+}
+
+message MiniGamePackage{
+         float position_x=1;
+         float position_y=2;
+         float position_z=3;
+         float rotation_y=4;
+         float speed=5;
 }