diff --git a/data/DB_Game_Drop.dat b/data/DB_Game_Drop.dat
index cb9b22d..93817af 100644
--- a/data/DB_Game_Drop.dat
+++ b/data/DB_Game_Drop.dat
@@ -208,59 +208,51 @@
 ÆÒ€´‰(±ê0�N:¯È
 ÇÒÀÊº(±ê0�N:Èá
 ÈÒ€áë(±ê0�N:áú
-Éð�N(±ê0J:
-ÊðÐ†(±ê0ó:
-ËðÀš(±ê0Í:
-ÌðÀ„=(±ê0�::
-ÍðÀ–±(±ê0�N:
-
-Îð€ÚÄ	(±ê0�N:Kd
-Ïô �(±ê0ç:
-Ðô Â(±ê0�:
-Ñô€‰z(±ê0�N:
-
-Òô€­â(±ê0�N:2
-Óô€áë(±ê0�N:áú
-Ôô€„¯_(±ê0�N:¬ô
-Õñ�N(±ê0J:
-ÖñÐ†(±ê0ó:
-×ñÀš(±ê0Í:
-ØñÀ„=(±ê0�::
-ÙñÀ–±(±ê0�N:
-
-Úñ€ÚÄ	(±ê0�N:Kd
-Ûõ�N(±ê0J:
-ÜõÐ†(±ê0ó:
-ÝõÀš(±ê0Í:
-ÞõÀ„=(±ê0�::
-ßõÀ–±(±ê0�N:
-
-àõ€ÚÄ	(±ê0�N:Kd
-áò�N(±ê0J:
-âòÐ†(±ê0ó:
-ãòÀš(±ê0Í:
-äòÀ„=(±ê0�::
-åòÀ–±(±ê0�N:
-
-æò€ÚÄ	(±ê0�N:Kd
-çö�N(±ê0J:
-èöÐ†(±ê0ó:
-éöÀš(±ê0Í:
-êöÀ„=(±ê0�::
-ëöÀ–±(±ê0�N:
-
-ìö€ÚÄ	(±ê0�N:Kd
-íó�N(±ê0J:
-îóÐ†(±ê0ó:
-ïóÀš(±ê0Í:
-ðóÀ„=(±ê0�::
-ñóÀ–±(±ê0�N:
-
-òó€ÚÄ	(±ê0�N:Kd
-ó÷�N(±ê0J:
-ô÷Ð†(±ê0ó:
-õ÷Àš(±ê0Í:
-ö÷À„=(±ê0�::
-÷÷À–±(±ê0�N:
-
-ø÷€ÚÄ	(±ê0�N:Kd
\ No newline at end of file
+Éð�N(±ê0•:
+ÊðÐ†(±ê0ç:
+ËðÀš(±ê0š:
+ÌðÀ„=(±ê0�N:
+ÍðÀ–±(±ê0�N:	
+Îð€ÚÄ	(±ê0�N: 
+Ïô �(±ê0Í:
+Ðô Â(±ê0�::
+Ñô€‰z(±ê0�N:
+Òô€­â(±ê0�N:

+Óô€áë(±ê0�N:HL
+Ôô€„¯_(±ê0�N:§«
+Õñ�N(±ê0•:
+ÖñÐ†(±ê0ç:
+×ñÀš(±ê0š:
+ØñÀ„=(±ê0�N:
+ÙñÀ–±(±ê0�N:	
+Úñ€ÚÄ	(±ê0�N: 
+Ûõ�N(±ê0•:
+ÜõÐ†(±ê0ç:
+ÝõÀš(±ê0š:
+ÞõÀ„=(±ê0�N:
+ßõÀ–±(±ê0�N:	
+àõ€ÚÄ	(±ê0�N: 
+áò�N(±ê0•:
+âòÐ†(±ê0ç:
+ãòÀš(±ê0š:
+äòÀ„=(±ê0�N:
+åòÀ–±(±ê0�N:	
+æò€ÚÄ	(±ê0�N: 
+çö�N(±ê0•:
+èöÐ†(±ê0ç:
+éöÀš(±ê0š:
+êöÀ„=(±ê0�N:
+ëöÀ–±(±ê0�N:	
+ìö€ÚÄ	(±ê0�N: 
+íó�N(±ê0•:
+îóÐ†(±ê0ç:
+ïóÀš(±ê0š:
+ðóÀ„=(±ê0�N:
+ñóÀ–±(±ê0�N:	
+òó€ÚÄ	(±ê0�N: 
+ó÷�N(±ê0•:
+ô÷Ð†(±ê0ç:
+õ÷Àš(±ê0š:
+ö÷À„=(±ê0�N:
+÷÷À–±(±ê0�N:	
+ø÷€ÚÄ	(±ê0�N: 
\ No newline at end of file
diff --git a/data/DB_Game_Drop.json b/data/DB_Game_Drop.json
index 2968cd8..2da5d7a 100644
--- a/data/DB_Game_Drop.json
+++ b/data/DB_Game_Drop.json
@@ -2205,7 +2205,7 @@
 			"GameId": 240,
 			"Bet": 10000,
 			"ItemId1": 30001,
-			"Rate1": 74,
+			"Rate1": 149,
 			"Amount1": [
 				1,
 				1
@@ -2216,7 +2216,7 @@
 			"GameId": 240,
 			"Bet": 50000,
 			"ItemId1": 30001,
-			"Rate1": 371,
+			"Rate1": 743,
 			"Amount1": [
 				1,
 				1
@@ -2227,7 +2227,7 @@
 			"GameId": 240,
 			"Bet": 200000,
 			"ItemId1": 30001,
-			"Rate1": 1485,
+			"Rate1": 2970,
 			"Amount1": [
 				1,
 				1
@@ -2238,7 +2238,7 @@
 			"GameId": 240,
 			"Bet": 1000000,
 			"ItemId1": 30001,
-			"Rate1": 7425,
+			"Rate1": 10000,
 			"Amount1": [
 				3,
 				5
@@ -2251,8 +2251,8 @@
 			"ItemId1": 30001,
 			"Rate1": 10000,
 			"Amount1": [
-				10,
-				25
+				5,
+				9
 			]
 		},
 		{
@@ -2262,8 +2262,8 @@
 			"ItemId1": 30001,
 			"Rate1": 10000,
 			"Amount1": [
-				75,
-				100
+				28,
+				32
 			]
 		},
 		{
@@ -2271,7 +2271,7 @@
 			"GameId": 244,
 			"Bet": 100000,
 			"ItemId1": 30001,
-			"Rate1": 743,
+			"Rate1": 1485,
 			"Amount1": [
 				1,
 				1
@@ -2282,7 +2282,7 @@
 			"GameId": 244,
 			"Bet": 500000,
 			"ItemId1": 30001,
-			"Rate1": 3713,
+			"Rate1": 7425,
 			"Amount1": [
 				2,
 				3
@@ -2295,8 +2295,8 @@
 			"ItemId1": 30001,
 			"Rate1": 10000,
 			"Amount1": [
-				5,
-				10
+				1,
+				5
 			]
 		},
 		{
@@ -2306,8 +2306,8 @@
 			"ItemId1": 30001,
 			"Rate1": 10000,
 			"Amount1": [
-				25,
-				50
+				13,
+				17
 			]
 		},
 		{
@@ -2317,8 +2317,8 @@
 			"ItemId1": 30001,
 			"Rate1": 10000,
 			"Amount1": [
-				225,
-				250
+				72,
+				76
 			]
 		},
 		{
@@ -2328,8 +2328,8 @@
 			"ItemId1": 30001,
 			"Rate1": 10000,
 			"Amount1": [
-				300,
-				500
+				295,
+				299
 			]
 		},
 		{
@@ -2337,7 +2337,7 @@
 			"GameId": 241,
 			"Bet": 10000,
 			"ItemId1": 30001,
-			"Rate1": 74,
+			"Rate1": 149,
 			"Amount1": [
 				1,
 				1
@@ -2348,7 +2348,7 @@
 			"GameId": 241,
 			"Bet": 50000,
 			"ItemId1": 30001,
-			"Rate1": 371,
+			"Rate1": 743,
 			"Amount1": [
 				1,
 				1
@@ -2359,7 +2359,7 @@
 			"GameId": 241,
 			"Bet": 200000,
 			"ItemId1": 30001,
-			"Rate1": 1485,
+			"Rate1": 2970,
 			"Amount1": [
 				1,
 				1
@@ -2370,7 +2370,7 @@
 			"GameId": 241,
 			"Bet": 1000000,
 			"ItemId1": 30001,
-			"Rate1": 7425,
+			"Rate1": 10000,
 			"Amount1": [
 				3,
 				5
@@ -2383,8 +2383,8 @@
 			"ItemId1": 30001,
 			"Rate1": 10000,
 			"Amount1": [
-				10,
-				25
+				5,
+				9
 			]
 		},
 		{
@@ -2394,8 +2394,8 @@
 			"ItemId1": 30001,
 			"Rate1": 10000,
 			"Amount1": [
-				75,
-				100
+				28,
+				32
 			]
 		},
 		{
@@ -2403,7 +2403,7 @@
 			"GameId": 245,
 			"Bet": 10000,
 			"ItemId1": 30001,
-			"Rate1": 74,
+			"Rate1": 149,
 			"Amount1": [
 				1,
 				1
@@ -2414,7 +2414,7 @@
 			"GameId": 245,
 			"Bet": 50000,
 			"ItemId1": 30001,
-			"Rate1": 371,
+			"Rate1": 743,
 			"Amount1": [
 				1,
 				1
@@ -2425,7 +2425,7 @@
 			"GameId": 245,
 			"Bet": 200000,
 			"ItemId1": 30001,
-			"Rate1": 1485,
+			"Rate1": 2970,
 			"Amount1": [
 				1,
 				1
@@ -2436,7 +2436,7 @@
 			"GameId": 245,
 			"Bet": 1000000,
 			"ItemId1": 30001,
-			"Rate1": 7425,
+			"Rate1": 10000,
 			"Amount1": [
 				3,
 				5
@@ -2449,8 +2449,8 @@
 			"ItemId1": 30001,
 			"Rate1": 10000,
 			"Amount1": [
-				10,
-				25
+				5,
+				9
 			]
 		},
 		{
@@ -2460,8 +2460,8 @@
 			"ItemId1": 30001,
 			"Rate1": 10000,
 			"Amount1": [
-				75,
-				100
+				28,
+				32
 			]
 		},
 		{
@@ -2469,7 +2469,7 @@
 			"GameId": 242,
 			"Bet": 10000,
 			"ItemId1": 30001,
-			"Rate1": 74,
+			"Rate1": 149,
 			"Amount1": [
 				1,
 				1
@@ -2480,7 +2480,7 @@
 			"GameId": 242,
 			"Bet": 50000,
 			"ItemId1": 30001,
-			"Rate1": 371,
+			"Rate1": 743,
 			"Amount1": [
 				1,
 				1
@@ -2491,7 +2491,7 @@
 			"GameId": 242,
 			"Bet": 200000,
 			"ItemId1": 30001,
-			"Rate1": 1485,
+			"Rate1": 2970,
 			"Amount1": [
 				1,
 				1
@@ -2502,7 +2502,7 @@
 			"GameId": 242,
 			"Bet": 1000000,
 			"ItemId1": 30001,
-			"Rate1": 7425,
+			"Rate1": 10000,
 			"Amount1": [
 				3,
 				5
@@ -2515,8 +2515,8 @@
 			"ItemId1": 30001,
 			"Rate1": 10000,
 			"Amount1": [
-				10,
-				25
+				5,
+				9
 			]
 		},
 		{
@@ -2526,8 +2526,8 @@
 			"ItemId1": 30001,
 			"Rate1": 10000,
 			"Amount1": [
-				75,
-				100
+				28,
+				32
 			]
 		},
 		{
@@ -2535,7 +2535,7 @@
 			"GameId": 246,
 			"Bet": 10000,
 			"ItemId1": 30001,
-			"Rate1": 74,
+			"Rate1": 149,
 			"Amount1": [
 				1,
 				1
@@ -2546,7 +2546,7 @@
 			"GameId": 246,
 			"Bet": 50000,
 			"ItemId1": 30001,
-			"Rate1": 371,
+			"Rate1": 743,
 			"Amount1": [
 				1,
 				1
@@ -2557,7 +2557,7 @@
 			"GameId": 246,
 			"Bet": 200000,
 			"ItemId1": 30001,
-			"Rate1": 1485,
+			"Rate1": 2970,
 			"Amount1": [
 				1,
 				1
@@ -2568,7 +2568,7 @@
 			"GameId": 246,
 			"Bet": 1000000,
 			"ItemId1": 30001,
-			"Rate1": 7425,
+			"Rate1": 10000,
 			"Amount1": [
 				3,
 				5
@@ -2581,8 +2581,8 @@
 			"ItemId1": 30001,
 			"Rate1": 10000,
 			"Amount1": [
-				10,
-				25
+				5,
+				9
 			]
 		},
 		{
@@ -2592,8 +2592,8 @@
 			"ItemId1": 30001,
 			"Rate1": 10000,
 			"Amount1": [
-				75,
-				100
+				28,
+				32
 			]
 		},
 		{
@@ -2601,7 +2601,7 @@
 			"GameId": 243,
 			"Bet": 10000,
 			"ItemId1": 30001,
-			"Rate1": 74,
+			"Rate1": 149,
 			"Amount1": [
 				1,
 				1
@@ -2612,7 +2612,7 @@
 			"GameId": 243,
 			"Bet": 50000,
 			"ItemId1": 30001,
-			"Rate1": 371,
+			"Rate1": 743,
 			"Amount1": [
 				1,
 				1
@@ -2623,7 +2623,7 @@
 			"GameId": 243,
 			"Bet": 200000,
 			"ItemId1": 30001,
-			"Rate1": 1485,
+			"Rate1": 2970,
 			"Amount1": [
 				1,
 				1
@@ -2634,7 +2634,7 @@
 			"GameId": 243,
 			"Bet": 1000000,
 			"ItemId1": 30001,
-			"Rate1": 7425,
+			"Rate1": 10000,
 			"Amount1": [
 				3,
 				5
@@ -2647,8 +2647,8 @@
 			"ItemId1": 30001,
 			"Rate1": 10000,
 			"Amount1": [
-				10,
-				25
+				5,
+				9
 			]
 		},
 		{
@@ -2658,8 +2658,8 @@
 			"ItemId1": 30001,
 			"Rate1": 10000,
 			"Amount1": [
-				75,
-				100
+				28,
+				32
 			]
 		},
 		{
@@ -2667,7 +2667,7 @@
 			"GameId": 247,
 			"Bet": 10000,
 			"ItemId1": 30001,
-			"Rate1": 74,
+			"Rate1": 149,
 			"Amount1": [
 				1,
 				1
@@ -2678,7 +2678,7 @@
 			"GameId": 247,
 			"Bet": 50000,
 			"ItemId1": 30001,
-			"Rate1": 371,
+			"Rate1": 743,
 			"Amount1": [
 				1,
 				1
@@ -2689,7 +2689,7 @@
 			"GameId": 247,
 			"Bet": 200000,
 			"ItemId1": 30001,
-			"Rate1": 1485,
+			"Rate1": 2970,
 			"Amount1": [
 				1,
 				1
@@ -2700,7 +2700,7 @@
 			"GameId": 247,
 			"Bet": 1000000,
 			"ItemId1": 30001,
-			"Rate1": 7425,
+			"Rate1": 10000,
 			"Amount1": [
 				3,
 				5
@@ -2713,8 +2713,8 @@
 			"ItemId1": 30001,
 			"Rate1": 10000,
 			"Amount1": [
-				10,
-				25
+				5,
+				9
 			]
 		},
 		{
@@ -2724,8 +2724,8 @@
 			"ItemId1": 30001,
 			"Rate1": 10000,
 			"Amount1": [
-				75,
-				100
+				28,
+				32
 			]
 		}
 	]
diff --git a/data/DB_PropExchange.dat b/data/DB_PropExchange.dat
index b7451ac..bed563e 100644
--- a/data/DB_PropExchange.dat
+++ b/data/DB_PropExchange.dat
@@ -1,5 +1,5 @@
 
-6Ó†Ô†Õ†Ö†×†"¡�À„=
+6Õ†Ö†×†Ó†Ô†"¡�À„=
 .Ø†Ù†Ú†Û†"¡�À„=
-WÙ†Ú†Û†Ó†Ô†Ö†Ø†Õ†×†"	¡�€­â
-]Ö†×†Ø†Ú†Û†Ü†Ó†Ô†Õ†Ù†"¢�ô
\ No newline at end of file
+WÖ†Õ†Ô†×†Ø†Ù†Ú†Û†Ó†"	¡�€­â
+]×†Ø†Û†Ó†Ô†Ö†Ü†Õ†Ù†Ú†"¢�ô
\ No newline at end of file
diff --git a/data/DB_Task.dat b/data/DB_Task.dat
index bb6d597..50d1fa8 100644
Binary files a/data/DB_Task.dat and b/data/DB_Task.dat differ
diff --git a/etcd/keyconf.go b/etcd/keyconf.go
index 7a832c6..a7710b8 100644
--- a/etcd/keyconf.go
+++ b/etcd/keyconf.go
@@ -53,4 +53,5 @@ const (
 	ETCDKEY_PLAYERPOOL                 = "/game/plt/playerpool/"  // ä¸ªäººæ°´æ± è°ƒæŽ§é…�ç½®
 	ETCDKEY_GAME_CONFIG                = "/game/plt/gameconfig/"  // æ¸¸æˆ�ç®¡ç�†/å…¨å±€é…�ç½®
 	ETCDKEY_ACT_PHONELOTTERY           = "/game/act_phoneLottery"
+	ETCDKEY_EXCHANGECHANNEL            = "/game/exchange/channel" // å¼€å�¯å…‘æ�¢åŠŸèƒ½çš„æ¸ é�“
 )
diff --git a/model/config.go b/model/config.go
index cc0f4a1..d93c6f2 100644
--- a/model/config.go
+++ b/model/config.go
@@ -115,6 +115,8 @@ type AllConfig struct {
 	*webapi.ExchangeShopList
 	// å•†åº—
 	ShopInfos map[int32]*ShopInfo // å•†å“�id:å•†å“�ä¿¡æ�¯
+	// å¼€å�¯å…‘æ�¢çš„æ¸ é�“
+	*webapi.ExchangeChannelConfig
 }
 
 type GlobalConfig struct {
diff --git a/protocol/gamehall/game.pb.go b/protocol/gamehall/game.pb.go
index a15294c..0a97e7f 100644
--- a/protocol/gamehall/game.pb.go
+++ b/protocol/gamehall/game.pb.go
@@ -284,6 +284,8 @@ const (
 	GameHallPacketID_PACKET_CS_PLAYER_SWITCHFLAG           GameHallPacketID = 8008
 	GameHallPacketID_PACKET_CSRoomEvent                    GameHallPacketID = 8009 // æˆ¿é—´äº‹ä»¶
 	GameHallPacketID_PACKET_SCRoomEvent                    GameHallPacketID = 8010 // æˆ¿é—´äº‹ä»¶
+	GameHallPacketID_PACKET_CSExchangeChannel              GameHallPacketID = 8011 // å¼€å�¯å…‘æ�¢çš„æ¸ é�“
+	GameHallPacketID_PACKET_SCExchangeChannel              GameHallPacketID = 8012 // å¼€å�¯å…‘æ�¢çš„æ¸ é�“
 )
 
 // Enum value maps for GameHallPacketID.
@@ -390,6 +392,8 @@ var (
 		8008: "PACKET_CS_PLAYER_SWITCHFLAG",
 		8009: "PACKET_CSRoomEvent",
 		8010: "PACKET_SCRoomEvent",
+		8011: "PACKET_CSExchangeChannel",
+		8012: "PACKET_SCExchangeChannel",
 	}
 	GameHallPacketID_value = map[string]int32{
 		"PACKET_GameHall_ZERO":                  0,
@@ -493,6 +497,8 @@ var (
 		"PACKET_CS_PLAYER_SWITCHFLAG":           8008,
 		"PACKET_CSRoomEvent":                    8009,
 		"PACKET_SCRoomEvent":                    8010,
+		"PACKET_CSExchangeChannel":              8011,
+		"PACKET_SCExchangeChannel":              8012,
 	}
 )
 
@@ -7182,6 +7188,93 @@ func (x *SCRoomEvent) GetTs() int64 {
 	return 0
 }
 
+// PACKET_CSExchangeChannel
+type CSExchangeChannel struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *CSExchangeChannel) Reset() {
+	*x = CSExchangeChannel{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_game_proto_msgTypes[102]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CSExchangeChannel) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CSExchangeChannel) ProtoMessage() {}
+
+func (x *CSExchangeChannel) ProtoReflect() protoreflect.Message {
+	mi := &file_game_proto_msgTypes[102]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CSExchangeChannel.ProtoReflect.Descriptor instead.
+func (*CSExchangeChannel) Descriptor() ([]byte, []int) {
+	return file_game_proto_rawDescGZIP(), []int{102}
+}
+
+// PACKET_SCExchangeChannel
+type SCExchangeChannel struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	OnChannelName []string `protobuf:"bytes,1,rep,name=OnChannelName,proto3" json:"OnChannelName,omitempty"` // å¼€å�¯æ¸ é�“
+}
+
+func (x *SCExchangeChannel) Reset() {
+	*x = SCExchangeChannel{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_game_proto_msgTypes[103]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SCExchangeChannel) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SCExchangeChannel) ProtoMessage() {}
+
+func (x *SCExchangeChannel) ProtoReflect() protoreflect.Message {
+	mi := &file_game_proto_msgTypes[103]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SCExchangeChannel.ProtoReflect.Descriptor instead.
+func (*SCExchangeChannel) Descriptor() ([]byte, []int) {
+	return file_game_proto_rawDescGZIP(), []int{103}
+}
+
+func (x *SCExchangeChannel) GetOnChannelName() []string {
+	if x != nil {
+		return x.OnChannelName
+	}
+	return nil
+}
+
 var File_game_proto protoreflect.FileDescriptor
 
 var file_game_proto_rawDesc = []byte{
@@ -7913,7 +8006,12 @@ var file_game_proto_rawDesc = []byte{
 	0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x43,
 	0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x18,
 	0x05, 0x20, 0x03, 0x28, 0x05, 0x52, 0x05, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x12, 0x0e, 0x0a, 0x02,
-	0x54, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x54, 0x73, 0x2a, 0xe6, 0x09, 0x0a,
+	0x54, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x54, 0x73, 0x22, 0x13, 0x0a, 0x11,
+	0x43, 0x53, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65,
+	0x6c, 0x22, 0x39, 0x0a, 0x11, 0x53, 0x43, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x43,
+	0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x24, 0x0a, 0x0d, 0x4f, 0x6e, 0x43, 0x68, 0x61, 0x6e,
+	0x6e, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x4f,
+	0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x2a, 0xe6, 0x09, 0x0a,
 	0x11, 0x4f, 0x70, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x5f, 0x47, 0x61,
 	0x6d, 0x65, 0x12, 0x14, 0x0a, 0x10, 0x4f, 0x50, 0x52, 0x43, 0x5f, 0x53, 0x75, 0x63, 0x65, 0x73,
 	0x73, 0x5f, 0x47, 0x61, 0x6d, 0x65, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x4f, 0x50, 0x52, 0x43,
@@ -7992,7 +8090,7 @@ var file_game_proto_rawDesc = []byte{
 	0x5f, 0x51, 0x75, 0x6f, 0x74, 0x61, 0x4e, 0x6f, 0x74, 0x45, 0x6e, 0x6f, 0x75, 0x67, 0x68, 0x5f,
 	0x47, 0x61, 0x6d, 0x65, 0x10, 0xab, 0x46, 0x12, 0x1c, 0x0a, 0x17, 0x4f, 0x50, 0x52, 0x43, 0x5f,
 	0x54, 0x68, 0x72, 0x5f, 0x47, 0x61, 0x6d, 0x65, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x5f, 0x47, 0x61,
-	0x6d, 0x65, 0x10, 0xb2, 0x46, 0x2a, 0xd0, 0x17, 0x0a, 0x10, 0x47, 0x61, 0x6d, 0x65, 0x48, 0x61,
+	0x6d, 0x65, 0x10, 0xb2, 0x46, 0x2a, 0x8e, 0x18, 0x0a, 0x10, 0x47, 0x61, 0x6d, 0x65, 0x48, 0x61,
 	0x6c, 0x6c, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x49, 0x44, 0x12, 0x18, 0x0a, 0x14, 0x50, 0x41,
 	0x43, 0x4b, 0x45, 0x54, 0x5f, 0x47, 0x61, 0x6d, 0x65, 0x48, 0x61, 0x6c, 0x6c, 0x5f, 0x5a, 0x45,
 	0x52, 0x4f, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x12, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x5f, 0x43,
@@ -8181,10 +8279,14 @@ var file_game_proto_rawDesc = []byte{
 	0x4c, 0x41, 0x47, 0x10, 0xc8, 0x3e, 0x12, 0x17, 0x0a, 0x12, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54,
 	0x5f, 0x43, 0x53, 0x52, 0x6f, 0x6f, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x10, 0xc9, 0x3e, 0x12,
 	0x17, 0x0a, 0x12, 0x50, 0x41, 0x43, 0x4b, 0x45, 0x54, 0x5f, 0x53, 0x43, 0x52, 0x6f, 0x6f, 0x6d,
-	0x45, 0x76, 0x65, 0x6e, 0x74, 0x10, 0xca, 0x3e, 0x42, 0x28, 0x5a, 0x26, 0x6d, 0x6f, 0x6e, 0x67,
-	0x6f, 0x2e, 0x67, 0x61, 0x6d, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x61, 0x6d, 0x65,
-	0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x61, 0x6d, 0x65, 0x68, 0x61,
-	0x6c, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x45, 0x76, 0x65, 0x6e, 0x74, 0x10, 0xca, 0x3e, 0x12, 0x1d, 0x0a, 0x18, 0x50, 0x41, 0x43, 0x4b,
+	0x45, 0x54, 0x5f, 0x43, 0x53, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x43, 0x68, 0x61,
+	0x6e, 0x6e, 0x65, 0x6c, 0x10, 0xcb, 0x3e, 0x12, 0x1d, 0x0a, 0x18, 0x50, 0x41, 0x43, 0x4b, 0x45,
+	0x54, 0x5f, 0x53, 0x43, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x43, 0x68, 0x61, 0x6e,
+	0x6e, 0x65, 0x6c, 0x10, 0xcc, 0x3e, 0x42, 0x28, 0x5a, 0x26, 0x6d, 0x6f, 0x6e, 0x67, 0x6f, 0x2e,
+	0x67, 0x61, 0x6d, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x61, 0x6d, 0x65, 0x2f, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x61, 0x6d, 0x65, 0x68, 0x61, 0x6c, 0x6c,
+	0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -8200,7 +8302,7 @@ func file_game_proto_rawDescGZIP() []byte {
 }
 
 var file_game_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
-var file_game_proto_msgTypes = make([]protoimpl.MessageInfo, 102)
+var file_game_proto_msgTypes = make([]protoimpl.MessageInfo, 104)
 var file_game_proto_goTypes = []interface{}{
 	(OpResultCode_Game)(0),                // 0: gamehall.OpResultCode_Game
 	(GameHallPacketID)(0),                 // 1: gamehall.GameHallPacketID
@@ -8306,6 +8408,8 @@ var file_game_proto_goTypes = []interface{}{
 	(*SCNoticeChange)(nil),                // 101: gamehall.SCNoticeChange
 	(*CSRoomEvent)(nil),                   // 102: gamehall.CSRoomEvent
 	(*SCRoomEvent)(nil),                   // 103: gamehall.SCRoomEvent
+	(*CSExchangeChannel)(nil),             // 104: gamehall.CSExchangeChannel
+	(*SCExchangeChannel)(nil),             // 105: gamehall.SCExchangeChannel
 }
 var file_game_proto_depIdxs = []int32{
 	0,  // 0: gamehall.SCEnterHall.OpRetCode:type_name -> gamehall.OpResultCode_Game
@@ -9594,6 +9698,30 @@ func file_game_proto_init() {
 				return nil
 			}
 		}
+		file_game_proto_msgTypes[102].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CSExchangeChannel); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_game_proto_msgTypes[103].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SCExchangeChannel); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
 	}
 	type x struct{}
 	out := protoimpl.TypeBuilder{
@@ -9601,7 +9729,7 @@ func file_game_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_game_proto_rawDesc,
 			NumEnums:      2,
-			NumMessages:   102,
+			NumMessages:   104,
 			NumExtensions: 0,
 			NumServices:   0,
 		},
diff --git a/protocol/gamehall/game.proto b/protocol/gamehall/game.proto
index 12137c9..c6f81c3 100644
--- a/protocol/gamehall/game.proto
+++ b/protocol/gamehall/game.proto
@@ -159,6 +159,8 @@ enum GameHallPacketID {
   PACKET_CS_PLAYER_SWITCHFLAG = 8008;
   PACKET_CSRoomEvent = 8009; // æˆ¿é—´äº‹ä»¶
   PACKET_SCRoomEvent = 8010; // æˆ¿é—´äº‹ä»¶
+  PACKET_CSExchangeChannel = 8011; // å¼€å�¯å…‘æ�¢çš„æ¸ é�“
+  PACKET_SCExchangeChannel = 8012; // å¼€å�¯å…‘æ�¢çš„æ¸ é�“
 }
 //è¿›å…¥æ¸¸æˆ�å¤§åŽ…
 //PACKET_CS_ENTERHALL
@@ -860,4 +862,12 @@ message SCRoomEvent{
   string Content = 4; // å†…å®¹
   repeated int32 Param= 5; // å�‚æ•°
   int64 Ts = 6; // æ—¶é—´æˆ³
+}
+
+// PACKET_CSExchangeChannel
+message CSExchangeChannel{}
+
+// PACKET_SCExchangeChannel
+message SCExchangeChannel{
+  repeated string OnChannelName = 1;  // å¼€å�¯æ¸ é�“
 }
\ No newline at end of file
diff --git a/protocol/webapi/common.pb.go b/protocol/webapi/common.pb.go
index 085d71f..1edfdf3 100644
--- a/protocol/webapi/common.pb.go
+++ b/protocol/webapi/common.pb.go
@@ -5701,6 +5701,62 @@ func (x *WelfareCollectConfig) GetSwitch() int32 {
 	return 0
 }
 
+// etcd /game/exchange/channel
+type ExchangeChannelConfig struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Platform      string   `protobuf:"bytes,1,opt,name=Platform,proto3" json:"Platform,omitempty"`
+	OnChannelName []string `protobuf:"bytes,2,rep,name=OnChannelName,proto3" json:"OnChannelName,omitempty"` // å¼€å�¯æ¸ é�“
+}
+
+func (x *ExchangeChannelConfig) Reset() {
+	*x = ExchangeChannelConfig{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_common_proto_msgTypes[55]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ExchangeChannelConfig) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ExchangeChannelConfig) ProtoMessage() {}
+
+func (x *ExchangeChannelConfig) ProtoReflect() protoreflect.Message {
+	mi := &file_common_proto_msgTypes[55]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ExchangeChannelConfig.ProtoReflect.Descriptor instead.
+func (*ExchangeChannelConfig) Descriptor() ([]byte, []int) {
+	return file_common_proto_rawDescGZIP(), []int{55}
+}
+
+func (x *ExchangeChannelConfig) GetPlatform() string {
+	if x != nil {
+		return x.Platform
+	}
+	return ""
+}
+
+func (x *ExchangeChannelConfig) GetOnChannelName() []string {
+	if x != nil {
+		return x.OnChannelName
+	}
+	return nil
+}
+
 var File_common_proto protoreflect.FileDescriptor
 
 var file_common_proto_rawDesc = []byte{
@@ -6628,10 +6684,16 @@ var file_common_proto_rawDesc = []byte{
 	0x63, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x6c, 0x61, 0x74,
 	0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x6c, 0x61, 0x74,
 	0x66, 0x6f, 0x72, 0x6d, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x18, 0x02,
-	0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x42, 0x26, 0x5a, 0x24,
-	0x6d, 0x6f, 0x6e, 0x67, 0x6f, 0x2e, 0x67, 0x61, 0x6d, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
-	0x67, 0x61, 0x6d, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x77, 0x65,
-	0x62, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x53, 0x77, 0x69, 0x74, 0x63, 0x68, 0x22, 0x59, 0x0a, 0x15,
+	0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x43,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72,
+	0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72,
+	0x6d, 0x12, 0x24, 0x0a, 0x0d, 0x4f, 0x6e, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x4e, 0x61,
+	0x6d, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x4f, 0x6e, 0x43, 0x68, 0x61, 0x6e,
+	0x6e, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x42, 0x26, 0x5a, 0x24, 0x6d, 0x6f, 0x6e, 0x67, 0x6f,
+	0x2e, 0x67, 0x61, 0x6d, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x61, 0x6d, 0x65, 0x2f,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x77, 0x65, 0x62, 0x61, 0x70, 0x69, 0x62,
+	0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -6646,7 +6708,7 @@ func file_common_proto_rawDescGZIP() []byte {
 	return file_common_proto_rawDescData
 }
 
-var file_common_proto_msgTypes = make([]protoimpl.MessageInfo, 60)
+var file_common_proto_msgTypes = make([]protoimpl.MessageInfo, 61)
 var file_common_proto_goTypes = []interface{}{
 	(*MysqlDbSetting)(nil),               // 0: webapi.MysqlDbSetting
 	(*MongoDbSetting)(nil),               // 1: webapi.MongoDbSetting
@@ -6703,31 +6765,32 @@ var file_common_proto_goTypes = []interface{}{
 	(*GameConfig)(nil),                   // 52: webapi.GameConfig
 	(*WelfarePhoneLotteryStatus)(nil),    // 53: webapi.WelfarePhoneLotteryStatus
 	(*WelfareCollectConfig)(nil),         // 54: webapi.WelfareCollectConfig
-	nil,                                  // 55: webapi.Platform.BindTelRewardEntry
-	nil,                                  // 56: webapi.PlayerData.RankScoreEntry
-	nil,                                  // 57: webapi.ItemShop.AwardEntry
-	nil,                                  // 58: webapi.VIPcfg.AwardEntry
-	nil,                                  // 59: webapi.VIPcfg.Privilege7Entry
-	(*server.DB_GameFree)(nil),           // 60: server.DB_GameFree
+	(*ExchangeChannelConfig)(nil),        // 55: webapi.ExchangeChannelConfig
+	nil,                                  // 56: webapi.Platform.BindTelRewardEntry
+	nil,                                  // 57: webapi.PlayerData.RankScoreEntry
+	nil,                                  // 58: webapi.ItemShop.AwardEntry
+	nil,                                  // 59: webapi.VIPcfg.AwardEntry
+	nil,                                  // 60: webapi.VIPcfg.Privilege7Entry
+	(*server.DB_GameFree)(nil),           // 61: server.DB_GameFree
 }
 var file_common_proto_depIdxs = []int32{
 	2,  // 0: webapi.Platform.Leaderboard:type_name -> webapi.RankSwitch
 	3,  // 1: webapi.Platform.ClubConfig:type_name -> webapi.ClubConfig
 	4,  // 2: webapi.Platform.ThirdGameMerchant:type_name -> webapi.ThirdGame
-	55, // 3: webapi.Platform.BindTelReward:type_name -> webapi.Platform.BindTelRewardEntry
+	56, // 3: webapi.Platform.BindTelReward:type_name -> webapi.Platform.BindTelRewardEntry
 	6,  // 4: webapi.GameConfigGlobal.GameStatus:type_name -> webapi.GameStatus
-	60, // 5: webapi.GameFree.DbGameFree:type_name -> server.DB_GameFree
+	61, // 5: webapi.GameFree.DbGameFree:type_name -> server.DB_GameFree
 	8,  // 6: webapi.PlatformGameConfig.DbGameFrees:type_name -> webapi.GameFree
 	0,  // 7: webapi.PlatformDbConfig.Mysql:type_name -> webapi.MysqlDbSetting
 	1,  // 8: webapi.PlatformDbConfig.MongoDb:type_name -> webapi.MongoDbSetting
 	1,  // 9: webapi.PlatformDbConfig.MongoDbLog:type_name -> webapi.MongoDbSetting
-	60, // 10: webapi.GameConfigGroup.DbGameFree:type_name -> server.DB_GameFree
-	56, // 11: webapi.PlayerData.RankScore:type_name -> webapi.PlayerData.RankScoreEntry
+	61, // 10: webapi.GameConfigGroup.DbGameFree:type_name -> server.DB_GameFree
+	57, // 11: webapi.PlayerData.RankScore:type_name -> webapi.PlayerData.RankScoreEntry
 	20, // 12: webapi.OnlineReport.GameCount:type_name -> webapi.OnlineGameCnt
 	22, // 13: webapi.CommonNoticeList.List:type_name -> webapi.CommonNotice
 	25, // 14: webapi.ExchangeShop.ExType:type_name -> webapi.ExchangeType
 	24, // 15: webapi.ExchangeShopList.List:type_name -> webapi.ExchangeShop
-	57, // 16: webapi.ItemShop.Award:type_name -> webapi.ItemShop.AwardEntry
+	58, // 16: webapi.ItemShop.Award:type_name -> webapi.ItemShop.AwardEntry
 	27, // 17: webapi.ItemShopList.List:type_name -> webapi.ItemShop
 	29, // 18: webapi.MatchInfoAward.ItemId:type_name -> webapi.ItemInfo
 	30, // 19: webapi.GameMatchDate.Award:type_name -> webapi.MatchInfoAward
@@ -6744,8 +6807,8 @@ var file_common_proto_depIdxs = []int32{
 	33, // 30: webapi.WelfareSpree.Item:type_name -> webapi.WelfareDate
 	42, // 31: webapi.WelfareFirstPayDataList.List:type_name -> webapi.WelfareSpree
 	42, // 32: webapi.WelfareContinuousPayDataList.List:type_name -> webapi.WelfareSpree
-	58, // 33: webapi.VIPcfg.Award:type_name -> webapi.VIPcfg.AwardEntry
-	59, // 34: webapi.VIPcfg.Privilege7:type_name -> webapi.VIPcfg.Privilege7Entry
+	59, // 33: webapi.VIPcfg.Award:type_name -> webapi.VIPcfg.AwardEntry
+	60, // 34: webapi.VIPcfg.Privilege7:type_name -> webapi.VIPcfg.Privilege7Entry
 	45, // 35: webapi.VIPcfgDataList.List:type_name -> webapi.VIPcfg
 	33, // 36: webapi.ChessRankConfig.Item:type_name -> webapi.WelfareDate
 	49, // 37: webapi.ChessRankcfgData.Datas:type_name -> webapi.ChessRankConfig
@@ -7422,6 +7485,18 @@ func file_common_proto_init() {
 				return nil
 			}
 		}
+		file_common_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ExchangeChannelConfig); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
 	}
 	type x struct{}
 	out := protoimpl.TypeBuilder{
@@ -7429,7 +7504,7 @@ func file_common_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_common_proto_rawDesc,
 			NumEnums:      0,
-			NumMessages:   60,
+			NumMessages:   61,
 			NumExtensions: 0,
 			NumServices:   0,
 		},
diff --git a/protocol/webapi/common.proto b/protocol/webapi/common.proto
index d35d787..236347c 100644
--- a/protocol/webapi/common.proto
+++ b/protocol/webapi/common.proto
@@ -631,4 +631,10 @@ message WelfarePhoneLotteryStatus{
 message WelfareCollectConfig{
   string Platform = 1;
   int32 Switch = 2;  // 1.å¼€å�¯ 2.å…³é—­
+}
+
+// etcd /game/exchange/channel
+message ExchangeChannelConfig{
+  string Platform = 1;
+  repeated string OnChannelName = 2;  // å¼€å�¯æ¸ é�“
 }
\ No newline at end of file
diff --git a/worldsrv/action_game.go b/worldsrv/action_game.go
index 7ac3e77..4c9d6ba 100644
--- a/worldsrv/action_game.go
+++ b/worldsrv/action_game.go
@@ -2226,6 +2226,31 @@ func (this *CSRecordAndNoticeHandler) Process(s *netlib.Session, packetid int, d
 	return nil
 }
 
+func CSExchangeChannel(s *netlib.Session, packetid int, data interface{}, sid int64) error {
+	logger.Logger.Trace("CSExchangeChannel Process recv ", data)
+	_, ok := data.(*gamehall.CSExchangeChannel)
+	if !ok {
+		return nil
+	}
+
+	p := PlayerMgrSington.GetPlayer(sid)
+	if p == nil {
+		logger.Logger.Warn("CSExchangeChannel p == nil")
+		return nil
+	}
+
+	var onChannelName []string
+	conf := PlatformMgrSingleton.GetConfig(p.Platform).ExchangeChannelConfig
+	if conf != nil {
+		onChannelName = conf.OnChannelName
+	}
+
+	p.SendToClient(int(gamehall.GameHallPacketID_PACKET_SCExchangeChannel), &gamehall.SCExchangeChannel{
+		OnChannelName: onChannelName,
+	})
+	return nil
+}
+
 func init() {
 	// è§‚ä¼—è¿›å…¥æˆ¿é—´
 	common.RegisterHandler(int(gamehall.GameHallPacketID_PACKET_CS_AUDIENCE_ENTERROOM), &CSAudienceEnterRoomHandler{})
@@ -2278,4 +2303,6 @@ func init() {
 	//æˆ‘çš„æ¸¸æˆ�ä¿¡æ�¯å�Šå¹³å�°å…¬å‘Š
 	common.RegisterHandler(int(gamehall.GameHallPacketID_PACKET_CS_COMNOTICE), &CSRecordAndNoticeHandler{})
 	netlib.RegisterFactory(int(gamehall.GameHallPacketID_PACKET_CS_COMNOTICE), &CSRecordAndNoticePacketFactory{})
+	// å¼€å�¯å…‘æ�¢çš„æ¸ é�“
+	common.Register(int(gamehall.GameHallPacketID_PACKET_CSExchangeChannel), gamehall.CSExchangeChannel{}, CSExchangeChannel)
 }
diff --git a/worldsrv/etcd.go b/worldsrv/etcd.go
index 5c8c0ea..208dab2 100644
--- a/worldsrv/etcd.go
+++ b/worldsrv/etcd.go
@@ -35,6 +35,8 @@ func init() {
 	etcd.Register(etcd.ETCDKEY_SHOP_ITEM, webapi.ItemShopList{}, platformConfigEvent)
 	// é›†å�¡æ´»åŠ¨
 	etcd.Register(etcd.ETCDKEY_ACT_Collect, webapi.WelfareCollectConfig{}, platformConfigEvent)
+	// å�¯åŠ¨å…‘æ�¢åŠŸèƒ½çš„æ¸ é�“
+	etcd.Register(etcd.ETCDKEY_EXCHANGECHANNEL, webapi.ExchangeChannelConfig{}, platformConfigEvent)
 }
 
 func platformConfigEvent(ctx context.Context, completeKey string, isInit bool, event *clientv3.Event, data interface{}) {
@@ -125,6 +127,16 @@ func platformConfigEvent(ctx context.Context, completeKey string, isInit bool, e
 		} else {
 			TournamentMgr.UpdateData(false, config)
 		}
+	case *webapi.ExchangeChannelConfig:
+		PlatformMgrSingleton.GetConfig(config.Platform).ExchangeChannelConfig = config
+		if !isInit {
+			// é€šçŸ¥å�˜æ›´
+			for _, v := range PlayerMgrSington.playerOfPlatform[config.Platform] {
+				if v != nil && v.IsOnLine() {
+					v.SendToClient(int(hallproto.GameHallPacketID_PACKET_SCExchangeChannel), &hallproto.SCExchangeChannel{})
+				}
+			}
+		}
 
 	default:
 		logger.Logger.Errorf("etcd completeKey:%s, Not processed", completeKey)
diff --git a/xlsx/DB_Game_Drop.xlsx b/xlsx/DB_Game_Drop.xlsx
index d6dfa2a..55883fa 100644
Binary files a/xlsx/DB_Game_Drop.xlsx and b/xlsx/DB_Game_Drop.xlsx differ
