diff --git a/README.md b/README.md
index ef2cf86..a54cc22 100644
--- a/README.md
+++ b/README.md
@@ -4,8 +4,25 @@
 
 ## 插件介绍
 
-基于upm_guru_kcp库,服务与dof项目的客户端类封装
+基于upm_guru_kcp库,服务与dof项目的客户端类封装.
+在更新了prot文件之后,需要重新生成对应的cs文件。请按以下步骤进行操作:
 
+## 安装 .NET 6.0 运行时(必须使用6.0版本)
+* 下载离线安装包
+https://dotnet.microsoft.com/zh-cn/download/dotnet/thank-you/runtime-6.0.21-macos-x64-installer
+
+* 或者使用 homebrew
+brew tap isen-ng/dotnet-sdk-versions
+brew install --cask dotnet-sdk6-0-400
+
+## 安装 protobuf-net.Protogen 命令行程序
+dotnet tool install --global protobuf-net.Protogen --version 3.2.12
+
+## 进入项目目录
+cd upm_guru_dof_lib/Runtime/ServerProtos
+
+## 生成 cs 文件
+~/.dotnet/tools/protogen messages.proto --csharp_out=../NetworkGen
 
 ## 安装和接入
 
diff --git a/Runtime/NetworkGen/Messages.cs b/Runtime/NetworkGen/Messages.cs
index a904b49..3b5d260 100644
--- a/Runtime/NetworkGen/Messages.cs
+++ b/Runtime/NetworkGen/Messages.cs
@@ -1,20 +1,26 @@
-// This file was generated by a tool; you should avoid making direct changes.
-// Consider using 'partial classes' to extend these types
-// Input: messages.proto
-
-#pragma warning disable CS1591, CS0612, CS3021
+// 
+//   This file was generated by a tool; you should avoid making direct changes.
+//   Consider using 'partial classes' to extend these types
+//   Input: messages.proto
+// 
 
