Compare commits

...

15 Commits

  1. 2
      Example/SystemExamples/PlayerStorage/Script/ViewStorage.cs
  2. 133
      Example/Tween/Texture/Gobot_Model.tscn
  3. BIN
      Example/Tween/Texture/gBot_pieces.png
  4. 34
      Example/Tween/Texture/gBot_pieces.png.import
  5. 3
      Example/UsingTest/Scene/TestEGFramework.tscn
  6. 175
      Example/UsingTest/Script/EGSaveTest.cs
  7. 386
      addons/EGFramework/Manual/EGSave.md
  8. 76
      addons/EGFramework/Module/SaveTools/EGByteSave.cs
  9. 15
      addons/EGFramework/Module/SaveTools/EGCsv.cs
  10. 226
      addons/EGFramework/Module/SaveTools/EGCsvSave.cs
  11. 32
      addons/EGFramework/Module/SaveTools/EGJsonSave.cs
  12. 16
      addons/EGFramework/Module/SaveTools/EGLiteDB.cs
  13. 65
      addons/EGFramework/Module/SaveTools/EGLiteDBSave.cs
  14. 176
      addons/EGFramework/Module/SaveTools/EGSave.cs
  15. 26
      addons/EGFramework/Module/SaveTools/EGSqlite.cs
  16. 24
      addons/EGFramework/Module/SaveTools/SaveToolsInterface.cs
  17. 54
      addons/Tools/ItemImporter/ToolItemImporter.cs
  18. 37
      addons/Tools/ItemImporter/ToolItemImporter.tscn
  19. 7
      addons/Tools/ItemImporter/plugin.cfg
  20. 7
      project.godot

2
Example/SystemExamples/PlayerStorage/Script/ViewStorage.cs

@ -8,8 +8,6 @@ public partial class ViewStorage : Node,IEGFramework @@ -8,8 +8,6 @@ public partial class ViewStorage : Node,IEGFramework
public override void _Ready()
{
// this.GetModule<EGByteSave>().SaveToFile("nihao");
Variant result = this.GetModule<EGByteSave>().LoadFromFile();
GD.Print(result);
}
// Called every frame. 'delta' is the elapsed time since the previous frame.

133
Example/Tween/Texture/Gobot_Model.tscn

