Browse Source

Merge branch '3.0.0'

makeyangcom 8 months ago
parent
commit
b543c0d8d8

BIN
game/assets/launch/message_background.png


+ 34 - 0
game/assets/launch/message_background.png.import

@@ -0,0 +1,34 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://llh2in832a08"
+path="res://.godot/imported/message_background.png-921fc0d794af457637631219ca27a628.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://assets/launch/message_background.png"
+dest_files=["res://.godot/imported/message_background.png-921fc0d794af457637631219ca27a628.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1

+ 361 - 44
game/scenes/launch/launch.tscn

@@ -1,5 +1,6 @@
-[gd_scene load_steps=21 format=3 uid="uid://i6g3y6btijjm"]
+[gd_scene load_steps=25 format=3 uid="uid://i6g3y6btijjm"]
 
+[ext_resource type="Script" path="res://scripts/launch/launch.gd" id="1_4mmer"]
 [ext_resource type="Texture2D" uid="uid://d05rp7emahb2e" path="res://assets/launch/background.jpeg" id="1_5xji2"]
 [ext_resource type="Texture2D" uid="uid://cuej03yg4jipe" path="res://assets/launch/logo.png" id="2_0aob3"]
 [ext_resource type="Texture2D" uid="uid://fsim526ipc0l" path="res://assets/launch/login/login_main.png" id="3_5llxh"]
@@ -13,6 +14,7 @@
 [ext_resource type="Texture2D" uid="uid://c2yxw4e4eqhtf" path="res://assets/launch/login/change_password_button_1.png" id="11_qrjou"]
 [ext_resource type="Texture2D" uid="uid://bc32c8pqrsy0b" path="res://assets/launch/login/change_password_button_2.png" id="12_2fiqv"]
 [ext_resource type="Texture2D" uid="uid://7ckxiv7awadm" path="res://assets/launch/login/register.png" id="13_ruxkj"]
+[ext_resource type="FontFile" uid="uid://b8ippc7k3ew6o" path="res://assets/common/font/msyh.ttc" id="13_scx2i"]
 [ext_resource type="Texture2D" uid="uid://bijbk6c76ynei" path="res://assets/launch/login/change_password.png" id="14_d8t0o"]
 [ext_resource type="Texture2D" uid="uid://dmkyb57b0idt6" path="res://assets/launch/login/confirm_button_0.png" id="14_f5mlh"]
 [ext_resource type="Texture2D" uid="uid://b2fk8xp87k1g" path="res://assets/launch/login/confirm_button_1.png" id="15_783oq"]
@@ -21,6 +23,10 @@
 [ext_resource type="Texture2D" uid="uid://06rsvnelh6ug" path="res://assets/launch/login/cancel_button_1.png" id="18_odk15"]
 [ext_resource type="Texture2D" uid="uid://cbdi6fpcw3q66" path="res://assets/launch/login/cancel_button_2.png" id="19_m2fqs"]
 
+[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_m6v8k"]
+
+[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_twyo5"]
+
 [node name="Launch" type="Control"]
 layout_mode = 3
 anchors_preset = 15
@@ -28,6 +34,7 @@ anchor_right = 1.0
 anchor_bottom = 1.0
 grow_horizontal = 2
 grow_vertical = 2
+script = ExtResource("1_4mmer")
 
 [node name="Background" type="TextureRect" parent="."]
 layout_mode = 1
@@ -48,9 +55,9 @@ anchor_top = 0.5
 anchor_right = 0.5
 anchor_bottom = 0.5
 offset_left = -200.5
-offset_top = -266.5
+offset_top = -264.5
 offset_right = 200.5
-offset_bottom = 170.5
+offset_bottom = 172.5
 grow_horizontal = 2
 grow_vertical = 2
 texture = ExtResource("2_0aob3")
@@ -79,14 +86,14 @@ anchor_top = 0.5
 anchor_right = 0.5
 anchor_bottom = 0.5
 offset_left = -281.0
-offset_top = 60.5
+offset_top = 64.5
 offset_right = 281.0
-offset_bottom = 315.5
+offset_bottom = 319.5
 grow_horizontal = 2
 grow_vertical = 2
 texture = ExtResource("3_5llxh")
 
-[node name="LoginButton" type="TextureButton" parent="Login/Main/Background"]
+[node name="MainSubmitButton" type="TextureButton" parent="Login/Main/Background"]
 layout_mode = 1
 anchors_preset = 8
 anchor_left = 0.5
@@ -94,42 +101,42 @@ anchor_top = 0.5
 anchor_right = 0.5
 anchor_bottom = 0.5
 offset_left = -93.0
-offset_top = 16.0
+offset_top = 13.0
 offset_right = 109.0
-offset_bottom = 62.0
+offset_bottom = 59.0
 grow_horizontal = 2
 grow_vertical = 2
 texture_normal = ExtResource("4_h5ojd")
 texture_pressed = ExtResource("5_jt32w")
 texture_hover = ExtResource("6_0lxvy")
 
-[node name="RegisterButton" type="TextureButton" parent="Login/Main/Background"]
+[node name="MainRegisterButton" type="TextureButton" parent="Login/Main/Background"]
 layout_mode = 1
 anchors_preset = 8
 anchor_left = 0.5
 anchor_top = 0.5
 anchor_right = 0.5
 anchor_bottom = 0.5
-offset_left = -151.0
-offset_top = 80.0
-offset_right = -29.0
-offset_bottom = 103.0
+offset_left = -170.0
+offset_top = 81.0
+offset_right = -48.0
+offset_bottom = 104.0
 grow_horizontal = 2
 grow_vertical = 2
 texture_normal = ExtResource("7_tqnk7")
 texture_pressed = ExtResource("8_gwvfn")
 texture_hover = ExtResource("9_4hsjm")
 
-[node name="RetrievePasswordButton" type="TextureButton" parent="Login/Main/Background"]
+[node name="MainChangePasswordButton" type="TextureButton" parent="Login/Main/Background"]
 layout_mode = 1
 anchors_preset = 8
 anchor_left = 0.5
 anchor_top = 0.5
 anchor_right = 0.5
 anchor_bottom = 0.5
-offset_left = 27.0
+offset_left = 45.0
 offset_top = 79.0
-offset_right = 149.0
+offset_right = 167.0
 offset_bottom = 104.0
 grow_horizontal = 2
 grow_vertical = 2
@@ -137,6 +144,46 @@ texture_normal = ExtResource("10_pmgwe")
 texture_pressed = ExtResource("11_qrjou")
 texture_hover = ExtResource("12_2fiqv")
 
+[node name="MainAccountInput" type="LineEdit" parent="Login/Main/Background"]
+layout_mode = 1
+anchors_preset = 8
+anchor_left = 0.5
+anchor_top = 0.5
+anchor_right = 0.5
+anchor_bottom = 0.5
+offset_left = -84.0
+offset_top = -79.5
+offset_right = 102.0
+offset_bottom = -52.5
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_fonts/font = ExtResource("13_scx2i")
+theme_override_font_sizes/font_size = 12
+theme_override_styles/focus = SubResource("StyleBoxEmpty_m6v8k")
+placeholder_text = "请输入登录邮箱"
+flat = true
+
+[node name="MainPasswordInput" type="LineEdit" parent="Login/Main/Background"]
+layout_mode = 1
+anchors_preset = 8
+anchor_left = 0.5
+anchor_top = 0.5
+anchor_right = 0.5
+anchor_bottom = 0.5
+offset_left = -83.0
+offset_top = -30.5
+offset_right = 103.0
+offset_bottom = -3.5
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_fonts/font = ExtResource("13_scx2i")
+theme_override_font_sizes/font_size = 12
+theme_override_styles/focus = SubResource("StyleBoxEmpty_twyo5")
+placeholder_text = "请输入登录密码"
+flat = true
+secret = true
+secret_character = "*"
+
 [node name="Register" type="Control" parent="Login"]
 layout_mode = 1
 anchors_preset = 15
@@ -160,41 +207,213 @@ grow_horizontal = 2
 grow_vertical = 2
 texture = ExtResource("13_ruxkj")
 
-[node name="ConfirmButton" type="TextureButton" parent="Login/Register/Background"]
+[node name="RegisterConfirmButton" type="TextureButton" parent="Login/Register/Background"]
+layout_mode = 1
+anchors_preset = 7
+anchor_left = 0.5
+anchor_top = 1.0
+anchor_right = 0.5
+anchor_bottom = 1.0
+offset_left = 20.0
+offset_top = -52.0
+offset_right = 104.0
+offset_bottom = -23.0
+grow_horizontal = 2
+grow_vertical = 0
+texture_normal = ExtResource("14_f5mlh")
+texture_pressed = ExtResource("15_783oq")
+texture_hover = ExtResource("16_tgcix")
+
+[node name="RegisterCancelButton" type="TextureButton" parent="Login/Register/Background"]
+layout_mode = 1
+anchors_preset = 7
+anchor_left = 0.5
+anchor_top = 1.0
+anchor_right = 0.5
+anchor_bottom = 1.0
+offset_left = 121.0
+offset_top = -52.0
+offset_right = 205.0
+offset_bottom = -23.0
+grow_horizontal = 2
+grow_vertical = 0
+texture_normal = ExtResource("17_1wujc")
+texture_pressed = ExtResource("18_odk15")
+texture_hover = ExtResource("19_m2fqs")
+
+[node name="RegisterAccountInput" type="LineEdit" parent="Login/Register/Background"]
 layout_mode = 1
 anchors_preset = 8
 anchor_left = 0.5
 anchor_top = 0.5
 anchor_right = 0.5
 anchor_bottom = 0.5
-offset_left = 23.0
-offset_top = 138.5
-offset_right = 107.0
-offset_bottom = 167.5
+offset_left = -170.5
+offset_top = -131.5
+offset_right = 10.5
+offset_bottom = -106.5
 grow_horizontal = 2
 grow_vertical = 2
-texture_normal = ExtResource("14_f5mlh")
-texture_pressed = ExtResource("15_783oq")
-texture_hover = ExtResource("16_tgcix")
+theme_override_fonts/font = ExtResource("13_scx2i")
+theme_override_font_sizes/font_size = 12
+theme_override_styles/focus = SubResource("StyleBoxEmpty_m6v8k")
+placeholder_text = "请输入登录邮箱"
+flat = true
 
-[node name="CancelButton" type="TextureButton" parent="Login/Register/Background"]
+[node name="RegisterPasswordInput" type="LineEdit" parent="Login/Register/Background"]
 layout_mode = 1
 anchors_preset = 8
 anchor_left = 0.5
 anchor_top = 0.5
 anchor_right = 0.5
 anchor_bottom = 0.5
-offset_left = 117.0
-offset_top = 138.5
-offset_right = 201.0
-offset_bottom = 167.5
+offset_left = -170.5
+offset_top = -101.5
+offset_right = 10.5
+offset_bottom = -76.5
 grow_horizontal = 2
 grow_vertical = 2
-texture_normal = ExtResource("17_1wujc")
-texture_pressed = ExtResource("18_odk15")
-texture_hover = ExtResource("19_m2fqs")
+theme_override_fonts/font = ExtResource("13_scx2i")
+theme_override_font_sizes/font_size = 12
+theme_override_styles/focus = SubResource("StyleBoxEmpty_m6v8k")
+placeholder_text = "请输入登录密码"
+flat = true
+
+[node name="RegisterConfirmPasswordInput" type="LineEdit" parent="Login/Register/Background"]
+layout_mode = 1
+anchors_preset = 8
+anchor_left = 0.5
+anchor_top = 0.5
+anchor_right = 0.5
+anchor_bottom = 0.5
+offset_left = -170.5
+offset_top = -71.5
+offset_right = 10.5
+offset_bottom = -46.5
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_fonts/font = ExtResource("13_scx2i")
+theme_override_font_sizes/font_size = 12
+theme_override_styles/focus = SubResource("StyleBoxEmpty_m6v8k")
+placeholder_text = "请输入登录密码"
+flat = true
 
-[node name="RetrievePassword" type="Control" parent="Login"]
+[node name="RegisterNameInput" type="LineEdit" parent="Login/Register/Background"]
+layout_mode = 1
+anchors_preset = 8
+anchor_left = 0.5
+anchor_top = 0.5
+anchor_right = 0.5
+anchor_bottom = 0.5
+offset_left = -171.5
+offset_top = -28.5
+offset_right = 9.5
+offset_bottom = -3.5
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_fonts/font = ExtResource("13_scx2i")
+theme_override_font_sizes/font_size = 12
+theme_override_styles/focus = SubResource("StyleBoxEmpty_m6v8k")
+placeholder_text = "请输入真实姓名"
+flat = true
+
+[node name="RegisterNumberInput" type="LineEdit" parent="Login/Register/Background"]
+layout_mode = 1
+anchors_preset = 8
+anchor_left = 0.5
+anchor_top = 0.5
+anchor_right = 0.5
+anchor_bottom = 0.5
+offset_left = -171.5
+offset_top = 1.5
+offset_right = 9.5
+offset_bottom = 26.5
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_fonts/font = ExtResource("13_scx2i")
+theme_override_font_sizes/font_size = 12
+theme_override_styles/focus = SubResource("StyleBoxEmpty_m6v8k")
+placeholder_text = "请输入身份证号码"
+flat = true
+
+[node name="RegisterQuestionAInput" type="LineEdit" parent="Login/Register/Background"]
+layout_mode = 1
+anchors_preset = 8
+anchor_left = 0.5
+anchor_top = 0.5
+anchor_right = 0.5
+anchor_bottom = 0.5
+offset_left = -171.5
+offset_top = 53.5
+offset_right = 9.5
+offset_bottom = 78.5
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_fonts/font = ExtResource("13_scx2i")
+theme_override_font_sizes/font_size = 12
+theme_override_styles/focus = SubResource("StyleBoxEmpty_m6v8k")
+placeholder_text = "请设置密保问题"
+flat = true
+
+[node name="RegisterAnswerAInput" type="LineEdit" parent="Login/Register/Background"]
+layout_mode = 1
+anchors_preset = 8
+anchor_left = 0.5
+anchor_top = 0.5
+anchor_right = 0.5
+anchor_bottom = 0.5
+offset_left = -171.5
+offset_top = 83.5
+offset_right = 9.5
+offset_bottom = 108.5
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_fonts/font = ExtResource("13_scx2i")
+theme_override_font_sizes/font_size = 12
+theme_override_styles/focus = SubResource("StyleBoxEmpty_m6v8k")
+placeholder_text = "请设置密保问题答案"
+flat = true
+
+[node name="RegisterQuestionBInput" type="LineEdit" parent="Login/Register/Background"]
+layout_mode = 1
+anchors_preset = 8
+anchor_left = 0.5
+anchor_top = 0.5
+anchor_right = 0.5
+anchor_bottom = 0.5
+offset_left = -171.5
+offset_top = 113.5
+offset_right = 9.5
+offset_bottom = 138.5
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_fonts/font = ExtResource("13_scx2i")
+theme_override_font_sizes/font_size = 12
+theme_override_styles/focus = SubResource("StyleBoxEmpty_m6v8k")
+placeholder_text = "请设置密保问题"
+flat = true
+
+[node name="RegisterAnswerBInput" type="LineEdit" parent="Login/Register/Background"]
+layout_mode = 1
+anchors_preset = 8
+anchor_left = 0.5
+anchor_top = 0.5
+anchor_right = 0.5
+anchor_bottom = 0.5
+offset_left = -171.5
+offset_top = 143.5
+offset_right = 9.5
+offset_bottom = 168.5
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_fonts/font = ExtResource("13_scx2i")
+theme_override_font_sizes/font_size = 12
+theme_override_styles/focus = SubResource("StyleBoxEmpty_m6v8k")
+placeholder_text = "请设置密保问题答案"
+flat = true
+
+[node name="ChangePassword" type="Control" parent="Login"]
+visible = false
 layout_mode = 1
 anchors_preset = 15
 anchor_right = 1.0
@@ -202,7 +421,7 @@ anchor_bottom = 1.0
 grow_horizontal = 2
 grow_vertical = 2
 
-[node name="Background" type="TextureRect" parent="Login/RetrievePassword"]
+[node name="Background" type="TextureRect" parent="Login/ChangePassword"]
 layout_mode = 1
 anchors_preset = 8
 anchor_left = 0.5
@@ -217,24 +436,116 @@ grow_horizontal = 2
 grow_vertical = 2
 texture = ExtResource("14_d8t0o")
 
-[node name="ConfirmButton" type="TextureButton" parent="Login/RetrievePassword/Background"]
-offset_left = 136.5
-offset_top = 186.5
-offset_right = 220.5
-offset_bottom = 215.5
+[node name="ChangePasswordConfirmButton" type="TextureButton" parent="Login/ChangePassword/Background"]
+layout_mode = 1
+anchors_preset = 7
+anchor_left = 0.5
+anchor_top = 1.0
+anchor_right = 0.5
+anchor_bottom = 1.0
+offset_left = -47.0
+offset_top = -62.0
+offset_right = 37.0
+offset_bottom = -33.0
+grow_horizontal = 2
+grow_vertical = 0
 texture_normal = ExtResource("14_f5mlh")
 texture_pressed = ExtResource("15_783oq")
 texture_hover = ExtResource("16_tgcix")
 
-[node name="CancelButton" type="TextureButton" parent="Login/RetrievePassword/Background"]
-offset_left = 238.5
-offset_top = 186.5
-offset_right = 322.5
-offset_bottom = 215.5
+[node name="ChangePasswordCancelButton" type="TextureButton" parent="Login/ChangePassword/Background"]
+layout_mode = 1
+anchors_preset = 7
+anchor_left = 0.5
+anchor_top = 1.0
+anchor_right = 0.5
+anchor_bottom = 1.0
+offset_left = 54.0
+offset_top = -62.0
+offset_right = 138.0
+offset_bottom = -33.0
+grow_horizontal = 2
+grow_vertical = 0
 texture_normal = ExtResource("17_1wujc")
 texture_pressed = ExtResource("18_odk15")
 texture_hover = ExtResource("19_m2fqs")
 
+[node name="ChangePasswordAccountInput" type="LineEdit" parent="Login/ChangePassword/Background"]
+layout_mode = 1
+anchors_preset = 8
+anchor_left = 0.5
+anchor_top = 0.5
+anchor_right = 0.5
+anchor_bottom = 0.5
+offset_left = -45.5
+offset_top = -64.5
+offset_right = 135.5
+offset_bottom = -39.5
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_fonts/font = ExtResource("13_scx2i")
+theme_override_font_sizes/font_size = 12
+theme_override_styles/focus = SubResource("StyleBoxEmpty_m6v8k")
+placeholder_text = "请输入账户邮箱"
+flat = true
+
+[node name="ChangePasswordOldInput" type="LineEdit" parent="Login/ChangePassword/Background"]
+layout_mode = 1
+anchors_preset = 8
+anchor_left = 0.5
+anchor_top = 0.5
+anchor_right = 0.5
+anchor_bottom = 0.5
+offset_left = -45.5
+offset_top = -34.5
+offset_right = 135.5
+offset_bottom = -9.5
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_fonts/font = ExtResource("13_scx2i")
+theme_override_font_sizes/font_size = 12
+theme_override_styles/focus = SubResource("StyleBoxEmpty_m6v8k")
+placeholder_text = "请输入原始密码"
+flat = true
+
+[node name="ChangePasswordNewInput" type="LineEdit" parent="Login/ChangePassword/Background"]
+layout_mode = 1
+anchors_preset = 8
+anchor_left = 0.5
+anchor_top = 0.5
+anchor_right = 0.5
+anchor_bottom = 0.5
+offset_left = -45.5
+offset_top = -4.5
+offset_right = 135.5
+offset_bottom = 20.5
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_fonts/font = ExtResource("13_scx2i")
+theme_override_font_sizes/font_size = 12
+theme_override_styles/focus = SubResource("StyleBoxEmpty_m6v8k")
+placeholder_text = "请输入新的密码"
+flat = true
+
+[node name="ChangePasswordConfirmInput" type="LineEdit" parent="Login/ChangePassword/Background"]
+layout_mode = 1
+anchors_preset = 8
+anchor_left = 0.5
+anchor_top = 0.5
+anchor_right = 0.5
+anchor_bottom = 0.5
+offset_left = -45.5
+offset_top = 25.5
+offset_right = 135.5
+offset_bottom = 50.5
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_fonts/font = ExtResource("13_scx2i")
+theme_override_font_sizes/font_size = 12
+theme_override_styles/focus = SubResource("StyleBoxEmpty_m6v8k")
+placeholder_text = "请再次输入新的密码"
+flat = true
+
 [node name="Server" type="Control" parent="."]
 anchors_preset = 0
 offset_right = 40.0
@@ -244,3 +555,9 @@ offset_bottom = 40.0
 anchors_preset = 0
 offset_right = 40.0
 offset_bottom = 40.0
+
+[connection signal="pressed" from="Login/Main/Background/MainRegisterButton" to="." method="_on_main_register_button_pressed"]
+[connection signal="pressed" from="Login/Main/Background/MainChangePasswordButton" to="." method="_on_main_change_password_button_pressed"]
+[connection signal="pressed" from="Login/Register/Background/RegisterConfirmButton" to="." method="_on_register_confirm_button_pressed"]
+[connection signal="pressed" from="Login/Register/Background/RegisterCancelButton" to="." method="_on_register_cancel_button_pressed"]
+[connection signal="pressed" from="Login/ChangePassword/Background/ChangePasswordCancelButton" to="." method="_on_change_password_cancel_button_pressed"]

+ 5 - 0
game/scripts/base/global.gd

@@ -60,3 +60,8 @@ func get_server_address() -> String:
 # 获取用户Token
 func get_account_token() -> String:
 	return data["account"]["token"]
+	
+# 更新并返回用户Token
+func update_account_token(token: String) -> String:
+	data["account"]["token"] = token
+	return data["account"]["token"]

+ 119 - 0
game/scripts/launch/launch.gd

@@ -0,0 +1,119 @@
+#*****************************************************************************
+# @file    launch.gd
+# @author  MakerYang(https://www.makeryang.com)
+# @statement 免费课程配套开源项目,任何形式收费均为盗版
+#*****************************************************************************
+extends Control
+
+@onready var login: Control = $Login
+@onready var main: Control = $Login/Main
+@onready var main_submit_button: TextureButton = $Login/Main/Background/MainSubmitButton
+@onready var main_register_button: TextureButton = $Login/Main/Background/MainRegisterButton
+@onready var main_change_password_button: TextureButton = $Login/Main/Background/MainChangePasswordButton
+@onready var main_account_input: LineEdit = $Login/Main/Background/MainAccountInput
+@onready var main_password_input: LineEdit = $Login/Main/Background/MainPasswordInput
+
+@onready var register: Control = $Login/Register
+@onready var register_confirm_button: TextureButton = $Login/Register/Background/RegisterConfirmButton
+@onready var register_cancel_button: TextureButton = $Login/Register/Background/RegisterCancelButton
+@onready var register_account_input: LineEdit = $Login/Register/Background/RegisterAccountInput
+@onready var register_password_input: LineEdit = $Login/Register/Background/RegisterPasswordInput
+@onready var register_confirm_password_input: LineEdit = $Login/Register/Background/RegisterConfirmPasswordInput
+@onready var register_name_input: LineEdit = $Login/Register/Background/RegisterNameInput
+@onready var register_number_input: LineEdit = $Login/Register/Background/RegisterNumberInput
+@onready var register_question_a_input: LineEdit = $Login/Register/Background/RegisterQuestionAInput
+@onready var register_answer_a_input: LineEdit = $Login/Register/Background/RegisterAnswerAInput
+@onready var register_question_b_input: LineEdit = $Login/Register/Background/RegisterQuestionBInput
+@onready var register_answer_b_input: LineEdit = $Login/Register/Background/RegisterAnswerBInput
+
+@onready var change_password: Control = $Login/ChangePassword
+@onready var change_password_confirm_button: TextureButton = $Login/ChangePassword/Background/ChangePasswordConfirmButton
+@onready var change_password_cancel_button: TextureButton = $Login/ChangePassword/Background/ChangePasswordCancelButton
+@onready var change_password_account_input: LineEdit = $Login/ChangePassword/Background/ChangePasswordAccountInput
+@onready var change_password_old_input: LineEdit = $Login/ChangePassword/Background/ChangePasswordOldInput
+@onready var change_password_new_input: LineEdit = $Login/ChangePassword/Background/ChangePasswordNewInput
+@onready var change_password_confirm_input: LineEdit = $Login/ChangePassword/Background/ChangePasswordConfirmInput
+
+@onready var server: Control = $Server
+@onready var role: Control = $Role
+
+func _ready() -> void:
+	server.visible = false
+	role.visible = false
+	register.visible = false
+	change_password.visible = false
+
+func _process(delta: float) -> void:
+	pass
+
+func _on_main_register_button_pressed() -> void:
+	register.visible = true
+
+func _on_main_change_password_button_pressed() -> void:
+	change_password.visible = true
+
+func _on_register_cancel_button_pressed() -> void:
+	register.visible = false
+
+func _on_change_password_cancel_button_pressed() -> void:
+	change_password.visible = false
+
+func _on_register_confirm_button_pressed() -> void:
+	if register_account_input.text == "" or register_password_input.text == "" or register_confirm_password_input.text == "":
+		printerr("注册信息不完整")
+		return
+	if register_password_input.text != register_confirm_password_input.text:
+		printerr("密码输入不一致")
+		return
+	if !check_mail_format(register_account_input.text):
+		printerr("邮箱格式不正确")
+		return
+	register_confirm_button.disabled = true
+	print("开始请求后端接口")
+	var post_data: Dictionary = {
+		"account": register_account_input.text,
+		"password": register_password_input.text,
+		"name": register_name_input.text,
+		"number": register_number_input.text,
+		"question_a": register_question_a_input.text,
+		"answer_a": register_answer_a_input.text,
+		"question_b": register_question_b_input.text,
+		"answer_b": register_answer_b_input.text,
+	}
+	print(post_data)
+	Request.on_server("/account/register", HTTPClient.METHOD_POST, post_data, func(_result, code, _headers, body):
+		if code == 200:
+			var response = JSON.parse_string(body.get_string_from_utf8())
+			print("[接口反馈数据]", response)
+			if response["code"] == 0:
+				print("接口请求成功")
+				Global.update_account_token(response["data"]["token"])
+				register_confirm_button.disabled = false
+				register.visible = false
+				register_account_input.text = ""
+				register_password_input.text = ""
+				register_confirm_password_input.text = ""
+				register_name_input.text = ""
+				register_number_input.text = ""
+				register_question_a_input.text = ""
+				register_answer_a_input.text= ""
+				register_question_b_input.text = ""
+				register_answer_b_input.text = ""
+			else:
+				register_confirm_button.disabled = false
+				if response["code"] == 10001:
+					printerr("邮箱已经被使用,请换一个")
+				else:
+					printerr("接口请求出错")
+		else:
+			printerr("接口异常")
+			register_confirm_button.disabled = false
+	)
+
+func check_mail_format(mail:String) -> bool:
+	var check:bool = true
+	var regex = RegEx.new()
+	regex.compile("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,6}$")
+	if !regex.search(mail):
+		check = false
+	return check

+ 45 - 0
server/framework/database/game_account_data/table.go

@@ -0,0 +1,45 @@
+/**
+#*****************************************************************************
+# @file    table.go
+# @author  MakerYang(https://www.makeryang.com)
+# @statement 免费课程配套开源项目,任何形式收费均为盗版
+#*****************************************************************************
+*/
+
+package GameAccountData
+
+import (
+	"Game/framework/database"
+	"Game/framework/utils"
+)
+
+var TableName = "game_account_data"
+
+type Data struct {
+	AccountId        int    `gorm:"primary_key;AUTO_INCREMENT;unique_index;not null;column:account_id"`
+	AccountAccount   string `gorm:"column:account_account"`
+	AccountPassword  string `gorm:"column:account_password"`
+	AccountName      string `gorm:"column:account_name"`
+	AccountNumber    string `gorm:"column:account_number"`
+	AccountQuestionA string `gorm:"column:account_question_a"`
+	AccountQuestionB string `gorm:"column:account_question_b"`
+	AccountAnswerA   string `gorm:"column:account_answer_a"`
+	AccountAnswerB   string `gorm:"column:account_answer_b"`
+	AccountStatus    int    `gorm:"column:account_status"`
+	Database.DefaultField
+}
+
+type Return struct {
+	Token string `json:"token"`
+}
+
+func ReturnData(dataStruct *Data) Return {
+
+	data := Return{}
+
+	if dataStruct.AccountId > 0 {
+		data.Token = Utils.EncodeId(32, dataStruct.AccountId)
+	}
+
+	return data
+}

+ 53 - 0
server/framework/database/game_level_data/table.go

@@ -0,0 +1,53 @@
+/**
+#*****************************************************************************
+# @file    table.go
+# @author  MakerYang(https://www.makeryang.com)
+# @statement 免费课程配套开源项目,任何形式收费均为盗版
+#*****************************************************************************
+*/
+
+package GameLevelData
+
+import (
+	"Game/framework/database"
+)
+
+var TableName = "game_level_data"
+
+type Data struct {
+	LevelId         int    `gorm:"primary_key;AUTO_INCREMENT;unique_index;not null;column:level_id"`
+	LevelServerId   int    `gorm:"column:level_server_id"`
+	LevelCareer     string `gorm:"column:level_career"`
+	LevelName       string `gorm:"column:level_name"`
+	LevelMin        int    `gorm:"column:level_min"`
+	LevelMax        int    `gorm:"column:level_max"`
+	LevelLifeValue  int    `gorm:"column:level_life_value"`
+	LevelMagicValue int    `gorm:"column:level_magic_value"`
+	LevelStatus     int    `gorm:"column:level_status"`
+	Database.DefaultField
+}
+
+type Return struct {
+	LevelCareer     string `json:"level_career"`
+	LevelName       string `json:"level_name"`
+	LevelMin        int    `json:"level_min"`
+	LevelMax        int    `json:"level_max"`
+	LevelLifeValue  int    `json:"level_life_value"`
+	LevelMagicValue int    `json:"level_magic_value"`
+}
+
+func ReturnData(dataStruct *Data) Return {
+
+	data := Return{}
+
+	if dataStruct.LevelId > 0 {
+		data.LevelCareer = dataStruct.LevelCareer
+		data.LevelName = dataStruct.LevelName
+		data.LevelMin = dataStruct.LevelMin
+		data.LevelMax = dataStruct.LevelMax
+		data.LevelLifeValue = dataStruct.LevelLifeValue
+		data.LevelMagicValue = dataStruct.LevelMagicValue
+	}
+
+	return data
+}

+ 47 - 0
server/framework/database/game_map_data/table.go

@@ -0,0 +1,47 @@
+/**
+#*****************************************************************************
+# @file    table.go
+# @author  MakerYang(https://www.makeryang.com)
+# @statement 免费课程配套开源项目,任何形式收费均为盗版
+#*****************************************************************************
+*/
+
+package GameMapData
+
+import (
+	"Game/framework/database"
+)
+
+var TableName = "game_map_data"
+
+type Data struct {
+	MapId       int    `gorm:"primary_key;AUTO_INCREMENT;unique_index;not null;column:map_id"`
+	MapServerId int    `gorm:"column:map_server_id"`
+	MapNumber   string `gorm:"column:map_number"`
+	MapName     string `gorm:"column:map_name"`
+	MapDefaultX int    `gorm:"column:map_default_x"`
+	MapDefaultY int    `gorm:"column:map_default_y"`
+	MapStatus   int    `gorm:"column:map_status"`
+	Database.DefaultField
+}
+
+type Return struct {
+	MapNumber   string `json:"map_number"`
+	MapName     string `json:"map_name"`
+	MapDefaultX int    `json:"map_default_x"`
+	MapDefaultY int    `json:"map_default_y"`
+}
+
+func ReturnData(dataStruct *Data) Return {
+
+	data := Return{}
+
+	if dataStruct.MapId > 0 {
+		data.MapNumber = dataStruct.MapNumber
+		data.MapName = dataStruct.MapName
+		data.MapDefaultX = dataStruct.MapDefaultX
+		data.MapDefaultY = dataStruct.MapDefaultY
+	}
+
+	return data
+}

+ 81 - 0
server/framework/database/game_player_data/table.go

@@ -0,0 +1,81 @@
+/**
+#*****************************************************************************
+# @file    table.go
+# @author  MakerYang(https://www.makeryang.com)
+# @statement 免费课程配套开源项目,任何形式收费均为盗版
+#*****************************************************************************
+*/
+
+package GamePlayerData
+
+import (
+	"Game/framework/database"
+	"Game/framework/utils"
+)
+
+var TableName = "game_player_data"
+
+type Data struct {
+	PlayerId              int    `gorm:"primary_key;AUTO_INCREMENT;unique_index;not null;column:player_id"`
+	PlayerAccountId       int    `gorm:"column:player_account_id"`
+	PlayerServerId        int    `gorm:"column:player_server_id"`
+	PlayerNickname        string `gorm:"column:player_nickname"`
+	PlayerCareer          string `gorm:"column:player_career"`
+	PlayerGender          string `gorm:"column:player_gender"`
+	PlayerAngle           int    `gorm:"column:player_angle"`
+	PlayerMap             string `gorm:"column:player_map"`
+	PlayerMapX            int    `gorm:"column:player_map_x"`
+	PlayerMapY            int    `gorm:"column:player_map_y"`
+	PlayerAssetLife       int    `gorm:"column:player_asset_life"`
+	PlayerAssetMagic      int    `gorm:"column:player_asset_magic"`
+	PlayerAssetExperience int    `gorm:"column:player_asset_experience"`
+	PlayerBodyClothe      string `gorm:"column:player_body_clothe"`
+	PlayerBodyWeapon      string `gorm:"column:player_body_weapon"`
+	PlayerBodyWing        string `gorm:"column:player_body_wing"`
+	PlayerGroupId         int    `gorm:"column:player_group_id"`
+	PlayerStatus          int    `gorm:"column:player_status"`
+	Database.DefaultField
+}
+
+type Return struct {
+	Token                 string `json:"token"`
+	PlayerNickname        string `json:"player_nickname"`
+	PlayerCareer          string `json:"player_career"`
+	PlayerGender          string `json:"player_gender"`
+	PlayerAngle           int    `json:"player_angle"`
+	PlayerMap             string `json:"player_map"`
+	PlayerMapX            int    `json:"player_map_x"`
+	PlayerMapY            int    `json:"player_map_y"`
+	PlayerAssetLife       int    `json:"player_asset_life"`
+	PlayerAssetMagic      int    `json:"player_asset_magic"`
+	PlayerAssetExperience int    `json:"player_asset_experience"`
+	PlayerBodyClothe      string `json:"player_body_clothe"`
+	PlayerBodyWeapon      string `json:"player_body_weapon"`
+	PlayerBodyWing        string `json:"player_body_wing"`
+	PlayerGroupId         int    `json:"player_group_id"`
+}
+
+func ReturnData(dataStruct *Data) Return {
+
+	data := Return{}
+
+	if dataStruct.PlayerId > 0 {
+		data.Token = Utils.EncodeId(32, dataStruct.PlayerId, dataStruct.PlayerAccountId, dataStruct.PlayerServerId)
+		data.PlayerNickname = dataStruct.PlayerNickname
+		data.PlayerCareer = dataStruct.PlayerCareer
+		data.PlayerGender = dataStruct.PlayerGender
+		data.PlayerAngle = dataStruct.PlayerAngle
+		data.PlayerMap = dataStruct.PlayerMap
+		data.PlayerMapX = dataStruct.PlayerMapX
+		data.PlayerMapY = dataStruct.PlayerMapY
+		data.PlayerAssetLife = dataStruct.PlayerAssetLife
+		data.PlayerAssetMagic = dataStruct.PlayerAssetMagic
+		data.PlayerAssetExperience = dataStruct.PlayerAssetExperience
+		data.PlayerBodyClothe = dataStruct.PlayerBodyClothe
+		data.PlayerBodyWeapon = dataStruct.PlayerBodyWeapon
+		data.PlayerBodyWing = dataStruct.PlayerBodyWing
+		data.PlayerGroupId = dataStruct.PlayerGroupId
+	}
+
+	return data
+}

+ 40 - 0
server/framework/database/game_server_data/table.go

@@ -0,0 +1,40 @@
+/**
+#*****************************************************************************
+# @file    table.go
+# @author  MakerYang(https://www.makeryang.com)
+# @statement 免费课程配套开源项目,任何形式收费均为盗版
+#*****************************************************************************
+*/
+
+package GameServerData
+
+import (
+	"Game/framework/database"
+	"Game/framework/utils"
+)
+
+var TableName = "game_server_data"
+
+type Data struct {
+	ServerId     int    `gorm:"primary_key;AUTO_INCREMENT;unique_index;not null;column:server_id"`
+	ServerName   string `gorm:"column:server_name"`
+	ServerStatus int    `gorm:"column:server_status"`
+	Database.DefaultField
+}
+
+type Return struct {
+	Token      string `json:"token"`
+	ServerName string `json:"server_name"`
+}
+
+func ReturnData(dataStruct *Data) Return {
+
+	data := Return{}
+
+	if dataStruct.ServerId > 0 {
+		data.Token = Utils.EncodeId(32, dataStruct.ServerId)
+		data.ServerName = dataStruct.ServerName
+	}
+
+	return data
+}

+ 81 - 0
server/framework/interface/account/account.go

@@ -0,0 +1,81 @@
+/**
+#*****************************************************************************
+# @file    account.go
+# @author  MakerYang(https://www.makeryang.com)
+# @statement 免费课程配套开源项目,任何形式收费均为盗版
+#*****************************************************************************
+*/
+
+package AccountInterface
+
+import (
+	"Game/framework/database"
+	"Game/framework/database/game_account_data"
+	"Game/framework/utils"
+	"encoding/json"
+	"fmt"
+	"github.com/gin-gonic/gin"
+	"io/ioutil"
+)
+
+type requestRegister struct {
+	Account   string `json:"account"`
+	Password  string `json:"password"`
+	Name      string `json:"name"`
+	Number    string `json:"number"`
+	QuestionA string `json:"question_a"`
+	AnswerA   string `json:"answer_a"`
+	QuestionB string `json:"question_b"`
+	AnswerB   string `json:"answer_b"`
+}
+
+type responseRegister struct {
+	Token string `json:"token"`
+}
+
+func Register(c *gin.Context) {
+
+	returnData := responseRegister{}
+
+	jsonData := requestRegister{}
+	requestJson, _ := ioutil.ReadAll(c.Request.Body)
+	err := json.Unmarshal(requestJson, &jsonData)
+	if err != nil {
+		Utils.Error(c, returnData)
+		return
+	}
+
+	accountDatabase := Database.New(GameAccountData.TableName)
+	accountData := GameAccountData.Data{}
+	where := fmt.Sprintf("account_account = %q", jsonData.Account)
+	err = accountDatabase.GetData(&accountData, where, "")
+	if err == nil && accountData.AccountId > 0 {
+		Utils.Warning(c, 10001, "邮箱已经被注册", returnData)
+		return
+	}
+
+	setData := &GameAccountData.Data{}
+	setData.AccountAccount = jsonData.Account
+	setData.AccountPassword = Utils.MD5Hash(jsonData.Password)
+	setData.AccountName = jsonData.Name
+	setData.AccountNumber = jsonData.Number
+	setData.AccountQuestionA = jsonData.QuestionA
+	setData.AccountAnswerA = jsonData.AnswerA
+	setData.AccountQuestionB = jsonData.QuestionB
+	setData.AccountAnswerB = jsonData.AnswerB
+	setData.AccountStatus = 2
+	err = accountDatabase.CreateData(setData)
+	if err != nil {
+		Utils.Error(c, accountData)
+		return
+	}
+	if setData.AccountId == 0 {
+		Utils.Error(c, accountData)
+		return
+	}
+
+	returnData.Token = Utils.EncodeId(128, setData.AccountId)
+
+	Utils.Success(c, returnData)
+	return
+}

+ 7 - 0
server/framework/interface/interface.go

@@ -10,6 +10,7 @@ package Interface
 
 import (
 	"Game/framework/config"
+	AccountInterface "Game/framework/interface/account"
 	"Game/framework/interface/ping"
 	"context"
 	"fmt"
@@ -32,6 +33,12 @@ func router() *gin.Engine {
 	// 健康检查接口
 	router.GET("/ping", PingInterface.Ping)
 
+	// 账户相关接口
+	account := router.Group("account")
+	{
+		account.POST("/register", AccountInterface.Register)
+	}
+
 	return router
 }
 

+ 1 - 1
update.bat

@@ -1,2 +1,2 @@
 @echo off
-scp -r ./engine/release/server* root@172.21.245.0:/data/wwwroot/game/
+scp -r ./engine/release/server* root@172.19.166.1:/data/wwwroot/game/

+ 553 - 1
wiki/course/3.0.0.md

@@ -4,4 +4,556 @@
 
 ### 用户界面
 
-> 用户界面的知识点、用户界面的规划
+> 用户界面的知识点、用户界面的规划
+
+### 数据表字段映射程序
+
+> `game_account_data`数据表字段映射程序
+
+```go
+package GameAccountData
+
+import (
+	"Game/framework/database"
+	"Game/framework/utils"
+)
+
+var TableName = "game_account_data"
+
+type Data struct {
+	AccountId        int    `gorm:"primary_key;AUTO_INCREMENT;unique_index;not null;column:account_id"`
+	AccountAccount   string `gorm:"column:account_account"`
+	AccountPassword  string `gorm:"column:account_password"`
+	AccountName      string `gorm:"column:account_name"`
+	AccountNumber    string `gorm:"column:account_number"`
+	AccountQuestionA string `gorm:"column:account_question_a"`
+	AccountQuestionB string `gorm:"column:account_question_b"`
+	AccountAnswerA   string `gorm:"column:account_answer_a"`
+	AccountAnswerB   string `gorm:"column:account_answer_b"`
+	AccountStatus    int    `gorm:"column:account_status"`
+	Database.DefaultField
+}
+
+type Return struct {
+	Token string `json:"token"`
+}
+
+func ReturnData(dataStruct *Data) Return {
+
+	data := Return{}
+
+	if dataStruct.AccountId > 0 {
+		data.Token = Utils.EncodeId(32, dataStruct.AccountId)
+	}
+
+	return data
+}
+```
+
+> `game_level_data`数据表字段映射程序
+
+```go
+package GameLevelData
+
+import (
+	"Game/framework/database"
+)
+
+var TableName = "game_level_data"
+
+type Data struct {
+	LevelId         int    `gorm:"primary_key;AUTO_INCREMENT;unique_index;not null;column:level_id"`
+	LevelServerId   int    `gorm:"column:level_server_id"`
+	LevelCareer     string `gorm:"column:level_career"`
+	LevelName       string `gorm:"column:level_name"`
+	LevelMin        int    `gorm:"column:level_min"`
+	LevelMax        int    `gorm:"column:level_max"`
+	LevelLifeValue  int    `gorm:"column:level_life_value"`
+	LevelMagicValue int    `gorm:"column:level_magic_value"`
+	LevelStatus     int    `gorm:"column:level_status"`
+	Database.DefaultField
+}
+
+type Return struct {
+	LevelCareer     string `json:"level_career"`
+	LevelName       string `json:"level_name"`
+	LevelMin        int    `json:"level_min"`
+	LevelMax        int    `json:"level_max"`
+	LevelLifeValue  int    `json:"level_life_value"`
+	LevelMagicValue int    `json:"level_magic_value"`
+}
+
+func ReturnData(dataStruct *Data) Return {
+
+	data := Return{}
+
+	if dataStruct.LevelId > 0 {
+		data.LevelCareer = dataStruct.LevelCareer
+		data.LevelName = dataStruct.LevelName
+		data.LevelMin = dataStruct.LevelMin
+		data.LevelMax = dataStruct.LevelMax
+		data.LevelLifeValue = dataStruct.LevelLifeValue
+		data.LevelMagicValue = dataStruct.LevelMagicValue
+	}
+
+	return data
+}
+```
+
+> `game_map_data`数据表字段映射程序
+
+```go
+package GameMapData
+
+import (
+	"Game/framework/database"
+)
+
+var TableName = "game_map_data"
+
+type Data struct {
+	MapId       int    `gorm:"primary_key;AUTO_INCREMENT;unique_index;not null;column:map_id"`
+	MapServerId int    `gorm:"column:map_server_id"`
+	MapNumber   string `gorm:"column:map_number"`
+	MapName     string `gorm:"column:map_name"`
+	MapDefaultX int    `gorm:"column:map_default_x"`
+	MapDefaultY int    `gorm:"column:map_default_y"`
+	MapStatus   int    `gorm:"column:map_status"`
+	Database.DefaultField
+}
+
+type Return struct {
+	MapNumber   string `json:"map_number"`
+	MapName     string `json:"map_name"`
+	MapDefaultX int    `json:"map_default_x"`
+	MapDefaultY int    `json:"map_default_y"`
+}
+
+func ReturnData(dataStruct *Data) Return {
+
+	data := Return{}
+
+	if dataStruct.MapId > 0 {
+		data.MapNumber = dataStruct.MapNumber
+		data.MapName = dataStruct.MapName
+		data.MapDefaultX = dataStruct.MapDefaultX
+		data.MapDefaultY = dataStruct.MapDefaultY
+	}
+
+	return data
+}
+```
+
+> `game_player_data`数据表字段映射程序
+
+```go
+package GamePlayerData
+
+import (
+	"Game/framework/database"
+	"Game/framework/utils"
+)
+
+var TableName = "game_player_data"
+
+type Data struct {
+	PlayerId              int    `gorm:"primary_key;AUTO_INCREMENT;unique_index;not null;column:player_id"`
+	PlayerAccountId       int    `gorm:"column:player_account_id"`
+	PlayerServerId        int    `gorm:"column:player_server_id"`
+	PlayerNickname        string `gorm:"column:player_nickname"`
+	PlayerCareer          string `gorm:"column:player_career"`
+	PlayerGender          string `gorm:"column:player_gender"`
+	PlayerAngle           int    `gorm:"column:player_angle"`
+	PlayerMap             string `gorm:"column:player_map"`
+	PlayerMapX            int    `gorm:"column:player_map_x"`
+	PlayerMapY            int    `gorm:"column:player_map_y"`
+	PlayerAssetLife       int    `gorm:"column:player_asset_life"`
+	PlayerAssetMagic      int    `gorm:"column:player_asset_magic"`
+	PlayerAssetExperience int    `gorm:"column:player_asset_experience"`
+	PlayerBodyClothe      string `gorm:"column:player_body_clothe"`
+	PlayerBodyWeapon      string `gorm:"column:player_body_weapon"`
+	PlayerBodyWing        string `gorm:"column:player_body_wing"`
+	PlayerGroupId         int    `gorm:"column:player_group_id"`
+	PlayerStatus          int    `gorm:"column:player_status"`
+	Database.DefaultField
+}
+
+type Return struct {
+	Token                 string `json:"token"`
+	PlayerNickname        string `json:"player_nickname"`
+	PlayerCareer          string `json:"player_career"`
+	PlayerGender          string `json:"player_gender"`
+	PlayerAngle           int    `json:"player_angle"`
+	PlayerMap             string `json:"player_map"`
+	PlayerMapX            int    `json:"player_map_x"`
+	PlayerMapY            int    `json:"player_map_y"`
+	PlayerAssetLife       int    `json:"player_asset_life"`
+	PlayerAssetMagic      int    `json:"player_asset_magic"`
+	PlayerAssetExperience int    `json:"player_asset_experience"`
+	PlayerBodyClothe      string `json:"player_body_clothe"`
+	PlayerBodyWeapon      string `json:"player_body_weapon"`
+	PlayerBodyWing        string `json:"player_body_wing"`
+	PlayerGroupId         int    `json:"player_group_id"`
+}
+
+func ReturnData(dataStruct *Data) Return {
+
+	data := Return{}
+
+	if dataStruct.PlayerId > 0 {
+		data.Token = Utils.EncodeId(32, dataStruct.PlayerId, dataStruct.PlayerAccountId, dataStruct.PlayerServerId)
+		data.PlayerNickname = dataStruct.PlayerNickname
+		data.PlayerCareer = dataStruct.PlayerCareer
+		data.PlayerGender = dataStruct.PlayerGender
+		data.PlayerAngle = dataStruct.PlayerAngle
+		data.PlayerMap = dataStruct.PlayerMap
+		data.PlayerMapX = dataStruct.PlayerMapX
+		data.PlayerMapY = dataStruct.PlayerMapY
+		data.PlayerAssetLife = dataStruct.PlayerAssetLife
+		data.PlayerAssetMagic = dataStruct.PlayerAssetMagic
+		data.PlayerAssetExperience = dataStruct.PlayerAssetExperience
+		data.PlayerBodyClothe = dataStruct.PlayerBodyClothe
+		data.PlayerBodyWeapon = dataStruct.PlayerBodyWeapon
+		data.PlayerBodyWing = dataStruct.PlayerBodyWing
+		data.PlayerGroupId = dataStruct.PlayerGroupId
+	}
+
+	return data
+}
+```
+
+> `game_server_data`数据表字段映射程序
+
+```go
+package GameServerData
+
+import (
+	"Game/framework/database"
+	"Game/framework/utils"
+)
+
+var TableName = "game_server_data"
+
+type Data struct {
+	ServerId     int    `gorm:"primary_key;AUTO_INCREMENT;unique_index;not null;column:server_id"`
+	ServerName   string `gorm:"column:server_name"`
+	ServerStatus int    `gorm:"column:server_status"`
+	Database.DefaultField
+}
+
+type Return struct {
+	Token      string `json:"token"`
+	ServerName string `json:"server_name"`
+}
+
+func ReturnData(dataStruct *Data) Return {
+
+	data := Return{}
+
+	if dataStruct.ServerId > 0 {
+		data.Token = Utils.EncodeId(32, dataStruct.ServerId)
+		data.ServerName = dataStruct.ServerName
+	}
+
+	return data
+}
+```
+
+### 创建数据表测试数据
+
+> `game_level_data`数据表测试数据
+
+```mysql
+INSERT INTO `game_level_data` VALUES (1, 1, 'warrior', 1, 1, 100, 10, 10, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (2, 1, 'warrior', 2, 100, 500, 20, 20, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (3, 1, 'warrior', 3, 500, 1000, 30, 30, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (4, 1, 'warrior', 4, 1000, 1500, 40, 40, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (5, 1, 'warrior', 5, 1500, 2000, 50, 50, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (6, 1, 'warrior', 6, 2000, 2500, 60, 60, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (7, 1, 'warrior', 7, 2500, 3000, 70, 70, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (8, 1, 'warrior', 8, 3000, 3500, 80, 80, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (9, 1, 'warrior', 9, 3500, 4000, 90, 90, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (10, 1, 'warrior', 10, 4000, 4500, 100, 100, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (11, 1, 'warrior', 11, 4500, 5000, 110, 110, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (12, 1, 'warrior', 12, 5000, 5500, 120, 120, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (13, 1, 'warrior', 13, 5500, 6000, 130, 130, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (14, 1, 'warrior', 14, 6000, 6500, 140, 140, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (15, 1, 'warrior', 15, 6500, 7000, 150, 150, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (16, 1, 'warrior', 16, 7000, 7500, 160, 160, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (17, 1, 'warrior', 17, 7500, 8000, 170, 170, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (18, 1, 'warrior', 18, 8000, 8500, 180, 180, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (19, 1, 'warrior', 19, 8500, 9000, 190, 190, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (20, 1, 'warrior', 20, 9000, 9500, 200, 200, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (21, 1, 'warrior', 21, 9500, 10500, 250, 220, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (22, 1, 'warrior', 22, 10500, 11000, 300, 240, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (23, 1, 'warrior', 23, 11000, 15000, 350, 260, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (24, 1, 'warrior', 24, 15000, 20000, 400, 280, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (25, 1, 'warrior', 25, 20000, 25000, 450, 300, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (26, 1, 'warrior', 26, 25000, 30000, 500, 320, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (27, 1, 'warrior', 27, 30000, 35000, 550, 340, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (28, 1, 'warrior', 28, 35000, 40000, 600, 380, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (29, 1, 'warrior', 29, 40000, 45000, 650, 400, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (30, 1, 'warrior', 30, 45000, 50000, 700, 420, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (31, 1, 'warrior', 31, 50000, 60000, 750, 440, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (32, 1, 'warrior', 32, 70000, 80000, 800, 460, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (33, 1, 'warrior', 33, 80000, 90000, 850, 480, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (34, 1, 'warrior', 34, 90000, 100000, 900, 500, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (35, 1, 'warrior', 35, 100000, 200000, 950, 520, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (36, 1, 'warrior', 36, 200000, 300000, 1000, 540, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (37, 1, 'warrior', 37, 300000, 400000, 1050, 560, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (38, 1, 'warrior', 38, 400000, 500000, 1100, 580, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (39, 1, 'warrior', 39, 500000, 600000, 1150, 600, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (40, 1, 'warrior', 40, 600000, 700000, 1200, 620, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (41, 1, 'warrior', 41, 700000, 800000, 1250, 640, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (42, 1, 'warrior', 42, 800000, 900000, 1300, 660, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (43, 1, 'warrior', 43, 900000, 1000000, 1350, 680, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (44, 1, 'warrior', 44, 1000000, 110000, 1400, 700, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (45, 1, 'warrior', 45, 1100000, 1200000, 1450, 720, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (46, 1, 'warrior', 46, 1200000, 1300000, 1500, 740, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (47, 1, 'warrior', 47, 1300000, 1400000, 1550, 760, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (48, 1, 'warrior', 48, 1400000, 1500000, 1600, 780, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (49, 1, 'warrior', 49, 1500000, 1600000, 1650, 800, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (50, 1, 'warrior', 50, 1600000, 1700000, 1700, 820, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (61, 1, 'warrior', 51, 1700000, 1800000, 1750, 840, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (62, 1, 'warrior', 52, 1800000, 1900000, 1800, 860, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (63, 1, 'warrior', 53, 1900000, 2000000, 1850, 880, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (64, 1, 'warrior', 54, 2000000, 3000000, 1900, 900, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (65, 1, 'warrior', 55, 3000000, 4000000, 1950, 920, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (66, 1, 'warrior', 56, 4000000, 5000000, 2000, 940, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (67, 1, 'warrior', 57, 5000000, 6000000, 2050, 960, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (68, 1, 'warrior', 58, 6000000, 7000000, 2100, 980, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (69, 1, 'warrior', 59, 7000000, 8000000, 2150, 1000, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (70, 1, 'warrior', 60, 8000000, 100000000, 2200, 1020, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (71, 1, 'mage', 1, 1, 100, 10, 10, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (72, 1, 'mage', 2, 100, 500, 20, 20, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (73, 1, 'mage', 3, 500, 1000, 30, 30, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (74, 1, 'mage', 4, 1000, 1500, 40, 40, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (75, 1, 'mage', 5, 1500, 2000, 50, 50, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (76, 1, 'mage', 6, 2000, 2500, 60, 60, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (77, 1, 'mage', 7, 2500, 3000, 70, 70, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (78, 1, 'mage', 8, 3000, 3500, 80, 80, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (79, 1, 'mage', 9, 3500, 4000, 90, 90, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (80, 1, 'mage', 10, 4000, 4500, 100, 100, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (81, 1, 'mage', 11, 4500, 5000, 110, 110, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (82, 1, 'mage', 12, 5000, 5500, 120, 120, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (83, 1, 'mage', 13, 5500, 6000, 130, 130, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (84, 1, 'mage', 14, 6000, 6500, 140, 140, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (85, 1, 'mage', 15, 6500, 7000, 150, 150, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (86, 1, 'mage', 16, 7000, 7500, 160, 160, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (87, 1, 'mage', 17, 7500, 8000, 170, 170, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (88, 1, 'mage', 18, 8000, 8500, 180, 180, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (89, 1, 'mage', 19, 8500, 9000, 190, 190, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (90, 1, 'mage', 20, 9000, 9500, 200, 200, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (91, 1, 'mage', 21, 9500, 10500, 250, 220, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (92, 1, 'mage', 22, 10500, 11000, 300, 240, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (93, 1, 'mage', 23, 11000, 15000, 350, 260, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (94, 1, 'mage', 24, 15000, 20000, 400, 280, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (95, 1, 'mage', 25, 20000, 25000, 450, 300, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (96, 1, 'mage', 26, 25000, 30000, 500, 320, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (97, 1, 'mage', 27, 30000, 35000, 550, 340, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (98, 1, 'mage', 28, 35000, 40000, 600, 380, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (99, 1, 'mage', 29, 40000, 45000, 650, 400, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (100, 1, 'mage', 30, 45000, 50000, 700, 420, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (101, 1, 'mage', 31, 50000, 60000, 750, 440, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (102, 1, 'mage', 32, 70000, 80000, 800, 460, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (103, 1, 'mage', 33, 80000, 90000, 850, 480, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (104, 1, 'mage', 34, 90000, 100000, 900, 500, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (105, 1, 'mage', 35, 100000, 200000, 950, 520, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (106, 1, 'mage', 36, 200000, 300000, 1000, 540, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (107, 1, 'mage', 37, 300000, 400000, 1050, 560, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (108, 1, 'mage', 38, 400000, 500000, 1100, 580, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (109, 1, 'mage', 39, 500000, 600000, 1150, 600, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (110, 1, 'mage', 40, 600000, 700000, 1200, 620, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (111, 1, 'mage', 41, 700000, 800000, 1250, 640, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (112, 1, 'mage', 42, 800000, 900000, 1300, 660, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (113, 1, 'mage', 43, 900000, 1000000, 1350, 680, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (114, 1, 'mage', 44, 1000000, 110000, 1400, 700, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (115, 1, 'mage', 45, 1100000, 1200000, 1450, 720, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (116, 1, 'mage', 46, 1200000, 1300000, 1500, 740, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (117, 1, 'mage', 47, 1300000, 1400000, 1550, 760, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (118, 1, 'mage', 48, 1400000, 1500000, 1600, 780, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (119, 1, 'mage', 49, 1500000, 1600000, 1650, 800, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (120, 1, 'mage', 50, 1600000, 1700000, 1700, 820, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (121, 1, 'mage', 51, 1700000, 1800000, 1750, 840, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (122, 1, 'mage', 52, 1800000, 1900000, 1800, 860, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (123, 1, 'mage', 53, 1900000, 2000000, 1850, 880, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (124, 1, 'mage', 54, 2000000, 3000000, 1900, 900, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (125, 1, 'mage', 55, 3000000, 4000000, 1950, 920, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (126, 1, 'mage', 56, 4000000, 5000000, 2000, 940, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (127, 1, 'mage', 57, 5000000, 6000000, 2050, 960, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (128, 1, 'mage', 58, 6000000, 7000000, 2100, 980, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (129, 1, 'mage', 59, 7000000, 8000000, 2150, 1000, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (130, 1, 'mage', 60, 8000000, 100000000, 2200, 1020, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (131, 1, 'taoist', 1, 1, 100, 10, 10, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (132, 1, 'taoist', 2, 100, 500, 20, 20, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (133, 1, 'taoist', 3, 500, 1000, 30, 30, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (134, 1, 'taoist', 4, 1000, 1500, 40, 40, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (135, 1, 'taoist', 5, 1500, 2000, 50, 50, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (136, 1, 'taoist', 6, 2000, 2500, 60, 60, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (137, 1, 'taoist', 7, 2500, 3000, 70, 70, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (138, 1, 'taoist', 8, 3000, 3500, 80, 80, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (139, 1, 'taoist', 9, 3500, 4000, 90, 90, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (140, 1, 'taoist', 10, 4000, 4500, 100, 100, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (141, 1, 'taoist', 11, 4500, 5000, 110, 110, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (142, 1, 'taoist', 12, 5000, 5500, 120, 120, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (143, 1, 'taoist', 13, 5500, 6000, 130, 130, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (144, 1, 'taoist', 14, 6000, 6500, 140, 140, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (145, 1, 'taoist', 15, 6500, 7000, 150, 150, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (146, 1, 'taoist', 16, 7000, 7500, 160, 160, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (147, 1, 'taoist', 17, 7500, 8000, 170, 170, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (148, 1, 'taoist', 18, 8000, 8500, 180, 180, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (149, 1, 'taoist', 19, 8500, 9000, 190, 190, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (150, 1, 'taoist', 20, 9000, 9500, 200, 200, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (151, 1, 'taoist', 21, 9500, 10500, 250, 220, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (152, 1, 'taoist', 22, 10500, 11000, 300, 240, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (153, 1, 'taoist', 23, 11000, 15000, 350, 260, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (154, 1, 'taoist', 24, 15000, 20000, 400, 280, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (155, 1, 'taoist', 25, 20000, 25000, 450, 300, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (156, 1, 'taoist', 26, 25000, 30000, 500, 320, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (157, 1, 'taoist', 27, 30000, 35000, 550, 340, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (158, 1, 'taoist', 28, 35000, 40000, 600, 380, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (159, 1, 'taoist', 29, 40000, 45000, 650, 400, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (160, 1, 'taoist', 30, 45000, 50000, 700, 420, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (161, 1, 'taoist', 31, 50000, 60000, 750, 440, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (162, 1, 'taoist', 32, 70000, 80000, 800, 460, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (163, 1, 'taoist', 33, 80000, 90000, 850, 480, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (164, 1, 'taoist', 34, 90000, 100000, 900, 500, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (165, 1, 'taoist', 35, 100000, 200000, 950, 520, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (166, 1, 'taoist', 36, 200000, 300000, 1000, 540, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (167, 1, 'taoist', 37, 300000, 400000, 1050, 560, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (168, 1, 'taoist', 38, 400000, 500000, 1100, 580, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (169, 1, 'taoist', 39, 500000, 600000, 1150, 600, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (170, 1, 'taoist', 40, 600000, 700000, 1200, 620, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (171, 1, 'taoist', 41, 700000, 800000, 1250, 640, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (172, 1, 'taoist', 42, 800000, 900000, 1300, 660, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (173, 1, 'taoist', 43, 900000, 1000000, 1350, 680, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (174, 1, 'taoist', 44, 1000000, 110000, 1400, 700, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (175, 1, 'taoist', 45, 1100000, 1200000, 1450, 720, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (176, 1, 'taoist', 46, 1200000, 1300000, 1500, 740, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (177, 1, 'taoist', 47, 1300000, 1400000, 1550, 760, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (178, 1, 'taoist', 48, 1400000, 1500000, 1600, 780, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (179, 1, 'taoist', 49, 1500000, 1600000, 1650, 800, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (180, 1, 'taoist', 50, 1600000, 1700000, 1700, 820, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (181, 1, 'taoist', 51, 1700000, 1800000, 1750, 840, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (182, 1, 'taoist', 52, 1800000, 1900000, 1800, 860, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (183, 1, 'taoist', 53, 1900000, 2000000, 1850, 880, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (184, 1, 'taoist', 54, 2000000, 3000000, 1900, 900, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (185, 1, 'taoist', 55, 3000000, 4000000, 1950, 920, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (186, 1, 'taoist', 56, 4000000, 5000000, 2000, 940, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (187, 1, 'taoist', 57, 5000000, 6000000, 2050, 960, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (188, 1, 'taoist', 58, 6000000, 7000000, 2100, 980, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (189, 1, 'taoist', 59, 7000000, 8000000, 2150, 1000, 2, 0, 0, 0);
+INSERT INTO `game_level_data` VALUES (190, 1, 'taoist', 60, 8000000, 100000000, 2200, 1020, 2, 0, 0, 0);
+```
+
+> `game_server_data`数据表测试数据
+
+```mysql
+INSERT INTO `game_server_data` VALUES (1, '游戏一区', 2, 0, 0, 0);
+INSERT INTO `game_server_data` VALUES (2, '游戏二区', 2, 0, 0, 0);
+INSERT INTO `game_server_data` VALUES (3, '游戏三区', 2, 0, 0, 0);
+```
+
+### 用户注册接口
+
+> 用户注册接口程序源码
+
+```go
+package AccountInterface
+
+import (
+	"Game/framework/database"
+	"Game/framework/database/game_account_data"
+	"Game/framework/utils"
+	"encoding/json"
+	"fmt"
+	"github.com/gin-gonic/gin"
+	"io/ioutil"
+)
+
+type requestRegister struct {
+	Account   string `json:"account"`
+	Password  string `json:"password"`
+	Name      string `json:"name"`
+	Number    string `json:"number"`
+	QuestionA string `json:"question_a"`
+	AnswerA   string `json:"answer_a"`
+	QuestionB string `json:"question_b"`
+	AnswerB   string `json:"answer_b"`
+}
+
+type responseRegister struct {
+	Token string `json:"token"`
+}
+
+func Register(c *gin.Context) {
+
+	returnData := responseRegister{}
+
+	jsonData := requestRegister{}
+	requestJson, _ := ioutil.ReadAll(c.Request.Body)
+	err := json.Unmarshal(requestJson, &jsonData)
+	if err != nil {
+		Utils.Error(c, returnData)
+		return
+	}
+
+	accountDatabase := Database.New(GameAccountData.TableName)
+	accountData := GameAccountData.Data{}
+	where := fmt.Sprintf("account_account = %q", jsonData.Account)
+	err = accountDatabase.GetData(&accountData, where, "")
+	if err == nil && accountData.AccountId > 0 {
+		Utils.Warning(c, 10001, "邮箱已经被注册", returnData)
+		return
+	}
+
+	setData := &GameAccountData.Data{}
+	setData.AccountAccount = jsonData.Account
+	setData.AccountPassword = Utils.MD5Hash(jsonData.Password)
+	setData.AccountName = jsonData.Name
+	setData.AccountNumber = jsonData.Number
+	setData.AccountQuestionA = jsonData.QuestionA
+	setData.AccountAnswerA = jsonData.AnswerA
+	setData.AccountQuestionB = jsonData.QuestionB
+	setData.AccountAnswerB = jsonData.AnswerB
+	setData.AccountStatus = 2
+	err = accountDatabase.CreateData(setData)
+	if err != nil {
+		Utils.Error(c, accountData)
+		return
+	}
+	if setData.AccountId == 0 {
+		Utils.Error(c, accountData)
+		return
+	}
+
+	returnData.Token = Utils.EncodeId(128, setData.AccountId)
+
+	Utils.Success(c, returnData)
+	return
+}
+```
+
+> 用户注册接口路由
+
+```go
+// 账户相关接口
+account := router.Group("account")
+{
+    account.POST("/register", AccountInterface.Register)
+}
+```
+
+### 邮箱格式验证函数
+
+> 用于游戏引擎中验证邮箱格式的合法性
+
+``` go
+func check_mail_format(mail:String) -> bool:
+	var check:bool = true
+	var regex = RegEx.new()
+	regex.compile("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,6}$")
+	if !regex.search(mail):
+		check = false
+	return check
+```