+#region Designer generated code
+#pragma warning disable CS0612, CS0618, CS1591, CS3021, IDE0079, IDE1006, RCS1036, RCS1057, RCS1085, RCS1192
 namespace Dof
 {
 
     [global::ProtoBuf.ProtoContract()]
-    public partial class ClientMessage
+    public partial class ClientMessage : global::ProtoBuf.IExtensible
     {
+        private global::ProtoBuf.IExtension __pbn__extensionData;
+        global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
+            => global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);
+
         [global::ProtoBuf.ProtoMember(1, Name = @"player_enter")]
         public PlayerEnter PlayerEnter
         {
-            get { return __pbn__actual.Is(1) ? ((PlayerEnter)__pbn__actual.Object) : default(PlayerEnter); }
-            set { __pbn__actual = new global::ProtoBuf.DiscriminatedUnionObject(1, value); }
+            get => __pbn__actual.Is(1) ? ((PlayerEnter)__pbn__actual.Object) : default;
+            set => __pbn__actual = new global::ProtoBuf.DiscriminatedUnionObject(1, value);
         }
         public bool ShouldSerializePlayerEnter() => __pbn__actual.Is(1);
         public void ResetPlayerEnter() => global::ProtoBuf.DiscriminatedUnionObject.Reset(ref __pbn__actual, 1);
@@ -24,8 +30,8 @@ namespace Dof
         [global::ProtoBuf.ProtoMember(2, Name = @"level_prepared")]
         public LevelPrepared LevelPrepared
         {
-            get { return __pbn__actual.Is(2) ? ((LevelPrepared)__pbn__actual.Object) : default(LevelPrepared); }
-            set { __pbn__actual = new global::ProtoBuf.DiscriminatedUnionObject(2, value); }
+            get => __pbn__actual.Is(2) ? ((LevelPrepared)__pbn__actual.Object) : default;
+            set => __pbn__actual = new global::ProtoBuf.DiscriminatedUnionObject(2, value);
         }
         public bool ShouldSerializeLevelPrepared() => __pbn__actual.Is(2);
         public void ResetLevelPrepared() => global::ProtoBuf.DiscriminatedUnionObject.Reset(ref __pbn__actual, 2);
@@ -33,8 +39,8 @@ namespace Dof
         [global::ProtoBuf.ProtoMember(3, Name = @"point_found")]
         public PointFound PointFound
         {
-            get { return __pbn__actual.Is(3) ? ((PointFound)__pbn__actual.Object) : default(PointFound); }
-            set { __pbn__actual = new global::ProtoBuf.DiscriminatedUnionObject(3, value); }
+            get => __pbn__actual.Is(3) ? ((PointFound)__pbn__actual.Object) : default;
+            set => __pbn__actual = new global::ProtoBuf.DiscriminatedUnionObject(3, value);
         }
         public bool ShouldSerializePointFound() => __pbn__actual.Is(3);
         public void ResetPointFound() => global::ProtoBuf.DiscriminatedUnionObject.Reset(ref __pbn__actual, 3);
@@ -42,8 +48,8 @@ namespace Dof
         [global::ProtoBuf.ProtoMember(4, Name = @"level_end")]
         public LevelEnd LevelEnd
         {
-            get { return __pbn__actual.Is(4) ? ((LevelEnd)__pbn__actual.Object) : default(LevelEnd); }
-            set { __pbn__actual = new global::ProtoBuf.DiscriminatedUnionObject(4, value); }
+            get => __pbn__actual.Is(4) ? ((LevelEnd)__pbn__actual.Object) : default;
+            set => __pbn__actual = new global::ProtoBuf.DiscriminatedUnionObject(4, value);
         }
         public bool ShouldSerializeLevelEnd() => __pbn__actual.Is(4);
         public void ResetLevelEnd() => global::ProtoBuf.DiscriminatedUnionObject.Reset(ref __pbn__actual, 4);
@@ -51,8 +57,8 @@ namespace Dof
         [global::ProtoBuf.ProtoMember(5, Name = @"all_level_end")]
         public AllLevelEnd AllLevelEnd
         {
-            get { return __pbn__actual.Is(5) ? ((AllLevelEnd)__pbn__actual.Object) : default(AllLevelEnd); }
-            set { __pbn__actual = new global::ProtoBuf.DiscriminatedUnionObject(5, value); }
+            get => __pbn__actual.Is(5) ? ((AllLevelEnd)__pbn__actual.Object) : default;
+            set => __pbn__actual = new global::ProtoBuf.DiscriminatedUnionObject(5, value);
         }
         public bool ShouldSerializeAllLevelEnd() => __pbn__actual.Is(5);
         public void ResetAllLevelEnd() => global::ProtoBuf.DiscriminatedUnionObject.Reset(ref __pbn__actual, 5);
@@ -60,8 +66,8 @@ namespace Dof
         [global::ProtoBuf.ProtoMember(6, Name = @"player_leave")]
         public PlayerLeave PlayerLeave
         {
-            get { return __pbn__actual.Is(6) ? ((PlayerLeave)__pbn__actual.Object) : default(PlayerLeave); }
-            set { __pbn__actual = new global::ProtoBuf.DiscriminatedUnionObject(6, value); }
+            get => __pbn__actual.Is(6) ? ((PlayerLeave)__pbn__actual.Object) : default;
+            set => __pbn__actual = new global::ProtoBuf.DiscriminatedUnionObject(6, value);
         }
         public bool ShouldSerializePlayerLeave() => __pbn__actual.Is(6);
         public void ResetPlayerLeave() => global::ProtoBuf.DiscriminatedUnionObject.Reset(ref __pbn__actual, 6);
@@ -69,13 +75,17 @@ namespace Dof
     }
 
     [global::ProtoBuf.ProtoContract()]
-    public partial class ServerMessage
+    public partial class ServerMessage : global::ProtoBuf.IExtensible
     {
+        private global::ProtoBuf.IExtension __pbn__extensionData;
+        global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
+            => global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);
+
         [global::ProtoBuf.ProtoMember(1, Name = @"player_entered")]
         public PlayerEntered PlayerEntered
         {
-            get { return __pbn__actual.Is(1) ? ((PlayerEntered)__pbn__actual.Object) : default(PlayerEntered); }
-            set { __pbn__actual = new global::ProtoBuf.DiscriminatedUnionObject(1, value); }
+            get => __pbn__actual.Is(1) ? ((PlayerEntered)__pbn__actual.Object) : default;
+            set => __pbn__actual = new global::ProtoBuf.DiscriminatedUnionObject(1, value);
         }
         public bool ShouldSerializePlayerEntered() => __pbn__actual.Is(1);
         public void ResetPlayerEntered() => global::ProtoBuf.DiscriminatedUnionObject.Reset(ref __pbn__actual, 1);