@ -0,0 +1,133 @@ @@ -0,0 +1,133 @@
[gd_scene load_steps=2 format=3 uid="uid://bonekg2q1lxx4"]
[ext_resource type="Texture2D" uid="uid://cbq4j4svebp45" path="res://Example/Tween/Texture/gBot_pieces.png" id="1_vmu55"]
[node name="Node2D" type="Node2D"]
[node name="Gobot" type="Node2D" parent="."]
position = Vector2(157, 138)
[node name="arm_left" type="Polygon2D" parent="Gobot"]
position = Vector2(77, 210)
texture = ExtResource("1_vmu55")
skeleton = NodePath("../../Skeleton2D")
polygon = PackedVector2Array(188, 36, 225, 22, 276, 47, 266, 129, 248, 188, 275, 275, 298, 302, 275, 348, 220, 360, 194, 313, 176, 246, 187, 199, 184, 102, 176, 48, 224, 96, 216, 192, 240, 304, 216, 208)
uv = PackedVector2Array(188, 36, 225, 22, 276, 47, 266, 129, 248, 188, 275, 275, 298, 302, 275, 348, 220, 360, 194, 313, 176, 246, 187, 199, 184, 102, 174, 44, 216, 96, 216, 192, 240, 304, 216, 200)
polygons = [PackedInt32Array(14, 1, 0, 13, 12), PackedInt32Array(1, 2, 3, 14), PackedInt32Array(14, 15, 4, 3), PackedInt32Array(14, 12, 11, 15), PackedInt32Array(5, 6, 7, 16), PackedInt32Array(16, 9, 8, 7), PackedInt32Array(11, 17, 15), PackedInt32Array(15, 17, 4), PackedInt32Array(17, 16, 9, 10, 11), PackedInt32Array(4, 17, 16, 5)]
bones = ["hip", PackedFloat32Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "hip/chest", PackedFloat32Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "hip/chest/head", PackedFloat32Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "hip/chest/head/jaw", PackedFloat32Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "hip/chest/arm_right", PackedFloat32Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "hip/chest/arm_right/hand_right", PackedFloat32Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "hip/chest/arm_left", PackedFloat32Array(1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0), "hip/chest/arm_left/hand_left", PackedFloat32Array(0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1), "hip/leg_left", PackedFloat32Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "hip/leg_left/calf_left", PackedFloat32Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "hip/leg_left/calf_left/foot_left", PackedFloat32Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "hip/leg_right", PackedFloat32Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "hip/leg_right/leg_right2", PackedFloat32Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "hip/leg_right/leg_right2/leg_right3", PackedFloat32Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)]
internal_vertex_count = 4
[node name="leg_left" type="Polygon2D" parent="Gobot"]
position = Vector2(-46, 56)
texture = ExtResource("1_vmu55")
skeleton = NodePath("../../Skeleton2D")
polygon = PackedVector2Array(285.231, 396.984, 311.252, 384.229, 343.905, 401.066, 341.354, 431.678, 333.701, 442.392, 327.578, 478.617, 337.782, 475.556, 340.843, 504.637, 326.047, 538.821, 327.578, 569.433, 349.517, 602.086, 382.17, 608.719, 391.354, 649.535, 403.088, 657.698, 406.66, 688.821, 397.476, 693.413, 250.027, 690.352, 247.476, 660.25, 252.068, 657.188, 247.986, 629.127, 254.619, 613.821, 254.619, 509.229, 281.66, 471.474, 290.992, 521.359, 297.01, 631.544, 294.695, 615.34, 297.473, 498.674)
uv = PackedVector2Array(285.231, 396.984, 311.252, 384.229, 343.905, 401.066, 341.354, 431.678, 333.701, 442.392, 327.578, 478.617, 337.782, 475.556, 340.843, 504.637, 326.047, 538.821, 327.578, 569.433, 349.517, 602.086, 382.17, 608.719, 391.354, 649.535, 403.088, 657.698, 406.66, 688.821, 397.476, 693.413, 250.027, 690.352, 247.476, 660.25, 252.068, 657.188, 247.986, 629.127, 254.619, 613.821, 254.619, 509.229, 281.66, 471.474, 290.992, 521.359, 297.01, 631.544, 294.695, 615.34, 297.473, 498.674)
polygons = [PackedInt32Array(23, 21, 20, 25, 9, 8), PackedInt32Array(25, 24, 10, 9), PackedInt32Array(20, 25, 24, 19), PackedInt32Array(26, 23, 8, 7), PackedInt32Array(22, 26, 23, 21), PackedInt32Array(7, 6, 5, 4, 3, 2, 1, 0, 22, 26), PackedInt32Array(19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 24)]
bones = ["hip", PackedFloat32Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "hip/chest", PackedFloat32Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "hip/chest/head", PackedFloat32Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "hip/chest/head/jaw", PackedFloat32Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "hip/chest/arm_right", PackedFloat32Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "hip/chest/arm_right/hand_right", PackedFloat32Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "hip/chest/arm_left", PackedFloat32Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "hip/chest/arm_left/hand_left", PackedFloat32Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "hip/leg_left", PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1), "hip/leg_left/calf_left", PackedFloat32Array(0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1), "hip/leg_left/calf_left/foot_left", PackedFloat32Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0), "hip/leg_right", PackedFloat32Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "hip/leg_right/leg_right2", PackedFloat32Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "hip/leg_right/leg_right2/leg_right3", PackedFloat32Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)]
internal_vertex_count = 4
[node name="Body" type="Polygon2D" parent="Gobot"]
position = Vector2(-213, 183)
texture = ExtResource("1_vmu55")
polygon = PackedVector2Array(454, 19, 483, 39, 487, 82, 521, 157, 524, 194, 509.272, 215.601, 494, 238, 475, 250, 476, 260, 493, 276, 488, 312, 462, 339, 422, 348, 367, 331, 346, 297, 349, 262, 375, 251, 372, 236, 350, 205, 340, 135, 357, 85, 384, 78, 393, 37, 427, 18)
uv = PackedVector2Array(454, 19, 483, 39, 487, 82, 521, 157, 524, 194, 494, 238, 475, 250, 476, 260, 493, 276, 488, 312, 462, 339, 422, 348, 367, 331, 346, 297, 349, 262, 375, 251, 372, 236, 350, 205, 340, 135, 357, 85, 384, 78, 393, 37, 427, 18)
[node name="leg_right" type="Polygon2D" parent="Gobot"]
position = Vector2(59, 63)
texture = ExtResource("1_vmu55")
polygon = PackedVector2Array(89.832, 385.034, 117.043, 400.68, 119.084, 426.531, 108.88, 441.497, 108.88, 463.265, 103.437, 476.871, 115.002, 472.789, 119.084, 508.843, 104.798, 537.415, 105.478, 559.864, 125.886, 593.197, 155.818, 602.041, 166.022, 617.007, 168.063, 643.537, 182.349, 653.061, 183.029, 676.19, 174.186, 685.714, 29.2878, 683.673, 19.7639, 674.83, 25.8864, 653.061, 30.6483, 604.762, 32.6891, 510.884, 61.2605, 470.068, 63.3014, 399.32)
uv = PackedVector2Array(89.832, 385.034, 117.043, 400.68, 119.084, 426.531, 108.88, 441.497, 108.88, 463.265, 103.437, 476.871, 115.002, 472.789, 119.084, 508.843, 104.798, 537.415, 105.478, 559.864, 125.886, 593.197, 155.818, 602.041, 166.022, 617.007, 168.063, 643.537, 182.349, 653.061, 183.029, 676.19, 174.186, 685.714, 29.2878, 683.673, 19.7639, 674.83, 25.8864, 653.061, 30.6483, 604.762, 32.6891, 510.884, 61.2605, 470.068, 63.3014, 399.32)
[node name="arm_right" type="Polygon2D" parent="Gobot"]
position = Vector2(53, 227)
texture = ExtResource("1_vmu55")
polygon = PackedVector2Array(80, 13, 141, 46, 98, 181, 139, 320, 122, 354, 62, 365, 26, 311, 14, 229, 32, 192, 21, 120, 34, 25)
uv = PackedVector2Array(80, 13, 141, 46, 98, 181, 139, 320, 122, 354, 62, 365, 26, 311, 14, 229, 32, 192, 21, 120, 34, 25)
[node name="head" type="Polygon2D" parent="Gobot"]
position = Vector2(-427, -344)
texture = ExtResource("1_vmu55")
polygon = PackedVector2Array(481.482, 378.14, 484.033, 449.058, 495.767, 494.466, 537.094, 496.507, 544.747, 525.079, 667.196, 533.242, 677.91, 506.711, 713.624, 511.303, 721.278, 521.507, 765.155, 517.426, 772.808, 505.181, 800.869, 503.65, 807.502, 489.364, 809.033, 380.691, 801.89, 361.303, 813.624, 340.895, 784.033, 294.466, 761.073, 297.017, 763.114, 272.528, 711.073, 252.119, 663.624, 255.691, 659.543, 269.977, 643.216, 249.568, 620.767, 247.017, 554.441, 282.221, 565.155, 316.405, 546.788, 327.119, 510.053, 328.14)
uv = PackedVector2Array(481.482, 378.14, 484.033, 449.058, 495.767, 494.466, 537.094, 496.507, 544.747, 525.079, 667.196, 533.242, 677.91, 506.711, 713.624, 511.303, 721.278, 521.507, 765.155, 517.426, 772.808, 505.181, 800.869, 503.65, 807.502, 489.364, 809.033, 380.691, 801.89, 361.303, 813.624, 340.895, 784.033, 294.466, 761.073, 297.017, 763.114, 272.528, 711.073, 252.119, 663.624, 255.691, 659.543, 269.977, 643.216, 249.568, 620.767, 247.017, 554.441, 282.221, 565.155, 316.405, 546.788, 327.119, 510.053, 328.14)
[node name="jaw" type="Polygon2D" parent="Gobot"]
position = Vector2(-423, -438)
texture = ExtResource("1_vmu55")
polygon = PackedVector2Array(488.089, 572.317, 541.793, 575.404, 544.879, 600.712, 548.583, 574.169, 616.484, 574.169, 620.805, 585.898, 635.003, 585.898, 644.879, 571.083, 716.484, 572.317, 723.891, 582.194, 738.706, 582.811, 744.262, 571.083, 819.57, 561.823, 815.867, 613.058, 788.089, 657.503, 754.756, 674.169, 654.138, 688.984, 547.965, 680.959, 498.583, 643.922, 481.916, 605.651)
uv = PackedVector2Array(488.089, 572.317, 541.793, 575.404, 544.879, 600.712, 548.583, 574.169, 616.484, 574.169, 620.805, 585.898, 635.003, 585.898, 644.879, 571.083, 716.484, 572.317, 723.891, 582.194, 738.706, 582.811, 744.262, 571.083, 819.57, 561.823, 815.867, 613.058, 788.089, 657.503, 754.756, 674.169, 654.138, 688.984, 547.965, 680.959, 498.583, 643.922, 481.916, 605.651)
[node name="Skeleton2D" type="Skeleton2D" parent="."]
position = Vector2(157, 138)
[node name="hip" type="Bone2D" parent="Skeleton2D"]
position = Vector2(218, 493)
rest = Transform2D(1, 0, 0, 1, 218, 493)
[node name="chest" type="Bone2D" parent="Skeleton2D/hip"]
position = Vector2(1, -45)
rest = Transform2D(1, 0, 0, 1, 1, -45)
[node name="head" type="Bone2D" parent="Skeleton2D/hip/chest"]
position = Vector2(5, -185)
rest = Transform2D(1, 0, 0, 1, 5, -185)
[node name="jaw" type="Bone2D" parent="Skeleton2D/hip/chest/head"]
position = Vector2(-95, -64)
rest = Transform2D(1, 0, 0, 1, -95, -64)
auto_calculate_length_and_angle = false
length = 150.0
bone_angle = 0.0
[node name="arm_right" type="Bone2D" parent="Skeleton2D/hip/chest"]
position = Vector2(-95, -132)
rest = Transform2D(1, 0, 0, 1, -95, -132)
[node name="hand_right" type="Bone2D" parent="Skeleton2D/hip/chest/arm_right"]
position = Vector2(-5, 101)
rotation = 1.39626
rest = Transform2D(0.173648, 0.984808, -0.984808, 0.173648, -5, 101)
auto_calculate_length_and_angle = false
length = 120.0
bone_angle = 0.0
[node name="arm_left" type="Bone2D" parent="Skeleton2D/hip/chest"]
position = Vector2(78, -142)
rest = Transform2D(1, 0, 0, 1, 78, -142)
[node name="hand_left" type="Bone2D" parent="Skeleton2D/hip/chest/arm_left"]
position = Vector2(1, 99)
rest = Transform2D(1, 0, 0, 1, 1, 99)
auto_calculate_length_and_angle = false
length = 120.0
bone_angle = 70.0
[node name="leg_left" type="Bone2D" parent="Skeleton2D/hip"]
position = Vector2(55, -21)
rest = Transform2D(1, 0, 0, 1, 55, -21)
[node name="calf_left" type="Bone2D" parent="Skeleton2D/hip/leg_left"]
position = Vector2(-29, 98)
rest = Transform2D(1, 0, 0, 1, -29, 98)
[node name="foot_left" type="Bone2D" parent="Skeleton2D/hip/leg_left/calf_left"]
position = Vector2(20, 135)
rest = Transform2D(1, 0, 0, 1, 20, 135)
auto_calculate_length_and_angle = false
length = 60.0
bone_angle = 0.0
[node name="leg_right" type="Bone2D" parent="Skeleton2D/hip"]
position = Vector2(-69, -16)
rest = Transform2D(1, 0, 0, 1, -69, -16)
[node name="leg_right2" type="Bone2D" parent="Skeleton2D/hip/leg_right"]
position = Vector2(-20, 98)
rest = Transform2D(1, 0, 0, 1, -20, 98)
[node name="leg_right3" type="Bone2D" parent="Skeleton2D/hip/leg_right/leg_right2"]
position = Vector2(13, 133)
rest = Transform2D(1, 0, 0, 1, 13, 133)
auto_calculate_length_and_angle = false
length = 60.0
bone_angle = 0.0

BIN
Example/Tween/Texture/gBot_pieces.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 453 KiB

34
Example/Tween/Texture/gBot_pieces.png.import