@@ -85,8 +95,8 @@ namespace Dof
         [global::ProtoBuf.ProtoMember(2, Name = @"game_start")]
         public GameStart GameStart
         {
-            get { return __pbn__actual.Is(2) ? ((GameStart)__pbn__actual.Object) : default(GameStart); }
-            set { __pbn__actual = new global::ProtoBuf.DiscriminatedUnionObject(2, value); }
+            get => __pbn__actual.Is(2) ? ((GameStart)__pbn__actual.Object) : default;
+            set => __pbn__actual = new global::ProtoBuf.DiscriminatedUnionObject(2, value);
         }
         public bool ShouldSerializeGameStart() => __pbn__actual.Is(2);
         public void ResetGameStart() => global::ProtoBuf.DiscriminatedUnionObject.Reset(ref __pbn__actual, 2);
@@ -94,8 +104,8 @@ namespace Dof
         [global::ProtoBuf.ProtoMember(3, Name = @"level_start")]
         public LevelStart LevelStart
         {
-            get { return __pbn__actual.Is(3) ? ((LevelStart)__pbn__actual.Object) : default(LevelStart); }
-            set { __pbn__actual = new global::ProtoBuf.DiscriminatedUnionObject(3, value); }
+            get => __pbn__actual.Is(3) ? ((LevelStart)__pbn__actual.Object) : default;
+            set => __pbn__actual = new global::ProtoBuf.DiscriminatedUnionObject(3, value);
         }
         public bool ShouldSerializeLevelStart() => __pbn__actual.Is(3);
         public void ResetLevelStart() => global::ProtoBuf.DiscriminatedUnionObject.Reset(ref __pbn__actual, 3);
@@ -103,8 +113,8 @@ namespace Dof
         [global::ProtoBuf.ProtoMember(4, Name = @"point_found")]
         public PointFound PointFound
         {
-            get { return __pbn__actual.Is(4) ? ((PointFound)__pbn__actual.Object) : default(PointFound); }
-            set { __pbn__actual = new global::ProtoBuf.DiscriminatedUnionObject(4, value); }
+            get => __pbn__actual.Is(4) ? ((PointFound)__pbn__actual.Object) : default;
+            set => __pbn__actual = new global::ProtoBuf.DiscriminatedUnionObject(4, value);
         }
         public bool ShouldSerializePointFound() => __pbn__actual.Is(4);
         public void ResetPointFound() => global::ProtoBuf.DiscriminatedUnionObject.Reset(ref __pbn__actual, 4);
@@ -112,8 +122,8 @@ namespace Dof
         [global::ProtoBuf.ProtoMember(5, Name = @"game_finish")]
         public GameFinish GameFinish
         {
-            get { return __pbn__actual.Is(5) ? ((GameFinish)__pbn__actual.Object) : default(GameFinish); }
-            set { __pbn__actual = new global::ProtoBuf.DiscriminatedUnionObject(5, value); }
+            get => __pbn__actual.Is(5) ? ((GameFinish)__pbn__actual.Object) : default;
+            set => __pbn__actual = new global::ProtoBuf.DiscriminatedUnionObject(5, value);
         }
         public bool ShouldSerializeGameFinish() => __pbn__actual.Is(5);
         public void ResetGameFinish() => global::ProtoBuf.DiscriminatedUnionObject.Reset(ref __pbn__actual, 5);
@@ -121,8 +131,12 @@ namespace Dof
     }
 
     [global::ProtoBuf.ProtoContract()]
-    public partial class PlayerEnter
+    public partial class PlayerEnter : global::ProtoBuf.IExtensible
     {
+        private global::ProtoBuf.IExtension __pbn__extensionData;
+        global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
+            => global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);
+
         [global::ProtoBuf.ProtoMember(1, Name = @"room_id")]
         [global::System.ComponentModel.DefaultValue("")]
         public string RoomId { get; set; } = "";
@@ -142,8 +156,12 @@ namespace Dof
     }
 
     [global::ProtoBuf.ProtoContract()]
-    public partial class LevelResource
+    public partial class LevelResource : global::ProtoBuf.IExtensible
     {
+        private global::ProtoBuf.IExtension __pbn__extensionData;
+        global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
+            => global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);
+
         [global::ProtoBuf.ProtoMember(1, Name = @"level_id")]
         [global::System.ComponentModel.DefaultValue("")]
         public string LevelId { get; set; } = "";
@@ -159,24 +177,36 @@ namespace Dof
     }
 
     [global::ProtoBuf.ProtoContract()]
-    public partial class PlayerEntered
+    public partial class PlayerEntered : global::ProtoBuf.IExtensible
     {
+        private global::ProtoBuf.IExtension __pbn__extensionData;
+        global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
+            => global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);
+
         [global::ProtoBuf.ProtoMember(1, Name = @"cid")]
         public long Cid { get; set; }
 
     }
 
     [global::ProtoBuf.ProtoContract()]
-    public partial class GameStart
+    public partial class GameStart : global::ProtoBuf.IExtensible
     {
+        private global::ProtoBuf.IExtension __pbn__extensionData;
+        global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
+            => global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);
+
         [global::ProtoBuf.ProtoMember(1, Name = @"level_resource")]
         public global::System.Collections.Generic.List LevelResources { get; } = new global::System.Collections.Generic.List();
 
     }
 
     [global::ProtoBuf.ProtoContract()]
-    public partial class LevelPrepared
+    public partial class LevelPrepared : global::ProtoBuf.IExtensible
     {
+        private global::ProtoBuf.IExtension __pbn__extensionData;
+        global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
+            => global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);
+
         [global::ProtoBuf.ProtoMember(1, Name = @"cid")]
         public long Cid { get; set; }
 
@@ -187,8 +217,12 @@ namespace Dof
     }
 
     [global::ProtoBuf.ProtoContract()]
-    public partial class LevelStart
+    public partial class LevelStart : global::ProtoBuf.IExtensible
     {
+        private global::ProtoBuf.IExtension __pbn__extensionData;
+        global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
+            => global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);
+
         [global::ProtoBuf.ProtoMember(1, Name = @"level")]
         [global::System.ComponentModel.DefaultValue("")]
         public string Level { get; set; } = "";
@@ -196,8 +230,12 @@ namespace Dof
     }
 
     [global::ProtoBuf.ProtoContract()]
-    public partial class PointFound
+    public partial class PointFound : global::ProtoBuf.IExtensible
     {
+        private global::ProtoBuf.IExtension __pbn__extensionData;
+        global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
+            => global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);
+
         [global::ProtoBuf.ProtoMember(1, Name = @"cid")]
         public long Cid { get; set; }
 
@@ -211,8 +249,12 @@ namespace Dof
     }
 
     [global::ProtoBuf.ProtoContract()]
-    public partial class LevelEnd
+    public partial class LevelEnd : global::ProtoBuf.IExtensible
     {
+        private global::ProtoBuf.IExtension __pbn__extensionData;
+        global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
+            => global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);
+
         [global::ProtoBuf.ProtoMember(1, Name = @"cid")]
         public long Cid { get; set; }
 
@@ -223,16 +265,24 @@ namespace Dof
     }
 
     [global::ProtoBuf.ProtoContract()]
-    public partial class AllLevelEnd
+    public partial class AllLevelEnd : global::ProtoBuf.IExtensible
     {
+        private global::ProtoBuf.IExtension __pbn__extensionData;
+        global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
+            => global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);
+
         [global::ProtoBuf.ProtoMember(1, Name = @"cid")]
         public long Cid { get; set; }
 
     }
 
     [global::ProtoBuf.ProtoContract()]
-    public partial class GameScore
+    public partial class GameScore : global::ProtoBuf.IExtensible
     {
+        private global::ProtoBuf.IExtension __pbn__extensionData;
+        global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
+            => global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);
+
         [global::ProtoBuf.ProtoMember(1, Name = @"uid")]
         [global::System.ComponentModel.DefaultValue("")]
         public string Uid { get; set; } = "";