@ -0,0 +1,34 @@ @@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cbq4j4svebp45"
path="res://.godot/imported/gBot_pieces.png-1c5266364ba54cfdb5b194e098160c14.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Example/Tween/Texture/gBot_pieces.png"
dest_files=["res://.godot/imported/gBot_pieces.png-1c5266364ba54cfdb5b194e098160c14.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

3
Example/UsingTest/Scene/TestEGFramework.tscn

@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
[ext_resource type="Script" path="res://Example/UsingTest/Script/EGSaveTest.cs" id="1_eij2h"]
[node name="TestEgFramework" type="Control"]
[node name="Test" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
@ -20,6 +20,7 @@ offset_right = 361.0 @@ -20,6 +20,7 @@ offset_right = 361.0
offset_bottom = 164.0
[node name="Button1" type="Button" parent="."]
visible = false
layout_mode = 0
offset_right = 50.0
offset_bottom = 50.0

175
Example/UsingTest/Script/EGSaveTest.cs

@ -1,20 +1,14 @@ @@ -1,20 +1,14 @@
using Godot;
using LiteDB;
using System;
using System.IO;
namespace EGFramework.Examples.Test{
public partial class EGSaveTest : Node,IEGFramework
{
public override void _Ready()
{
base._Ready();
this.EGSave().OpenUserPath();
// GD.Print(ProjectSettings.GlobalizePath("res://SaveData/Default.json"));
// GD.Print(ProjectSettings.GlobalizePath("user://SaveData/Default.json"));
// GD.Print(Path.GetDirectoryName(ProjectSettings.GlobalizePath("res://SaveData/Default.json")));
// TestLiteDB();
}
public override void _Ready()
{
base._Ready();
TestCode();
}
public void TestSqlite(){
// string result = this.EGSqlite().CreateTable<SqliteBackpackItem>();
@ -27,63 +21,84 @@ namespace EGFramework.Examples.Test{ @@ -27,63 +21,84 @@ namespace EGFramework.Examples.Test{
// var properties = typeof(SqliteBackpackItem).GetFields();
// Godot.GD.Print(properties.Count() + " Readed ");
}
public void TestCode(){
// this.EGSave().OpenUserPath();
// GD.Print(ProjectSettings.GlobalizePath("res://SaveData/Default.json"));
// GD.Print(ProjectSettings.GlobalizePath("user://SaveData/Default.json"));
// GD.Print(Path.GetDirectoryName(ProjectSettings.GlobalizePath("res://SaveData/Default.json")));
// string Path2 = "Data1.json".GetGodotResPath();
// this.EGSave().LoadObjectFile<EGJsonSave>(Path2);
// this.EGSave().SetObject(Path2,"Customer1",new Customer() { Name = "Andy" });
// this.EGSave().SetObject(Path2,"Customer3",new Customer() { Name = "Terry" });
// string CardPath1 = "Card1";
// FileAccess fileAccess = FileAccess.Open("res://SaveData/TestCsv.csv", FileAccess.ModeFlags.Read);
// GD.Print(fileAccess.GetAsText());
// FileAccess testJson = FileAccess.Open("res://TestJson.json", FileAccess.ModeFlags.Read);
// this.EGSave().ReadObject<EGJsonSave>("TestJson",testJson.GetAsText());
// Customer customer = this.EGSave().GetObject<Customer>("TestJson","Customer3");
// GD.Print("ReadName is "+customer.Name);
// FileAccess testCSV = FileAccess.Open("res://SaveData/TestCSV.json", FileAccess.ModeFlags.Read);
public void TestLiteDB(){
// 打开数据库 (如果不存在自动创建)
using(var db = new LiteDatabase("SaveData/MyData.db"))
{
// 获取一个集合 (如果不存在创建)
LiteCollection<Customer> col = (LiteCollection<Customer>)db.GetCollection<Customer>("customers");
GD.Print(col);
// // 创建新顾客实例
// var customer = new Customer
// {
// Id = 200,
// Name = "Alexander King",
// Phones = new string[] { "8000-0000", "9000-0000" },
// IsActive = true
// };
// // 插入新顾客文档 (Id 自增)
// for (int i = 0; i < 10000; i++)
// {
// customer.Id ++;
// col.Insert(customer);
// }
// // 更新集合中的一个文档
// customer.Name = "Joana Doe";
// col.Update(customer);
// // 使用文档的 Name 属性为文档建立索引
// col.EnsureIndex(x => x.Name);
// 使用 LINQ 查询文档
// var results = col.Find(x => x.Name.StartsWith("Al"));
// GD.Print("Find:"+results.Count());
// string ids = "";
// foreach(var item in results){
// ids += "["+item.Id.ToString()+"]";
// }
// GD.Print(ids);
// // 让我们创建在电话号码字段上创建一个索引 (使用表达式). 它是一个多键值索引
// //col.EnsureIndex(x => x.Phones, "$.Phones[*]");
// col.EnsureIndex(x => x.Phones);
// // 现在我们可以查询电话号码
// var r = col.FindOne(x => x.Phones.Contains("8888-5555"));\
// Test Other
// ILiteCollection<SqliteBackpackItem> col = db.GetCollection<SqliteBackpackItem>("SqliteBackpackItem");
// var item = new SqliteBackpackItem{
// ItemID = 10,
// ItemCount = 1,
// BackpackID = 1,
// };
// for (int i = 0; i < 100; i++)
// {
// col.Insert(item);
// }
// EGCsvSave csvSave = new EGCsvSave();
// csvSave.InitSaveFile("SaveData/TestCsv.csv");
// Customer testData = csvSave.GetData<Customer>("",1);
// GD.Print("Name = "+testData.Name +" || ID = "+testData.Id);
// CustomerByte testData = new CustomerByte(){
// Id = 1008,
// Name = "AddDataDefault",
// IsActive = true
// };
// csvSave.SetData("",testData,2)
string Path1 = "SaveData/TestCsv.csv".GetGodotResPath();
this.EGSave().LoadDataFile<EGCsvSave>(Path1);
IEnumerable<Customer> allResult = this.EGSave().FindData<Customer>(Path1,"",cus=>cus.Id==0);
foreach(Customer customer in allResult){
GD.Print(customer.Id +"|" + customer.Name);
}
// this.EGSave().SetData(Path1,"Customer1",new Customer() { Name = "Andy" },9);
// IEnumerable<Customer> allResult = this.EGSave().GetAllData<Customer>(Path1,"");
// foreach(Customer customer in allResult){
// GD.Print(customer.Id +"|" + customer.Name);
// }
// Customer customer1 = this.EGSave().GetData<Customer>(Path1,"",0);
// GD.Print(customer1.Id +"|" + customer1.Name);
// FileAccess testCsv = FileAccess.Open("res://SaveData/TestCsv.csv", FileAccess.ModeFlags.Read);
// this.EGSave().ReadData<EGCsvSave>("TestCsv",testCsv.GetAsText());
// this.EGSave().LoadObjectFile<EGByteSave>("SaveData/testDat.dat");
// // this.EGSave().SetObject("SaveData/testDat.dat","",testData);
// CustomerByte testDat = this.EGSave().GetObject<CustomerByte>("SaveData/testDat.dat","");
// GD.Print(testDat.Id);
// System.Linq.Expressions.Expression<Func<Customer, bool>> expr = i => i.Name == "Creature";
// IEnumerable<Customer> linqResult = csvSave.FindData<Customer>("",expr);
// GD.Print("Find result " + linqResult.Count());
// foreach(Customer customer in linqResult){
// GD.Print(customer.Id);
// }
// GD.Print(typeof(Customer));
// Type type = typeof(Customer);
// foreach(PropertyInfo property in type.GetProperties()){
// GD.Print(property.Name);
// CsvParamAttribute csvParam = property.GetCustomAttribute<CsvParamAttribute>();
// if(csvParam != null){
// GD.Print("["+csvParam._name+"]");
// }
// }
// foreach(FieldInfo property in type.GetFields()){
// GD.Print(property.Name);
// }
}
}
public struct SqliteBackpackItem{
public int Id { get; set; }
@ -94,9 +109,39 @@ namespace EGFramework.Examples.Test{ @@ -94,9 +109,39 @@ namespace EGFramework.Examples.Test{
public class Customer
{
[CsvParam("ID")]
public int Id { get; set; }
[CsvParam("Name")]
public string Name { get; set; }
public string[] Phones { get; set; }
[CsvParam("是否启用")]
public bool IsActive { get; set; }
}
public class CustomerByte : Customer, IResponse, IRequest
{
public byte[] ToProtocolByteData()
{
byte[] data = new byte[0];
data = data.Concat(((uint)Id).ToBytesLittleEndian()).ToArray();
return data;
}
public string ToProtocolData()
{
return "";
}
public bool TrySetData(string protocolData, byte[] protocolBytes)
{
if(protocolBytes != null && protocolBytes.Length >= 4){
Id = (int)protocolBytes.ToUINTLittleEndian();
return true;
}else{
return false;
}
}
}
}

386
addons/EGFramework/Manual/EGSave.md

@ -0,0 +1,386 @@ @@ -0,0 +1,386 @@
# SaveTools(EGSave)模块使用说明
---
注:下述`数据`无特殊声明默认指代:对象的集合。
SaveTools使用了两种数据格式,一种是表式存储,一种是对象存储,统一使用key-value方式存储数据,通过唯一key值锁定对应的数据。如果是只读数据,则需指定唯一标识key,读写数据,这个key值则为文件路径(唯一)。
在使用该库时,一定要保证该数据被加载。可以重复读取数据文件,如果外部进行了修改,新读取的数据会覆盖掉原来的数据。使用流程:加载数据->读写数据或者其他操作
需要在对应Godot的Node类下实现接口 `IEGFramework`
下面演示一个打开Res文件夹的示例:
```csharp
public partial class EGSaveTest : Node,IEGFramework{
public override void _Ready()
{
base._Ready();
this.EGSave().OpenResPath();
}
}
```
数据工具类开发状态如下:
只读&非只读数据:
- [x] CSV
- [x] Json
- [ ] XML
- [ ] etc...
非只读数据:
- [x] LiteDB
- [x] Byte
- [ ] Sqlite
- [ ] Other DataBase
- [ ] etc...
# API参考
---
# EGSave 使用说明
## 属性
暂无
## 方法
| 方法名 | 简介 |
| -------------------------------------------------------------------------------------------------------- | ---------------- |
| void LoadDataFile<TSaveData>(string path) | 加载数据文件(需要路径) |
| void ReadData<TReadOnlyData>(string key,string data) | 读取数据(需获取字符串原始值) |
| void ReadData<TReadOnlyData>(string key,byte[] data) | 读取数据(需获取字节流原始值) |
| void LoadObjectFile<TSaveObject>(string path) | 加载对象文件(需要路径) |
| void ReadObject<TReadOnlyObject>(string key,string data) | 读取对象(需获取字符串原始值) |
| void ReadObject<TReadOnlyObject>(string key,byte[] data) | 读取对象(需获取字节流原始值) |
| void Unload(string keyOrPath) | 卸载数据 |
| List<string> GetKeys() | 获取所有加载过的key或者路径值 |
| void SetObject<TObject>(string path,string objectKey,TObject obj) | 设置对象(写入文件) |
| TObject GetObject<TObject>(string path,string key) | 获取对象(读取文件) |
| void SetData<TData>(string path,string dataKey,TData data,int id) | 设置数据(写入文件) |
| TData GetData<TData>(string keyOrPath,string key,int id) | 获取单个数据(读取文件) |
| IEnumerable<TData> GetAllData<TData>(string keyOrPath,string key) | 获取全部数据(读取文件) |
| IEnumerable<TData> FindData<TData>(string keyOrPath,string key,Expression<Func<TData, bool>> expression) | 查找符合条件的对应数据 |
| OpenResPath() | 打开Res文件目录 |
| OpenUserPath() | 打开User文件目录 |
## 扩展方法
| 方法名 | 简介 |
| ------------------------------------------- | -------------- |
| this.EGSave() | 使用存储模块 |
| [string].GetGodotResPath(this string path) | 转为res文件下的相对路径 |
| [string].GetGodotUserPath(this string path) | 转为User文件下的相对路径 |
## 属性说明
暂无
## 方法说明
### LoadDataFile<T>(string path)
从路径中加载数据文件,因为是可读写,所以必须指定对应的文件路径位置,如果不存在该文件则会新建对应数据文件。
- T:指代任何一个数据存储工具类
- Path:文件的相对路径&绝对路径
```csharp
string Path1 = "Data/Test1.csv".GetGodotResPath();
this.EGSave().LoadDataFile<EGCsvSave>(Path1);
```
### ReadData<T>(string key,string data)
### ReadData<T>(string key,byte[] data)
从文本数据中读取数据,并且赋予对应的key值方便索引到该数据位置上。由于是只读数据,不会创建文件,也不会存在路径信息。
- T:指代任何一个数据工具类
- key:数据的索引,用于定位数据内容。
- data:原始数据,字符串格式或者byte[]字节流。
```csharp
FileAccess testCsv = FileAccess.Open("res://TestCsv.csv", FileAccess.ModeFlags.Read);
this.EGSave().ReadData<EGCsvSave>("TestCsv",testCsv.GetAsText());
```
### LoadObjectFile<T>(string path)
从路径中加载对象文件,因为是可读写,所以必须指定对应的文件路径位置,如果不存在该文件则会新建对应数据文件。
- T:指代任何一个对象存储工具类
- Path:文件的相对路径&绝对路径
```csharp
string Path2 = "Data1.json".GetGodotResPath();
this.EGSave().LoadObjectFile<EGJsonSave>(Path2);
```
### ReadObject<T>(string key,string data)
### ReadObject<T>(string key,byte[] data)
从文本数据中读取对象,并且赋予对应的key值方便索引到该数据位置上。由于是只读对象,不会创建文件,也不会存在路径信息。
- T:指代任何一个对象工具类
- key:对象的索引,用于定位对象内容。
- data:原始数据,字符串格式或者byte[]字节流。
```csharp
FileAccess testJson = FileAccess.Open("res://TestJson.json", FileAccess.ModeFlags.Read);
this.EGSave().ReadObject<EGJsonSave>("TestJson",testJson.GetAsText());
```
### Unload(string keyOrPath)
卸载已读取或者加载的数据,并删除对应key值下的数据,此方法执行后,不再能获取对应的数据,也不能写入文件,需要重新加载。
- keyOrPath:key值或者路径值
```csharp
this.EGSave().Unload("TestCsv");
```
### List<string> GetKeys()
获取所有加载过的key值或者路径值。
```csharp
List<string> keys = this.EGSave().GetKeys();
```
### SetObject<T>(string path,string objectKey,TObject obj)
把对象写入文件中。需要先加载再写入。
- T:指代任何一个对象工具类
- path:对象文件的路径值
- objectKey:对象文件的key值
- obj:要写入的对象
```csharp
public class Customer
{
[CsvParam("ID")]
public int Id { get; set; }
[CsvParam("Name")]
public string Name { get; set; }
public string[] Phones { get; set; }
[CsvParam("是否启用")]
public bool IsActive { get; set; }
}
public partial class EGSaveTest : Node,IEGFramework{
public override void _Ready()
{
string Path2 = "Data1.json".GetGodotResPath();
this.EGSave().LoadObjectFile<EGJsonSave>(Path2);
        this.EGSave().SetObject(Path2,"Customer1",new Customer()
            { Name = "Andy" });
}
}
```
### TObject GetObject<T>(string path,string key)
从文件中获取对象,同样需要先加载再获取。
- TObject:要获取的对象类型。
- path:对象文件的路径值
- key:对象的key值
```csharp
string Path2 = "Data1.json".GetGodotResPath();
this.EGSave().LoadObjectFile<EGJsonSave>(Path2);
Customer customer = this.EGSave().
GetObject<Customer>("Data1.json","Customer1");
```
### SetData<T>(string path,string dataKey,TData data,int id)
把一条数据写入文件中的指定位置。特别注意,如果写入的位置超出了文件中的数据量,则会进行追加数据,否则覆盖对应位置的数据。
- T:指代任何一个数据工具类
- path:数据文件的路径值
- dataKey:数据文件的key值
- data:要写入的数据
- id:指代第x条数据
```csharp
string Path2 = "TestCsv.csv".GetGodotResPath();
this.EGSave().LoadObjectFile<EGJsonSave>(Path2);
this.EGSave().SetData(Path1,"Customer1",
    new Customer() { Name = "Andy" },9);
```
### T GetData<T>(string keyOrPath,string key,int id)
获取文件中特定key值的列表里,第x条数据。
- keyOrPath:文件的路径,或者读取后存储的key值。
- key:文件中的数据列表对应的key值。
- id:第【id】条
```csharp
string Path1 = "SaveData/TestCsv.csv".GetGodotResPath();
this.EGSave().LoadDataFile<EGCsvSave>(Path1);
Customer customer1 = this.EGSave().GetData<Customer>(Path1,"",0);
GD.Print(customer1.Id +"|" + customer1.Name);
```
### IEnumerable<T> GetAllData<T>(string keyOrPath,string key)
获取文件中特定key值的全部数据。
- keyOrPath:文件的路径,或者读取后存储的key值。
- key:文件中的数据列表对应的key值。
```csharp
string Path1 = "SaveData/TestCsv.csv".GetGodotResPath();
this.EGSave().LoadDataFile<EGCsvSave>(Path1);
IEnumerable<Customer> allResult = this.EGSave().GetAllData<Customer>(Path1,"");
foreach(Customer customer in allResult){
GD.Print(customer.Id +"|" + customer.Name);
}
```
### IEnumerable<T> FindData<T> (string keyOrPath,string key,Expression<Func<T, bool>> expression)
查找文件中特定key值的全部符合条件的数据。
- keyOrPath:文件的路径,或者读取后存储的key值。
- key:文件中的数据列表对应的key值。
- Expression : 查询条件
```csharp
string Path1 = "SaveData/TestCsv.csv".GetGodotResPath();
this.EGSave().LoadDataFile<EGCsvSave>(Path1);
IEnumerable<Customer> findResult = this.EGSave().FindData<Customer>(Path1,"",cus=>cus.Id==0);
foreach(Customer customer in findResult){
GD.Print(customer.Id +"|" + customer.Name);
}
```
### OpenResPath()
打开godot对应的res文件夹
### OpenUserPath()
打开godot对应的user文件夹
# IEGSave 接口说明与扩展建议
---
只读&非只读数据说明:
只读数据不实现写数据功能,非只读需要实现写数据功能。
正常数据通过Path加载,只读数据则是通过string加载,无法对其中Path进行写入操作。
| 接口名称 | 接口简介 |
| --------------------- | ------ |
| IEGSave | 读写数据加载 |
| IEGSaveReadOnly | 只读数据加载 |
| IEGSaveObjectReadOnly | 只读对象 |
| IEGSaveObject | 读写对象 |
| IEGSaveDataReadOnly | 只读数据 |
| IEGSaveData | 读写数据 |
## IEGSave
### 描述
通用的存储数据加载接口,通过Path加载文件的数据。
### 方法说明
### void InitSaveFile(string path)
> 通过文件路径加载存储文件
## IEGSaveReadOnly
只读文件的数据加载接口,通过字符串或者字节流加载成对应的数据对象。
### void InitReadOnly(string data);
> 通过字符串加载文件内容,需要先从文本文件中读取,请求服务或者其他方式获取内容。
### void InitReadOnly(byte[] data);
> 通过字节流加载文件内容,需要先从字节流文件中读取,请求服务或者其他方式获取内容。
## IEGSaveObjectReadOnly
只读对象文件的获取数据接口
### T GetObject<T>(string objectKey) where T: new();
> 通过键获取对应的对象,如果是单个对象文件的话,则传空字符串即可。
## IEGSaveObject : IEGSaveObjectReadOnly
对象文件的获取&写入数据接口
### void SetObject<T>(string objectKey,T obj);
> 将key值与key对应的对象写入到该文件下。
## IEGSaveDataReadOnly
只读数据文件的获取数据接口
### T GetData<T>(string dataKey,object id) where T : new();
> 用于获取指定条目的数据对象。
### IEnumerable<T> GetAll<T>(string dataKey) where T : new();
> 用于获取key值下的所有列表数据
### IEnumerable<T> FindData<T>(string dataKey,Expression<Func<T, bool>> expression) where T : new();
> 用于查找key值下的所有满足条件的列表数据
## IEGSaveData
数据文件的获取&写入数据接口
### void SetData<TData>(string dataKey,TData data,object id);
> 将key值与key对应的对象的写入到该文件对应的位置(id)下,如果存在数据则进行覆盖。

76
addons/EGFramework/Module/SaveTools/EGByteSave.cs

@ -3,47 +3,77 @@ using System.Collections.Generic; @@ -3,47 +3,77 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Runtime.Serialization.Formatters.Binary;
using Godot;
using System.IO;
namespace EGFramework
{
public class EGByteSave : EGModule, IEGSave,IEGSaveObject
[Obsolete("this idea can be replaced by EGFileStream")]
public class EGByteSave : IEGSave,IEGSaveObject
{
public void SaveToFile(string content)
{
using var file = FileAccess.Open("user://save_game.dat", FileAccess.ModeFlags.Write);
Variant hp = 10;
file.StoreVar(hp);
Variant pos = new Vector2(100,100);
file.StoreVar(pos);
}
public Encoding StringEncoding { set; get; } = Encoding.ASCII;
private string DefaultPath { set; get; }
private byte[] Data { get; set; }
public Variant LoadFromFile()
{
using var file = FileAccess.Open("user://save_game.dat", FileAccess.ModeFlags.Read);
Variant content = file.GetVar();
Variant pos = file.GetVar();
return pos;
public void ReadDataBlock(string path){
DefaultPath = path;
try
{
FileStream fileStream = new FileStream(path,FileMode.OpenOrCreate);
byte[] buffer = new byte[fileStream.Length];
fileStream.Read(buffer, 0, (int)fileStream.Length);
fileStream.Close();
fileStream.Dispose();
Data = buffer;
}
catch (System.Exception e)
{
Godot.GD.Print("e:" + e);
throw;
}
}
public override void Init()
{
public void WriteDataBlock(string path){
try
{
FileStream fileStream = File.Create(path);
fileStream.Write(Data,0,Data.Length);
fileStream.Close();
fileStream.Dispose();
}
catch (System.Exception e)
{
Godot.GD.Print("e:" + e);
throw;
}
}
public void InitSaveFile(string path)
{
//throw new NotImplementedException();
ReadDataBlock(path);
}
public void SetObject<TObject>(string objectKey , TObject obj)
{
throw new NotImplementedException();
if(typeof(TObject).GetInterfaces().Contains(typeof(IRequest))){
Data = ((IRequest)obj).ToProtocolByteData();
}else{
throw new Exception("This byte class cannot be serialized! you should implement IRequest first!");
}
WriteDataBlock(DefaultPath);
}
public TObject GetObject<TObject>(string objectKey) where TObject : new()
{
throw new NotImplementedException();
if(typeof(TObject).GetInterfaces().Contains(typeof(IResponse))){
TObject result = new TObject();
((IResponse)result).TrySetData(StringEncoding.GetString(Data),Data);
return result;
}else{
throw new Exception("This byte class cannot be serialized! you should implement IRequest first!");
}
}
}
public interface IEGByteInit{
void Init(byte[] data);
}
}

15
addons/EGFramework/Module/SaveTools/EGCsv.cs

@ -1,15 +0,0 @@ @@ -1,15 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace EGFramework
{
public class EGCsv : EGModule
{
public override void Init()
{
}
}
}

226
addons/EGFramework/Module/SaveTools/EGCsvSave.cs

@ -0,0 +1,226 @@ @@ -0,0 +1,226 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace EGFramework
{
public class EGCsvSave : IEGSaveData, IEGSave, IEGSaveReadOnly
{
public bool IsReadOnly { get; set; }
public Encoding StringEncoding { set; get; } = Encoding.UTF8;
private string DefaultPath { set; get; }
private List<string[]> CsvDataBlock { get; set; }
private Dictionary<string,int> CsvDataHeader = new Dictionary<string,int>();
public IOCContainer TypeDataContainer = new IOCContainer();
private string ReadText { set; get; }
public void InitSaveFile(string path)
{
ReadDataBlock(path);
}
public void InitReadOnly(string data)
{
ReadText = data;
if(ReadText != null || ReadText != ""){
CsvDataBlock = GetCSVDataBlockFromText(ReadText,out CsvDataHeader);
}
}
public void InitReadOnly(byte[] data)
{
ReadText = StringEncoding.GetString(data);
if(ReadText != null || ReadText != ""){
CsvDataBlock = GetCSVDataBlockFromText(ReadText,out CsvDataHeader);
}
}
public void ReadDataBlock(string path){
DefaultPath = path;
try
{
FileStream fileStream = new FileStream(path,FileMode.Open);
byte[] buffer = new byte[fileStream.Length];
fileStream.Read(buffer, 0, (int)fileStream.Length);
fileStream.Close();
fileStream.Dispose();
ReadText = StringEncoding.GetString(buffer);
}
catch (System.Exception e)
{
Godot.GD.Print("e:" + e);
throw;
}
if(ReadText != null || ReadText != ""){
CsvDataBlock = GetCSVDataBlockFromText(ReadText,out CsvDataHeader);
}
}
public void WriteDataBlock(string path){
try
{
FileStream fileStream = File.Create(path);
string writeText = "";
string headerText = "";
foreach(string headStr in CsvDataHeader.Keys){
headerText+=headStr + ",";
}
headerText = headerText.Remove(headerText.Length-1,1);
writeText = headerText + "\n";
foreach(string[] lineData in CsvDataBlock){
string lineText = "";
foreach(string singleData in lineData){
lineText += singleData + ",";
}
lineText = lineText.Remove(lineText.Length-1,1);
writeText += lineText + "\n";
}
writeText = writeText.Remove(writeText.Length-1,1);
byte[] data = StringEncoding.GetBytes(writeText);
fileStream.Write(data,0,data.Length);
fileStream.Close();
fileStream.Dispose();
}
catch (System.Exception e)
{
Godot.GD.Print("e:" + e);
throw;
}
}
public List<string[]> GetCSVDataBlockFromText(string text,out Dictionary<string,int> header){
List<string[]> csvBlock = new List<string[]>();
string[] lineData = text.Split('\n');
string[] headerStr = lineData[0].Split(',');
header = new Dictionary<string,int>();
for (int i = 0; i < headerStr.Length; i++)
{
header.Add(headerStr[i],i);
}
for (int lineID = 0; lineID < lineData.Length; lineID++)
{
if (lineID!=0){
csvBlock.Add(lineData[lineID].Split(','));
}
}
return csvBlock;
}
public string[] ReadLine(int id){
if(CsvDataBlock.Count()>0){
return CsvDataBlock[id];
}else{
return null;
}
}
public void WriteLine(string[] lineData){
CsvDataBlock.Add(lineData);
this.WriteDataBlock(DefaultPath);
}
public void SetData<TData>(string dataKey, TData data, object id)
{
if(IsReadOnly){
throw new Exception("This file is readonly! can't set any data to file.");
}
bool IsAdd = false;
int dataID = 0;
if(id.GetType()==typeof(int)){
dataID = (int)id;
}else if(int.TryParse(id.ToString() ,out dataID)){
throw new Exception("Id cannot be convert to int!");
}
if(dataID>=CsvDataBlock.Count() || dataID < 0){
IsAdd = true;
}
string[] csvSet = new string[CsvDataHeader.Keys.Count()];
foreach(PropertyInfo property in data.GetType().GetProperties()){
CsvParamAttribute csvParam = property.GetCustomAttribute<CsvParamAttribute>();
if(csvParam != null && CsvDataHeader.ContainsKey(csvParam._name)){
csvSet[CsvDataHeader[csvParam._name]] = property.GetValue(data).ToString();
}
}
if(IsAdd){
CsvDataBlock.Add(csvSet);
}else{
CsvDataBlock[dataID] = csvSet;
}
this.WriteDataBlock(DefaultPath);
}
public TData GetData<TData>(string dataKey, object id) where TData : new()
{
TData data = new TData();
int dataID = 0;
if(id.GetType()==typeof(int)){
dataID = (int)id;
}else if(int.TryParse(id.ToString() ,out dataID)){
throw new Exception("Id cannot be convert to int!");
}
if(dataID>=CsvDataBlock.Count()){
throw new IndexOutOfRangeException("Parameter index is out of range.");
}
foreach(PropertyInfo property in data.GetType().GetProperties()){
CsvParamAttribute csvParam = property.GetCustomAttribute<CsvParamAttribute>();
if(csvParam != null && CsvDataHeader.ContainsKey(csvParam._name)){
string valueStr = CsvDataBlock[dataID][CsvDataHeader[csvParam._name]];
if(property.PropertyType==typeof(string)){
property.SetValue(data,valueStr);
}else{
property.SetValue(data,Convert.ChangeType(valueStr,property.PropertyType));
}
}
}
return data;
}
public IEnumerable<TData> GetAll<TData>(string dataKey) where TData : new()
{
// throw new NotImplementedException();
List<TData> DataList = new List<TData>();
PropertyInfo[] properties = typeof(TData).GetProperties();
for (int dataID = 0; dataID < CsvDataBlock.Count(); dataID++){
TData data = new TData();
foreach(PropertyInfo property in properties){
CsvParamAttribute csvParam = property.GetCustomAttribute<CsvParamAttribute>();
if(csvParam != null && CsvDataHeader.ContainsKey(csvParam._name)){
string valueStr = CsvDataBlock[dataID][CsvDataHeader[csvParam._name]];
if(property.PropertyType==typeof(string)){
property.SetValue(data,valueStr);
}else{
property.SetValue(data,Convert.ChangeType(valueStr,property.PropertyType));
}
}
}
DataList.Add(data);
}
TypeDataContainer.Register(DataList);
return DataList;
}
public IEnumerable<TData> FindData<TData>(string dataKey, Expression<Func<TData, bool>> expression) where TData : new()
{
List<TData> sourceList;
if(TypeDataContainer.self.ContainsKey(typeof(List<TData>))){
sourceList = TypeDataContainer.Get<List<TData>>();
}else{
sourceList = (List<TData>)GetAll<TData>(dataKey);
}
return sourceList.Where(expression.Compile());
}
}
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
public class CsvParamAttribute: Attribute{
public string _name { set; get; }
public CsvParamAttribute(string name){
this._name = name;
}
}
}

32
addons/EGFramework/Module/SaveTools/EGJsonSave.cs

@ -8,8 +8,10 @@ using Newtonsoft.Json.Linq; @@ -8,8 +8,10 @@ using Newtonsoft.Json.Linq;
namespace EGFramework
{
public class EGJsonSave : IEGSave,IEGSaveObject
public class EGJsonSave : IEGSave,IEGSaveReadOnly,IEGSaveObject
{
public bool IsReadOnly { get; set; }
public Encoding StringEncoding { set; get; } = Encoding.UTF8;
private string DefaultPath { set; get; }
private JObject _SaveObject;
private JObject SaveObject{
@ -28,7 +30,7 @@ namespace EGFramework @@ -28,7 +30,7 @@ namespace EGFramework
{
DefaultPath = path;
if(!File.Exists(path)){
if (!Directory.Exists(DefaultPath))
if (!Directory.Exists(Path.GetDirectoryName(DefaultPath)))
{
Directory.CreateDirectory(Path.GetDirectoryName(DefaultPath));
File.WriteAllText(DefaultPath,"{}");
@ -42,12 +44,27 @@ namespace EGFramework @@ -42,12 +44,27 @@ namespace EGFramework
}
}
public void InitReadOnly(string data)
{
_SaveObject = JObject.Parse(data);
IsReadOnly = true;
}
public void InitReadOnly(byte[] data)
{
_SaveObject = JObject.Parse(StringEncoding.GetString(data));
IsReadOnly = true;
}
public void SetObject<TObject>(string objectKey,TObject obj)
{
if(SaveObject.ContainsKey(typeof(TObject).ToString())){
SaveObject[typeof(TObject).ToString()] = JToken.FromObject(obj);
if(IsReadOnly){
throw new Exception("This file is readonly! can't set any object to file.");
}
if(SaveObject.ContainsKey(objectKey)){
SaveObject[objectKey] = JToken.FromObject(obj);
}else{
SaveObject.Add(typeof(TObject).ToString(),JToken.FromObject(obj));
SaveObject.Add(objectKey,JToken.FromObject(obj));
}
File.WriteAllText(DefaultPath,JsonConvert.SerializeObject(SaveObject,Formatting.Indented));
}
@ -57,11 +74,12 @@ namespace EGFramework @@ -57,11 +74,12 @@ namespace EGFramework
/// </summary>
public TObject GetObject<TObject>(string objectKey) where TObject : new()
{
if(!SaveObject.ContainsKey(typeof(TObject).ToString())){
if(!SaveObject.ContainsKey(objectKey)){
throw new Exception("Key not found!");
}
TObject data = SaveObject[typeof(TObject).ToString()].ToObject<TObject>();
TObject data = SaveObject[objectKey].ToObject<TObject>();
return data;
}
}
}

16
addons/EGFramework/Module/SaveTools/EGLiteDB.cs

@ -1,16 +0,0 @@ @@ -1,16 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using LiteDB;
namespace EGFramework
{
public class EGLiteDB : EGModule
{
public override void Init()
{
// throw new NotImplementedException();
}
}
}

65
addons/EGFramework/Module/SaveTools/EGLiteDBSave.cs

@ -0,0 +1,65 @@ @@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using LiteDB;
namespace EGFramework
{
public class EGLiteDBSave : IEGSave,IEGSaveData
{
private string DefaultPath { set; get; }
private LiteDatabase _Database { set; get; }
private LiteDatabase Database{
get {
if(_Database == null){
InitSaveFile(DefaultPath);
}
return _Database;
}
}
public void InitSaveFile(string path)
{
DefaultPath = path;
if (!Directory.Exists(Path.GetDirectoryName(DefaultPath)))
{
Directory.CreateDirectory(Path.GetDirectoryName(DefaultPath));
}
// Default is "SaveData/DefaultLiteDBData.db"
_Database = new LiteDatabase(path);
}
public TData GetData<TData>(string dataKey, object id) where TData : new()
{
LiteCollection<TData> collection = (LiteCollection<TData>)Database.GetCollection<TData>(dataKey);
TData result = collection.FindById((BsonValue)id);
return result;
}
public void SetData<TData>(string dataKey, TData data, object id)
{
LiteCollection<TData> collection = (LiteCollection<TData>)Database.GetCollection<TData>(dataKey);
if(collection.FindById((BsonValue)id)==null){
collection.Insert((BsonValue)id, data);
}
collection.Update(data);
}
public IEnumerable<TData> GetAll<TData>(string dataKey) where TData : new()
{
LiteCollection<TData> collection = (LiteCollection<TData>)Database.GetCollection<TData>(dataKey);
return collection.FindAll();
}
public IEnumerable<TData> FindData<TData>(string dataKey, Expression<Func<TData, bool>> expression) where TData : new()
{
LiteCollection<TData> collection = (LiteCollection<TData>)Database.GetCollection<TData>(dataKey);
return collection.Find(expression);
}
}
}

176
addons/EGFramework/Module/SaveTools/EGSave.cs

@ -27,48 +27,172 @@ namespace EGFramework @@ -27,48 +27,172 @@ namespace EGFramework
private Dictionary<string,IEGSaveData> DataBaseFiles = new Dictionary<string,IEGSaveData>();
private Dictionary<string,IEGSaveObject> ObjectFiles = new Dictionary<string,IEGSaveObject>();
private Dictionary<string,IEGSaveDataReadOnly> DataBaseReadOnly = new Dictionary<string, IEGSaveDataReadOnly>();
private Dictionary<string,IEGSaveObjectReadOnly> ObjectReadOnly = new Dictionary<string,IEGSaveObjectReadOnly>();
public EGSave() {}
public override void Init()
{
LoadObjectFile("Default/SaveData.json".GetGodotUserPath(),TypeEGSave.Json);
LoadObjectFile<EGJsonSave>("SaveData/DefaultJsonSave.json".GetGodotResPath());
}
public void LoadDataFile<TSaveData>(string path) where TSaveData:IEGSaveData,IEGSave,new(){
TSaveData saveData = new TSaveData();
saveData.InitSaveFile(path);
if(!DataBaseFiles.ContainsKey(path)){
DataBaseFiles.Add(path,saveData);
}else{
DataBaseFiles[path] = saveData;
}
}
public void ReadData<TReadOnlyData>(string key,string data) where TReadOnlyData:IEGSaveDataReadOnly,IEGSaveReadOnly,new(){
TReadOnlyData readOnlyData = new TReadOnlyData();
readOnlyData.InitReadOnly(data);
if(!DataBaseReadOnly.ContainsKey(key)){
DataBaseReadOnly.Add(key,readOnlyData);
}else{
DataBaseReadOnly[key] = readOnlyData;
}
}
public void ReadData<TReadOnlyData>(string key,byte[] data) where TReadOnlyData:IEGSaveDataReadOnly,IEGSaveReadOnly,new(){
TReadOnlyData readOnlyData = new TReadOnlyData();
readOnlyData.InitReadOnly(data);
if(!DataBaseReadOnly.ContainsKey(key)){
DataBaseReadOnly.Add(key,readOnlyData);
}else{
DataBaseReadOnly[key] = readOnlyData;
}
}
public void LoadDataFile(string path,TypeDBSave type){
switch(type){
case TypeDBSave.Csv:
break;
default:
break;
public void LoadObjectFile<TSaveObject>(string path) where TSaveObject:IEGSaveObject,IEGSave,new(){
TSaveObject saveObject = new TSaveObject();
saveObject.InitSaveFile(path);
if(!ObjectFiles.ContainsKey(path)){
ObjectFiles.Add(path, saveObject);
}else{
ObjectFiles[path] = saveObject;
}
}
public void LoadObjectFile(string path,TypeEGSave type){
switch(type){
case TypeEGSave.Json:
EGJsonSave newJsonFile = new EGJsonSave();
newJsonFile.InitSaveFile(path);
ObjectFiles.Add(path, newJsonFile);
break;
default:
break;
public void ReadObject<TReadOnlyObject>(string key,string data) where TReadOnlyObject:IEGSaveObjectReadOnly,IEGSaveReadOnly,new(){
TReadOnlyObject readOnlyObject = new TReadOnlyObject();
readOnlyObject.InitReadOnly(data);
if(!ObjectReadOnly.ContainsKey(key)){
ObjectReadOnly.Add(key,readOnlyObject);
}else{
ObjectReadOnly[key] = readOnlyObject;
}
}
public void ReadObject<TReadOnlyObject>(string key,byte[] data) where TReadOnlyObject:IEGSaveObjectReadOnly,IEGSaveReadOnly,new(){
TReadOnlyObject readOnlyObject = new TReadOnlyObject();
readOnlyObject.InitReadOnly(data);
if(!ObjectReadOnly.ContainsKey(key)){
ObjectReadOnly.Add(key,readOnlyObject);
}else{
ObjectReadOnly[key] = readOnlyObject;
}
}
public void Unload(string keyOrPath){
if(DataBaseReadOnly.ContainsKey(keyOrPath)){
DataBaseReadOnly.Remove(keyOrPath);
}else if(ObjectReadOnly.ContainsKey(keyOrPath)){
ObjectReadOnly.Remove(keyOrPath);
}else if(DataBaseFiles.ContainsKey(keyOrPath)){
DataBaseFiles.Remove(keyOrPath);
}else if(ObjectFiles.ContainsKey(keyOrPath)){
ObjectFiles.Remove(keyOrPath);
}else{
throw new Exception("Key is not found!");
}
}
public List<string> GetKeys(){
List<string> keys = new List<string>();
foreach(string key in DataBaseReadOnly.Keys){
keys.Add(key);
}
foreach(string key in ObjectReadOnly.Keys){
keys.Add(key);
}
foreach(string key in DataBaseFiles.Keys){
keys.Add(key);
}
foreach(string key in ObjectFiles.Keys){
keys.Add(key);
}
return keys;
}
public void SetObject<TObject>(string path,string objectKey,TObject obj){
ObjectFiles[path].SetObject(objectKey,obj);
if(ObjectFiles.ContainsKey(path)){
ObjectFiles[path].SetObject(objectKey,obj);
}else{
throw new Exception("File not loaded, you should use LoadObjectFile(key) first.");
}
}
public TObject GetObject<TObject>(string path,string key) where TObject : new(){
return ObjectFiles[path].GetObject<TObject>(key);
if(ObjectFiles.ContainsKey(path)){
return ObjectFiles[path].GetObject<TObject>(key);
}else if(ObjectReadOnly.ContainsKey(path)){
return ObjectReadOnly[path].GetObject<TObject>(key);
}else{
throw new Exception("File not loaded, you should use LoadObjectFile(key) or ReadObject(key) first.");
}
}
public void SetData<TData>(string path,string dataKey,TData data,int id){
if(DataBaseFiles.ContainsKey(path)){
DataBaseFiles[path].SetData(dataKey,data,id);
}else{
throw new Exception("File not loaded, you should use LoadDataFile(path) first.");
}
}
public TData GetData<TData>(string keyOrPath,string key,int id) where TData : new(){
if(DataBaseFiles.ContainsKey(keyOrPath)){
return DataBaseFiles[keyOrPath].GetData<TData>(key,id);
}else if(DataBaseReadOnly.ContainsKey(keyOrPath)){
return DataBaseReadOnly[keyOrPath].GetData<TData>(key,id);
}else{
throw new Exception("File not loaded, you should use LoadDataFile(key) or ReadData(key,data) first.");
}
}
public IEnumerable<TData> GetAllData<TData>(string keyOrPath,string key) where TData : new(){
if(DataBaseFiles.ContainsKey(keyOrPath)){
return DataBaseFiles[keyOrPath].GetAll<TData>(key);
}else if(DataBaseReadOnly.ContainsKey(keyOrPath)){
return DataBaseReadOnly[keyOrPath].GetAll<TData>(key);
}else{
throw new Exception("File not loaded, you should use LoadDataFile(key) or ReadData(key,data) first.");
}
}
public IEnumerable<TData> FindData<TData>(string keyOrPath,string key,System.Linq.Expressions.Expression<Func<TData, bool>> expression) where TData : new(){
if(DataBaseFiles.ContainsKey(keyOrPath)){
return DataBaseFiles[keyOrPath].FindData<TData>(key,expression);
}else if(DataBaseReadOnly.ContainsKey(keyOrPath)){
return DataBaseReadOnly[keyOrPath].FindData<TData>(key,expression);
}else{
throw new Exception("File not loaded, you should use LoadDataFile(key) or ReadData(key,data) first.");
}
}
//------------------------------------------------------------------------------//
#region Default Json Operation
public void SetObjectToJson<TObject>(TObject obj){
ObjectFiles["Default/SaveData.json"].SetObject(typeof(TObject).ToString(),obj);
ObjectFiles["SaveData/DefaultJsonSave.json"].SetObject(typeof(TObject).ToString(),obj);
}
public TObject GetObjectFromJson<TObject>() where TObject : new(){
return ObjectFiles["Default/SaveData.json"].GetObject<TObject>(typeof(TObject).ToString());
return ObjectFiles["SaveData/DefaultJsonSave.json"].GetObject<TObject>(typeof(TObject).ToString());
}
#endregion
@ -91,12 +215,16 @@ namespace EGFramework @@ -91,12 +215,16 @@ namespace EGFramework
return self.GetModule<EGSave>();
}
public static string GetGodotResPath(this string absPath){
return ProjectSettings.GlobalizePath("res://"+absPath);
public static string GetGodotResPath(this string path){
return ProjectSettings.GlobalizePath("res://"+path);
}
public static string GetGodotUserPath(this string absPath){
return ProjectSettings.GlobalizePath("user://"+absPath);
public static string GetGodotUserPath(this string path){
return ProjectSettings.GlobalizePath("user://"+path);
}
public static string GetDirectoryName(this string path){
return Path.GetDirectoryName(path);
}
}

26
addons/EGFramework/Module/SaveTools/EGSqlite.cs

@ -80,12 +80,12 @@ namespace EGFramework{ @@ -80,12 +80,12 @@ namespace EGFramework{
{
string sqlCommand = "CREATE TABLE " + typeof(TData).Name;
sqlCommand += "(\"ID\" INTEGER NOT NULL UNIQUE,";
var properties = typeof(TData).GetFields();
var properties = typeof(TData).GetProperties();
Godot.GD.Print(properties.Count() + " Readed ");
foreach(var property in properties){
if(property.FieldType == typeof(int) || property.FieldType == typeof(bool) || property.FieldType.IsEnum){
if(property.PropertyType == typeof(int) || property.PropertyType == typeof(bool) || property.PropertyType.IsEnum){
sqlCommand += "\"" + property.Name + "\" INTEGER" + " NOT NULL,";
}else if(property.FieldType == typeof(double) || property.FieldType == typeof(float)){
}else if(property.PropertyType == typeof(double) || property.PropertyType == typeof(float)){
sqlCommand += "\"" + property.Name + "\" REAL" + " NOT NULL,";
}
else{
@ -135,15 +135,15 @@ namespace EGFramework{ @@ -135,15 +135,15 @@ namespace EGFramework{
try
{
string sqlCommand = "INSERT INTO " + typeof(TData).Name;
var properties = typeof(TData).GetFields();
var properties = typeof(TData).GetProperties();
Dictionary<string,object> dataParams = new Dictionary<string, object>();
foreach(var property in properties){
dataParams.Add(property.Name,property.GetValue(data));
if(property.FieldType==typeof(bool) || property.FieldType.IsEnum){
if(property.PropertyType==typeof(bool) || property.PropertyType.IsEnum){
// If property is bool type , save data to data base should be 0 or 1 instead of false or true;
// If property is Enum type , then transform data to int;
dataParams[property.Name] = System.Convert.ToInt32(dataParams[property.Name]);
}else if(property.FieldType.IsClass || property.FieldType.IsValueType && !property.FieldType.IsPrimitive && property.FieldType != typeof(string)){
}else if(property.PropertyType.IsClass || property.PropertyType.IsValueType && !property.PropertyType.IsPrimitive && property.PropertyType != typeof(string)){
dataParams[property.Name] = JsonConvert.SerializeObject(dataParams[property.Name]);
}
}
@ -188,23 +188,23 @@ namespace EGFramework{ @@ -188,23 +188,23 @@ namespace EGFramework{
string sqlCommand = "SELECT * FROM " + typeof(TData).Name;
SqliteCommand selectCommand = new SqliteCommand(sqlCommand,SqliteConn);
SqliteDataReader reader = selectCommand.ExecuteReader();
var properties = typeof(TData).GetFields();
var properties = typeof(TData).GetProperties();
while (reader.Read())
{
TData dataRow = new TData();
foreach(var property in properties){
if(property.FieldType == reader[property.Name].GetType()){
if(property.PropertyType == reader[property.Name].GetType()){
property.SetValue(dataRow,reader[property.Name]);
}else if(property.FieldType.IsEnum){
object propertyEnum = Enum.Parse(property.FieldType,reader[property.Name].ToString());
}else if(property.PropertyType.IsEnum){
object propertyEnum = Enum.Parse(property.PropertyType,reader[property.Name].ToString());
property.SetValue(dataRow,propertyEnum);
}
else if(property.FieldType.IsPrimitive) {
object propertyObject = System.Convert.ChangeType(reader[property.Name],property.FieldType);
else if(property.PropertyType.IsPrimitive) {
object propertyObject = System.Convert.ChangeType(reader[property.Name],property.PropertyType);
property.SetValue(dataRow,propertyObject);
}else{
object classObject = JsonConvert.DeserializeObject(reader[property.Name].ToString(),property.FieldType);
object classObject = JsonConvert.DeserializeObject(reader[property.Name].ToString(),property.PropertyType);
property.SetValue(dataRow,classObject);
}
}

24
addons/EGFramework/Module/SaveTools/SaveToolsInterface.cs

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace EGFramework
@ -9,15 +10,26 @@ namespace EGFramework @@ -9,15 +10,26 @@ namespace EGFramework
void InitSaveFile(string path);
}
public interface IEGSaveObject{
void SetObject<TObject>(string objectKey,TObject obj);
public interface IEGSaveReadOnly{
void InitReadOnly(string data);
void InitReadOnly(byte[] data);
}
public interface IEGSaveObjectReadOnly{
TObject GetObject<TObject>(string objectKey) where TObject : new();
}
public interface IEGSaveDataReadOnly{
TData GetData<TData>(string dataKey,object id) where TData : new();
IEnumerable<TData> GetAll<TData>(string dataKey) where TData : new();
IEnumerable<TData> FindData<TData>(string dataKey,Expression<Func<TData, bool>> expression) where TData : new();
}
public interface IEGSaveObject : IEGSaveObjectReadOnly{
void SetObject<TObject>(string objectKey,TObject obj);
}
//
public interface IEGSaveData{
void SetData<TData>(TData data,string dataKey,int id);
TData GetData<TData>(string dataKey,int id) where TData : new();
IList<TData> QueryData<TData>(string dataKey,string sql) where TData : new();
public interface IEGSaveData : IEGSaveDataReadOnly{
void SetData<TData>(string dataKey,TData data,object id);
}
}

54
addons/Tools/ItemImporter/ToolItemImporter.cs

@ -1,54 +0,0 @@ @@ -1,54 +0,0 @@
#if TOOLS
using Godot;
using System;
namespace EGFramework.Example.SystemExamples.PlayerStorage
{
[Tool]
public partial class ToolItemImporter : EditorPlugin
{
PackedScene MainPanel = ResourceLoader.Load<PackedScene>("res://addons/Tools/ItemImporter/ToolItemImporter.tscn");
Control MainPanelInstance;
public override void _EnterTree()
{
// Initialization of the plugin goes here.
MainPanelInstance = (Control)MainPanel.Instantiate();
// Add the main panel to the editor's main viewport.
EditorInterface.Singleton.GetEditorMainScreen().AddChild(MainPanelInstance);
// Hide the main panel. Very much required.
_MakeVisible(false);
}
public override void _ExitTree()
{
// Clean-up of the plugin goes here.
if (MainPanelInstance != null)
{
MainPanelInstance.QueueFree();
}
}
public override bool _HasMainScreen()
{
return true;
}
public override void _MakeVisible(bool visible)
{
if (MainPanelInstance != null)
{
MainPanelInstance.Visible = visible;
}
}
public override string _GetPluginName()
{
return "Tool Item Importer";
}
public override Texture2D _GetPluginIcon()
{
return EditorInterface.Singleton.GetEditorTheme().GetIcon("Node", "EditorIcons");
}
}
}
#endif

37
addons/Tools/ItemImporter/ToolItemImporter.tscn

@ -1,37 +0,0 @@ @@ -1,37 +0,0 @@
[gd_scene format=3 uid="uid://bglw1yht7w1kt"]
[node name="ToolItemImporter" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="Button" type="Button" parent="."]
layout_mode = 1
offset_right = 69.0
offset_bottom = 31.0
text = "导入CSV"
[node name="Button2" type="Button" parent="."]
layout_mode = 1
anchors_preset = 1
anchor_left = 1.0
anchor_right = 1.0
offset_left = -72.0
offset_bottom = 31.0
grow_horizontal = 0
text = "重新载入"
[node name="Button3" type="Button" parent="."]
layout_mode = 1
anchors_preset = 1
anchor_left = 1.0
anchor_right = 1.0
offset_left = -71.0
offset_top = 36.0
offset_right = 1.0
offset_bottom = 67.0
grow_horizontal = 0
text = "重新载入"

7
addons/Tools/ItemImporter/plugin.cfg

@ -1,7 +0,0 @@ @@ -1,7 +0,0 @@
[plugin]
name="ItemImporter"
description="a csv ItemImporter"
author="jkpete"
version=""
script="ToolItemImporter.cs"

7
project.godot

@ -16,13 +16,18 @@ run/main_scene="res://Example/UsingTest/Scene/TestEGFramework.tscn" @@ -16,13 +16,18 @@ run/main_scene="res://Example/UsingTest/Scene/TestEGFramework.tscn"
config/features=PackedStringArray("4.2", "C#", "GL Compatibility")
config/icon="res://icon.svg"
[display]
window/size/viewport_width=1920
window/size/viewport_height=1080
[dotnet]
project/assembly_name="EGFramework"
[editor_plugins]
enabled=PackedStringArray("res://addons/Tools/ItemImporter/plugin.cfg")
enabled=PackedStringArray()
[input]

Loading…
Cancel
Save