@@ -243,16 +293,24 @@ namespace Dof
     }
 
     [global::ProtoBuf.ProtoContract()]
-    public partial class GameFinish
+    public partial class GameFinish : global::ProtoBuf.IExtensible
     {
+        private global::ProtoBuf.IExtension __pbn__extensionData;
+        global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
+            => global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);
+
         [global::ProtoBuf.ProtoMember(1, Name = @"scores")]
         public global::System.Collections.Generic.List Scores { get; } = new global::System.Collections.Generic.List();
 
     }
 
     [global::ProtoBuf.ProtoContract()]
-    public partial class PlayerLeave
+    public partial class PlayerLeave : global::ProtoBuf.IExtensible
     {
+        private global::ProtoBuf.IExtension __pbn__extensionData;
+        global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
+            => global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);
+
         [global::ProtoBuf.ProtoMember(1, Name = @"cid")]
         public long Cid { get; set; }
 
@@ -260,4 +318,5 @@ namespace Dof
 
 }
 
-#pragma warning restore CS1591, CS0612, CS3021
+#pragma warning restore CS0612, CS0618, CS1591, CS3021, IDE0079, IDE1006, RCS1036, RCS1057, RCS1085, RCS1192
+#endregion
diff --git a/Runtime/ServerProto.meta b/Runtime/ServerProto.meta
new file mode 100644
index 0000000..452affe
--- /dev/null
+++ b/Runtime/ServerProto.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 12246e2263bf547dab4b44aad300edce
+folderAsset: yes
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Runtime/ServerProto/messages.proto b/Runtime/ServerProto/messages.proto
new file mode 100644
index 0000000..534fed5
--- /dev/null
+++ b/Runtime/ServerProto/messages.proto
@@ -0,0 +1,86 @@
+syntax = "proto3";
+package dof;
+option go_package = "./;pb";
+
+// ClientMessage 客户端发送给服务端的消息类型
+message ClientMessage {
+  oneof actual {
+    PlayerEnter player_enter = 1;
+    LevelPrepared level_prepared = 2;
+    PointFound point_found = 3;
+    LevelEnd level_end = 4;
+    AllLevelEnd all_level_end = 5;
+    PlayerLeave player_leave = 6;
+  }
+}
+
+// ServerMessage 服务端发送给客户端的消息类型
+message ServerMessage {
+  oneof actual {
+    PlayerEntered player_entered = 1;
+    GameStart game_start = 2;
+    LevelStart level_start = 3;
+    PointFound point_found = 4;
+    GameFinish game_finish = 5;
+  }
+}
+
+// PlayerEnter 客户端进入房间
+message PlayerEnter {
+  string room_id = 1;
+  string uid = 2;
+  string nick_name = 3;
+  string country = 4;
+}
+
+message LevelResource {
+  string level_id = 1;
+  string android_generation = 2;
+  string ios_generation = 3;
+}
+
+// PlayerEntered 服务端接收到 PlayerEnter 消息后发还给客户端的回执
+message PlayerEntered {
+  int64 cid = 1;
+}
+
+message GameStart {
+  repeated LevelResource level_resource = 1;
+}
+
+message LevelPrepared {
+  int64 cid = 1;
+  string level = 2;
+}
+
+message LevelStart {
+  string level = 1;
+}
+
+message PointFound {
+  int64 cid = 1;
+  string level = 2;
+  int32 point_id = 3;
+}
+
+message LevelEnd {
+  int64 cid = 1;
+  string level = 2;
+}
+
+message AllLevelEnd {
+  int64 cid = 1;
+}
+
+message GameScore {
+  string uid = 1;
+  int32 score = 2;
+}
+
+message GameFinish {
+  repeated GameScore scores = 1;
+}
+
+message PlayerLeave {
+  int64 cid = 1;
+}
diff --git a/Runtime/ServerProto/messages.proto.meta b/Runtime/ServerProto/messages.proto.meta
new file mode 100644
index 0000000..20519ed
--- /dev/null
+++ b/Runtime/ServerProto/messages.proto.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 708181539a3344339a13ca0252be5c5e
+DefaultImporter:
+  externalObjects: {}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: