diff --git a/.drone.yml b/.drone.yml index 9484e36..7891f20 100644 --- a/.drone.yml +++ b/.drone.yml @@ -10,7 +10,7 @@ steps: auto_tag: true - name: frontend - image: privateregistry.michelescandura.com/michele/basecompileimage + image: privateregistry.michelescandura.com/michele/basecompileimage:1.1 pull: true volumes: - name: cache @@ -50,7 +50,7 @@ steps: - name: cache path: /release settings: - api_key: 96d2ba3da7491bd7760e2681f8882cf41f82e609 + api_key: 5eb87a0a7d55fbf8fb64e678781a5ddcc1a27e09 base_url: https://git.michelescandura.com files: /release/zip/* title: ${DRONE_TAG} diff --git a/.gitignore b/.gitignore index 2527dec..bfb3dac 100644 --- a/.gitignore +++ b/.gitignore @@ -362,4 +362,6 @@ MigrationBackup/ # Fody - auto-generated XML schema FodyWeavers.xsd -/db \ No newline at end of file +/db +*.db +*.db* \ No newline at end of file diff --git a/Assets/migration scripts.txt b/Assets/migration scripts.txt new file mode 100644 index 0000000..771a499 --- /dev/null +++ b/Assets/migration scripts.txt @@ -0,0 +1,52 @@ + + +select * from MapLog where SessionId=2 --Ruined Maze D0823E78-15E4-45EE-A396-0A2E891961DC + +select * from MapLog where SessionId=4 --test 6351309A-EFA5-4721-A4BE-AC63995ADB7F + +select * from MapLog where SessionId=5 --daniele 7EB1D6F5-12E2-4A8F-98CD-3351D40F1D26 + +select * from MapLog where SessionId=6 --Psyruque BED7EF13-5823-427A-8C40-8BE94A563638 + + +select * from Sessions +select * from Snapshots +select * from Snapshot where SessionId=2 +select * from Sessions +select * from MapLogs +select * from MapLog +INSERT INTO Snapshots (Object, SessionId, Timestamp) +SELECT Object, "BED7EF13-5823-427A-8C40-8BE94A563638",Timestamp +FROM Snapshot +WHERE SessionId=6 +order by SnapshotId + +INSERT INTO MapLogs (Object, Operation, SessionId, Timestamp, Type, UserId) +SELECT Object, Operation, "6351309A-EFA5-4721-A4BE-AC63995ADB7F", Timestamp, Type, "cd85a137-a5e8-4e4a-81d2-3e1c94ac9470" +FROM MapLog +WHERE SessionId =2 +ORDER BY MapLogId + +INSERT INTO MapLogs (Object, Operation, SessionId, Timestamp, Type, UserId) +SELECT Object, Operation, "D0823E78-15E4-45EE-A396-0A2E891961DC", Timestamp, Type, "cd85a137-a5e8-4e4a-81d2-3e1c94ac9470" +FROM MapLog +WHERE SessionId =4 +ORDER BY MapLogId + +INSERT INTO MapLogs (Object, Operation, SessionId, Timestamp, Type, UserId) +SELECT Object, Operation, "7EB1D6F5-12E2-4A8F-98CD-3351D40F1D26", Timestamp, Type, "cd85a137-a5e8-4e4a-81d2-3e1c94ac9470" +FROM MapLog +WHERE SessionId =5 +ORDER BY MapLogId + +INSERT INTO MapLogs (Object, Operation, SessionId, Timestamp, Type, UserId) +SELECT Object, Operation, "BED7EF13-5823-427A-8C40-8BE94A563638", Timestamp, Type, "cd85a137-a5e8-4e4a-81d2-3e1c94ac9470" +FROM MapLog +WHERE SessionId =6 +ORDER BY MapLogId + +--delete from Snapshots where SessionId="A306DFEE-82A9-4964-942A-1B923B970951" + + +insert into Snapshots ( +select * from Snapshot where SessionId=2 diff --git a/Assets/sledgemapper.drawio b/Assets/sledgemapper.drawio new file mode 100644 index 0000000..d445036 --- /dev/null +++ b/Assets/sledgemapper.drawio @@ -0,0 +1 @@ +7Vvbdto4FP0aHpPlC7c8gnNpO2mGljSZV4EFaJAtRhYh9OvnyJZvKICd4DohrMUDOpZlS3vraGvbbtiO93zD0WL2nbmYNizDfW7Ylw3LMpuW1ZA/w11HkU5bBaacuKpSGhiS31gFDRVdEhcHuYqCMSrIIh8cM9/HY5GLIc7ZKl9twmj+qgs0xVpgOEZUjz4SV8yiaNfqpPEvmExn8ZXN9kV0xENxZdWTYIZctsqE7KuG7XDGRPTPe3YwlYMXj8vj1/UjvZ23b779CP5Dv/p/3d89nEWNXZc5JekCx754ddO/55PrLw/Nf/9ZDK5/rIyb3ujbmTrFeEJ0qcbLQd4Ckamv+izW8UAGK+JR5EOpP2G+GKojMAx9ROUJ9uUY7g9zCDxhLghg0FMHBFtAdDwj1L1Fa7aUvQgEGs/jUn/GOPkNzSIKh0wIwGEuFJ2sdq7GUJ4JYQOiHAdQZxAPjZmEblEgVJ0xoxQtAjIKb1hW8RCfEr/PhGBe3BBb+i52VSnBOiwIzuYJe+T5BQFRwMnRwM8ZOiqAbjDzsOBrqKKOJlxTk82My6uUumZbxWZZ2tpdNWXUdJkmbSeX+wnTC/lTGIT0evbG9ZoFrweI5C6HKADvI4H7chiDLBHhT6araSikZwmqmhpV75CHNZrCSIsMJSmeiK2EDBZoTPzpbVjnsplGfqqeyhCDcyc0JMOMuC72Q7IIJFDEJ8mQBSO+CIei1YcfDJhjnLcaLbghB8pmWoafrM6Fw3zgFSIhgTCQdYUlYV+g1s6Ju59a6zxiZZHNEikHaVn8LD3VcAyMcfvrXwFkjWMDckdCmQmPqr9Vwd2yaobb1uC+8hCRp/VcF1J0cAL8oIB3ujUD3tQA1xCmJJQPajTMF5fWPfB7AKRsLsb7XtLh8szUOGHrnLBfwJ+iEaYDFhBBmGyfR3U3eFFX0jaNZjFUd6z+bwK1pYE6WPLxDAVSRIDqmsPwhv+OcD5XBqpZd25ua6gOxdKV3Swo+o2T6D+c6Dc3RL/drlb0mxui3+6+X9Hf2c5U427pjY5QNxZMO+3CNHsvG4CuhmUP7l7aN5bxHZaSo0PyoIKwNN617wAuToLw4KAWVflV6UFTNwy/QuI3rgANMkLhMnPPZMDnTDZ3ZFM6K4KaVYHcrTtTm7rXdoPlkjvEHvERl4jfoznWTeKPjm9VkNav+eMb2JWOse/25CMXKI0ok3K7DyGlx00jKl4TGi9dewRzfv3D7hTHUwfTEVtdpYF+GIADMVNKy+2Awb4U74cMNhhTXGA7J+92J7AvAckxRYI85Z887RDnA0ncVJhbRl6YW4adbyLqpDor+6inbEPRKGgNHcyq182/AWcTHARM1+unLWb1W0x7c8tXdIvZMfaS+IUdpt0ssMPsvI8dpqn7lkNEkcq4n3BtSybvx9lZmrpNqaH32bca5WEtuoGsbK+h25SfSrHEiL1ryWJuZPrOKyWLvdGQ1dm4l6oli+40bntOeRIs1QuWltHN0aHwizCWuWOR2a5YWq0P9CKMbqQOBcdYf3rzWRRLpzC93o1i0c1Rh4jj05wHtcDL41y7B27pfikkbXF8r63VDHTtb79YumUKyl6u4pbhMPcE+IEBL/xmTHWI64aqA2MijtA5qBtr+5Vi7HBY64amBvKnNxjK49oqKMOqchgs3ft7AIjcY1ygq0OxXXsm1u2/v5disZT2Qk8+q7yV8+CEaGFEL2rPt+WsP7YIx7qcuZf4gmb9Vp8a271OX4zlXqtP4SyplLU1muqG3uj6Jc9zEsJY+SaKun6t5p6Gtrh+WkNnm0+cNtphk0mAKzEOLd04NM7PY+BTuoZmXCYR7Ek7I2XJRWt4H43n05C/DqOMw3GfpQakcrut4jkhnl/qo0t1W43k87PiRt3ZGxkVE/OPwaWbZ8WxivXTRwXrMLM/fin3j0One2YUeiEXeLTV+8zI8U1UdRVcxMFPNPpurEu56G8khkaAbVwpvk5cHIYpdt7Fj5P0W7gCxfST66h6+uG6ffU/ \ No newline at end of file diff --git a/External tools/Myra.1.2.1.0/AssetManagementBase.dll b/External tools/Myra.1.2.1.0/AssetManagementBase.dll deleted file mode 100644 index f49a1cc..0000000 Binary files a/External tools/Myra.1.2.1.0/AssetManagementBase.dll and /dev/null differ diff --git a/External tools/Myra.1.2.1.0/Assets/fonts/arial64.fnt b/External tools/Myra.1.2.1.0/Assets/fonts/arial64.fnt deleted file mode 100644 index 108850f..0000000 --- a/External tools/Myra.1.2.1.0/Assets/fonts/arial64.fnt +++ /dev/null @@ -1,288 +0,0 @@ -info face="Arial" size=64 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 outline=0 -common lineHeight=63 base=51 scaleW=512 scaleH=512 pages=1 packed=0 alphaChnl=1 redChnl=0 greenChnl=0 blueChnl=0 -page id=0 file="arial64_0.png" -chars count=191 -char id=32 x=508 y=2 width=3 height=1 xoffset=-1 yoffset=62 xadvance=15 page=0 chnl=15 -char id=33 x=497 y=270 width=7 height=40 xoffset=5 yoffset=11 xadvance=17 page=0 chnl=15 -char id=34 x=445 y=382 width=16 height=14 xoffset=2 yoffset=11 xadvance=20 page=0 chnl=15 -char id=35 x=453 y=229 width=31 height=40 xoffset=0 yoffset=11 xadvance=31 page=0 chnl=15 -char id=36 x=188 y=105 width=28 height=46 xoffset=1 yoffset=10 xadvance=31 page=0 chnl=15 -char id=37 x=346 y=190 width=44 height=40 xoffset=2 yoffset=11 xadvance=49 page=0 chnl=15 -char id=38 x=147 y=238 width=34 height=40 xoffset=2 yoffset=11 xadvance=37 page=0 chnl=15 -char id=39 x=462 y=382 width=7 height=14 xoffset=2 yoffset=11 xadvance=11 page=0 chnl=15 -char id=40 x=287 y=53 width=14 height=51 xoffset=3 yoffset=11 xadvance=18 page=0 chnl=15 -char id=41 x=272 y=53 width=14 height=51 xoffset=3 yoffset=11 xadvance=18 page=0 chnl=15 -char id=42 x=379 y=384 width=19 height=17 xoffset=1 yoffset=11 xadvance=21 page=0 chnl=15 -char id=43 x=26 y=400 width=28 height=27 xoffset=2 yoffset=19 xadvance=32 page=0 chnl=15 -char id=44 x=470 y=380 width=7 height=13 xoffset=4 yoffset=46 xadvance=15 page=0 chnl=15 -char id=45 x=128 y=419 width=16 height=5 xoffset=1 yoffset=34 xadvance=18 page=0 chnl=15 -char id=46 x=162 y=419 width=7 height=5 xoffset=4 yoffset=46 xadvance=15 page=0 chnl=15 -char id=47 x=62 y=321 width=17 height=40 xoffset=-1 yoffset=11 xadvance=15 page=0 chnl=15 -char id=48 x=341 y=314 width=27 height=39 xoffset=2 yoffset=12 xadvance=31 page=0 chnl=15 -char id=49 x=369 y=313 width=16 height=39 xoffset=5 yoffset=12 xadvance=31 page=0 chnl=15 -char id=50 x=200 y=320 width=28 height=39 xoffset=1 yoffset=12 xadvance=31 page=0 chnl=15 -char id=51 x=229 y=320 width=27 height=39 xoffset=2 yoffset=12 xadvance=31 page=0 chnl=15 -char id=52 x=112 y=321 width=29 height=39 xoffset=0 yoffset=12 xadvance=31 page=0 chnl=15 -char id=53 x=171 y=320 width=28 height=39 xoffset=2 yoffset=12 xadvance=31 page=0 chnl=15 -char id=54 x=142 y=320 width=28 height=39 xoffset=1 yoffset=12 xadvance=31 page=0 chnl=15 -char id=55 x=313 y=315 width=27 height=39 xoffset=2 yoffset=12 xadvance=31 page=0 chnl=15 -char id=56 x=257 y=320 width=27 height=39 xoffset=2 yoffset=12 xadvance=31 page=0 chnl=15 -char id=57 x=285 y=315 width=27 height=39 xoffset=2 yoffset=12 xadvance=31 page=0 chnl=15 -char id=58 x=491 y=350 width=7 height=29 xoffset=4 yoffset=22 xadvance=15 page=0 chnl=15 -char id=59 x=26 y=362 width=7 height=37 xoffset=4 yoffset=22 xadvance=15 page=0 chnl=15 -char id=60 x=84 y=395 width=28 height=27 xoffset=2 yoffset=18 xadvance=32 page=0 chnl=15 -char id=61 x=350 y=385 width=28 height=17 xoffset=2 yoffset=23 xadvance=32 page=0 chnl=15 -char id=62 x=55 y=396 width=28 height=27 xoffset=2 yoffset=18 xadvance=32 page=0 chnl=15 -char id=63 x=333 y=273 width=27 height=40 xoffset=2 yoffset=11 xadvance=31 page=0 chnl=15 -char id=64 x=0 y=0 width=52 height=52 xoffset=2 yoffset=11 xadvance=56 page=0 chnl=15 -char id=65 x=471 y=188 width=38 height=40 xoffset=-1 yoffset=11 xadvance=37 page=0 chnl=15 -char id=66 x=387 y=231 width=32 height=40 xoffset=3 yoffset=11 xadvance=37 page=0 chnl=15 -char id=67 x=406 y=103 width=36 height=42 xoffset=2 yoffset=10 xadvance=40 page=0 chnl=15 -char id=68 x=182 y=238 width=34 height=40 xoffset=4 yoffset=11 xadvance=40 page=0 chnl=15 -char id=69 x=0 y=280 width=31 height=40 xoffset=4 yoffset=11 xadvance=37 page=0 chnl=15 -char id=70 x=247 y=279 width=28 height=40 xoffset=4 yoffset=11 xadvance=34 page=0 chnl=15 -char id=71 x=367 y=103 width=38 height=42 xoffset=2 yoffset=10 xadvance=43 page=0 chnl=15 -char id=72 x=420 y=229 width=32 height=40 xoffset=4 yoffset=11 xadvance=40 page=0 chnl=15 -char id=73 x=88 y=321 width=7 height=40 xoffset=4 yoffset=11 xadvance=15 page=0 chnl=15 -char id=74 x=189 y=196 width=23 height=41 xoffset=1 yoffset=11 xadvance=28 page=0 chnl=15 -char id=75 x=217 y=238 width=34 height=40 xoffset=3 yoffset=11 xadvance=37 page=0 chnl=15 -char id=76 x=417 y=272 width=27 height=40 xoffset=3 yoffset=11 xadvance=31 page=0 chnl=15 -char id=77 x=391 y=188 width=39 height=40 xoffset=3 yoffset=11 xadvance=45 page=0 chnl=15 -char id=78 x=252 y=233 width=33 height=40 xoffset=3 yoffset=11 xadvance=40 page=0 chnl=15 -char id=79 x=327 y=105 width=39 height=42 xoffset=2 yoffset=10 xadvance=43 page=0 chnl=15 -char id=80 x=32 y=280 width=31 height=40 xoffset=4 yoffset=11 xadvance=37 page=0 chnl=15 -char id=81 x=217 y=105 width=39 height=44 xoffset=2 yoffset=10 xadvance=43 page=0 chnl=15 -char id=82 x=38 y=239 width=36 height=40 xoffset=4 yoffset=11 xadvance=40 page=0 chnl=15 -char id=83 x=443 y=103 width=33 height=42 xoffset=2 yoffset=10 xadvance=37 page=0 chnl=15 -char id=84 x=286 y=233 width=33 height=40 xoffset=0 yoffset=11 xadvance=33 page=0 chnl=15 -char id=85 x=477 y=102 width=32 height=41 xoffset=4 yoffset=11 xadvance=40 page=0 chnl=15 -char id=86 x=0 y=239 width=37 height=40 xoffset=0 yoffset=11 xadvance=37 page=0 chnl=15 -char id=87 x=291 y=191 width=54 height=40 xoffset=0 yoffset=11 xadvance=54 page=0 chnl=15 -char id=88 x=111 y=238 width=35 height=40 xoffset=0 yoffset=11 xadvance=35 page=0 chnl=15 -char id=89 x=75 y=239 width=35 height=40 xoffset=0 yoffset=11 xadvance=35 page=0 chnl=15 -char id=90 x=320 y=232 width=33 height=40 xoffset=0 yoffset=11 xadvance=34 page=0 chnl=15 -char id=91 x=329 y=53 width=12 height=51 xoffset=3 yoffset=11 xadvance=15 page=0 chnl=15 -char id=92 x=44 y=321 width=17 height=40 xoffset=-1 yoffset=11 xadvance=15 page=0 chnl=15 -char id=93 x=316 y=53 width=12 height=51 xoffset=0 yoffset=11 xadvance=15 page=0 chnl=15 -char id=94 x=248 y=391 width=22 height=21 xoffset=1 yoffset=11 xadvance=24 page=0 chnl=15 -char id=95 x=76 y=424 width=34 height=5 xoffset=-2 yoffset=57 xadvance=31 page=0 chnl=15 -char id=96 x=29 y=428 width=11 height=8 xoffset=2 yoffset=11 xadvance=18 page=0 chnl=15 -char id=97 x=241 y=360 width=28 height=30 xoffset=1 yoffset=21 xadvance=31 page=0 chnl=15 -char id=98 x=389 y=272 width=27 height=40 xoffset=3 yoffset=11 xadvance=31 page=0 chnl=15 -char id=99 x=297 y=355 width=26 height=30 xoffset=2 yoffset=21 xadvance=28 page=0 chnl=15 -char id=100 x=305 y=274 width=27 height=40 xoffset=1 yoffset=11 xadvance=31 page=0 chnl=15 -char id=101 x=212 y=360 width=28 height=30 xoffset=1 yoffset=21 xadvance=31 page=0 chnl=15 -char id=102 x=25 y=321 width=18 height=40 xoffset=0 yoffset=11 xadvance=15 page=0 chnl=15 -char id=103 x=56 y=197 width=27 height=41 xoffset=1 yoffset=21 xadvance=31 page=0 chnl=15 -char id=104 x=471 y=270 width=25 height=40 xoffset=3 yoffset=11 xadvance=31 page=0 chnl=15 -char id=105 x=96 y=321 width=7 height=40 xoffset=2 yoffset=11 xadvance=11 page=0 chnl=15 -char id=106 x=302 y=53 width=13 height=51 xoffset=-3 yoffset=11 xadvance=13 page=0 chnl=15 -char id=107 x=485 y=229 width=25 height=40 xoffset=3 yoffset=11 xadvance=28 page=0 chnl=15 -char id=108 x=80 y=321 width=7 height=40 xoffset=2 yoffset=11 xadvance=11 page=0 chnl=15 -char id=109 x=140 y=361 width=41 height=30 xoffset=3 yoffset=21 xadvance=47 page=0 chnl=15 -char id=110 x=324 y=355 width=25 height=30 xoffset=3 yoffset=21 xadvance=31 page=0 chnl=15 -char id=111 x=182 y=360 width=29 height=30 xoffset=1 yoffset=21 xadvance=31 page=0 chnl=15 -char id=112 x=0 y=197 width=27 height=41 xoffset=3 yoffset=21 xadvance=31 page=0 chnl=15 -char id=113 x=28 y=197 width=27 height=41 xoffset=1 yoffset=21 xadvance=31 page=0 chnl=15 -char id=114 x=350 y=354 width=16 height=30 xoffset=3 yoffset=21 xadvance=18 page=0 chnl=15 -char id=115 x=270 y=360 width=26 height=30 xoffset=1 yoffset=21 xadvance=28 page=0 chnl=15 -char id=116 x=386 y=313 width=15 height=39 xoffset=0 yoffset=12 xadvance=15 page=0 chnl=15 -char id=117 x=0 y=401 width=25 height=29 xoffset=3 yoffset=22 xadvance=31 page=0 chnl=15 -char id=118 x=435 y=352 width=27 height=29 xoffset=1 yoffset=22 xadvance=29 page=0 chnl=15 -char id=119 x=367 y=354 width=39 height=29 xoffset=0 yoffset=22 xadvance=39 page=0 chnl=15 -char id=120 x=463 y=350 width=27 height=29 xoffset=0 yoffset=22 xadvance=27 page=0 chnl=15 -char id=121 x=361 y=272 width=27 height=40 xoffset=0 yoffset=22 xadvance=27 page=0 chnl=15 -char id=122 x=407 y=352 width=27 height=29 xoffset=0 yoffset=22 xadvance=27 page=0 chnl=15 -char id=123 x=254 y=53 width=17 height=51 xoffset=1 yoffset=11 xadvance=18 page=0 chnl=15 -char id=124 x=337 y=0 width=6 height=52 xoffset=4 yoffset=11 xadvance=14 page=0 chnl=15 -char id=125 x=236 y=53 width=17 height=51 xoffset=0 yoffset=11 xadvance=18 page=0 chnl=15 -char id=126 x=0 y=431 width=28 height=10 xoffset=2 yoffset=27 xadvance=32 page=0 chnl=15 -char id=160 x=508 y=0 width=3 height=1 xoffset=-1 yoffset=62 xadvance=15 page=0 chnl=15 -char id=161 x=104 y=321 width=7 height=40 xoffset=5 yoffset=22 xadvance=17 page=0 chnl=15 -char id=162 x=161 y=53 width=27 height=51 xoffset=2 yoffset=11 xadvance=31 page=0 chnl=15 -char id=163 x=127 y=279 width=30 height=40 xoffset=0 yoffset=11 xadvance=31 page=0 chnl=15 -char id=164 x=165 y=392 width=28 height=24 xoffset=1 yoffset=20 xadvance=31 page=0 chnl=15 -char id=165 x=354 y=231 width=32 height=40 xoffset=-1 yoffset=11 xadvance=31 page=0 chnl=15 -char id=166 x=344 y=0 width=6 height=52 xoffset=4 yoffset=11 xadvance=14 page=0 chnl=15 -char id=167 x=189 y=53 width=27 height=51 xoffset=2 yoffset=11 xadvance=31 page=0 chnl=15 -char id=168 x=111 y=423 width=16 height=5 xoffset=1 yoffset=11 xadvance=18 page=0 chnl=15 -char id=169 x=137 y=154 width=43 height=41 xoffset=-1 yoffset=10 xadvance=41 page=0 chnl=15 -char id=170 x=292 y=391 width=19 height=20 xoffset=0 yoffset=11 xadvance=20 page=0 chnl=15 -char id=171 x=113 y=393 width=25 height=25 xoffset=3 yoffset=24 xadvance=31 page=0 chnl=15 -char id=172 x=399 y=384 width=28 height=16 xoffset=2 yoffset=24 xadvance=32 page=0 chnl=15 -char id=173 x=145 y=419 width=16 height=5 xoffset=1 yoffset=34 xadvance=18 page=0 chnl=15 -char id=174 x=181 y=154 width=43 height=41 xoffset=-1 yoffset=10 xadvance=41 page=0 chnl=15 -char id=175 x=41 y=428 width=34 height=5 xoffset=-2 yoffset=4 xadvance=30 page=0 chnl=15 -char id=176 x=428 y=382 width=16 height=15 xoffset=3 yoffset=11 xadvance=22 page=0 chnl=15 -char id=177 x=34 y=362 width=28 height=33 xoffset=1 yoffset=18 xadvance=30 page=0 chnl=15 -char id=178 x=312 y=386 width=18 height=20 xoffset=0 yoffset=11 xadvance=18 page=0 chnl=15 -char id=179 x=331 y=386 width=18 height=20 xoffset=0 yoffset=11 xadvance=18 page=0 chnl=15 -char id=180 x=492 y=380 width=11 height=8 xoffset=5 yoffset=12 xadvance=18 page=0 chnl=15 -char id=181 x=0 y=321 width=24 height=40 xoffset=4 yoffset=22 xadvance=32 page=0 chnl=15 -char id=182 x=439 y=52 width=32 height=50 xoffset=-1 yoffset=11 xadvance=30 page=0 chnl=15 -char id=183 x=504 y=371 width=7 height=5 xoffset=5 yoffset=29 xadvance=18 page=0 chnl=15 -char id=184 x=478 y=380 width=13 height=11 xoffset=2 yoffset=51 xadvance=18 page=0 chnl=15 -char id=185 x=499 y=350 width=12 height=20 xoffset=2 yoffset=11 xadvance=18 page=0 chnl=15 -char id=186 x=271 y=391 width=20 height=20 xoffset=0 yoffset=11 xadvance=20 page=0 chnl=15 -char id=187 x=139 y=393 width=25 height=25 xoffset=3 yoffset=24 xadvance=31 page=0 chnl=15 -char id=188 x=47 y=155 width=44 height=41 xoffset=2 yoffset=11 xadvance=46 page=0 chnl=15 -char id=189 x=92 y=154 width=44 height=41 xoffset=2 yoffset=11 xadvance=46 page=0 chnl=15 -char id=190 x=0 y=155 width=46 height=41 xoffset=0 yoffset=11 xadvance=46 page=0 chnl=15 -char id=191 x=276 y=274 width=28 height=40 xoffset=3 yoffset=22 xadvance=34 page=0 chnl=15 -char id=192 x=469 y=0 width=38 height=51 xoffset=-1 yoffset=0 xadvance=37 page=0 chnl=15 -char id=193 x=430 y=0 width=38 height=51 xoffset=-1 yoffset=0 xadvance=37 page=0 chnl=15 -char id=194 x=391 y=0 width=38 height=51 xoffset=-1 yoffset=0 xadvance=37 page=0 chnl=15 -char id=195 x=366 y=52 width=38 height=50 xoffset=-1 yoffset=1 xadvance=37 page=0 chnl=15 -char id=196 x=61 y=105 width=38 height=48 xoffset=-1 yoffset=3 xadvance=37 page=0 chnl=15 -char id=197 x=100 y=105 width=38 height=48 xoffset=-1 yoffset=3 xadvance=37 page=0 chnl=15 -char id=198 x=236 y=192 width=54 height=40 xoffset=-1 yoffset=11 xadvance=55 page=0 chnl=15 -char id=199 x=173 y=0 width=36 height=52 xoffset=2 yoffset=10 xadvance=40 page=0 chnl=15 -char id=200 x=37 y=53 width=31 height=51 xoffset=4 yoffset=0 xadvance=37 page=0 chnl=15 -char id=201 x=69 y=53 width=31 height=51 xoffset=4 yoffset=0 xadvance=37 page=0 chnl=15 -char id=202 x=101 y=53 width=31 height=51 xoffset=4 yoffset=0 xadvance=37 page=0 chnl=15 -char id=203 x=139 y=105 width=31 height=48 xoffset=4 yoffset=3 xadvance=37 page=0 chnl=15 -char id=204 x=354 y=52 width=11 height=51 xoffset=1 yoffset=0 xadvance=15 page=0 chnl=15 -char id=205 x=342 y=53 width=11 height=51 xoffset=3 yoffset=0 xadvance=15 page=0 chnl=15 -char id=206 x=217 y=53 width=18 height=51 xoffset=-1 yoffset=0 xadvance=15 page=0 chnl=15 -char id=207 x=171 y=105 width=16 height=48 xoffset=0 yoffset=3 xadvance=15 page=0 chnl=15 -char id=208 x=431 y=188 width=39 height=40 xoffset=-1 yoffset=11 xadvance=40 page=0 chnl=15 -char id=209 x=405 y=52 width=33 height=50 xoffset=3 yoffset=1 xadvance=40 page=0 chnl=15 -char id=210 x=53 y=0 width=39 height=52 xoffset=2 yoffset=0 xadvance=43 page=0 chnl=15 -char id=211 x=93 y=0 width=39 height=52 xoffset=2 yoffset=0 xadvance=43 page=0 chnl=15 -char id=212 x=133 y=0 width=39 height=52 xoffset=2 yoffset=0 xadvance=43 page=0 chnl=15 -char id=213 x=351 y=0 width=39 height=51 xoffset=2 yoffset=1 xadvance=43 page=0 chnl=15 -char id=214 x=472 y=52 width=39 height=49 xoffset=2 yoffset=3 xadvance=43 page=0 chnl=15 -char id=215 x=194 y=391 width=24 height=23 xoffset=4 yoffset=20 xadvance=32 page=0 chnl=15 -char id=216 x=257 y=105 width=40 height=43 xoffset=2 yoffset=10 xadvance=43 page=0 chnl=15 -char id=217 x=243 y=0 width=32 height=52 xoffset=4 yoffset=0 xadvance=40 page=0 chnl=15 -char id=218 x=276 y=0 width=32 height=52 xoffset=4 yoffset=0 xadvance=40 page=0 chnl=15 -char id=219 x=210 y=0 width=32 height=52 xoffset=4 yoffset=0 xadvance=40 page=0 chnl=15 -char id=220 x=0 y=105 width=32 height=49 xoffset=4 yoffset=3 xadvance=40 page=0 chnl=15 -char id=221 x=0 y=53 width=36 height=51 xoffset=-1 yoffset=0 xadvance=37 page=0 chnl=15 -char id=222 x=64 y=280 width=31 height=40 xoffset=4 yoffset=11 xadvance=37 page=0 chnl=15 -char id=223 x=96 y=280 width=30 height=40 xoffset=3 yoffset=11 xadvance=34 page=0 chnl=15 -char id=224 x=460 y=146 width=28 height=41 xoffset=1 yoffset=10 xadvance=31 page=0 chnl=15 -char id=225 x=315 y=149 width=28 height=41 xoffset=1 yoffset=10 xadvance=31 page=0 chnl=15 -char id=226 x=344 y=148 width=28 height=41 xoffset=1 yoffset=10 xadvance=31 page=0 chnl=15 -char id=227 x=218 y=279 width=28 height=40 xoffset=1 yoffset=11 xadvance=31 page=0 chnl=15 -char id=228 x=432 y=313 width=28 height=38 xoffset=1 yoffset=13 xadvance=31 page=0 chnl=15 -char id=229 x=298 y=105 width=28 height=43 xoffset=1 yoffset=8 xadvance=31 page=0 chnl=15 -char id=230 x=92 y=362 width=47 height=30 xoffset=1 yoffset=21 xadvance=49 page=0 chnl=15 -char id=231 x=84 y=197 width=26 height=41 xoffset=2 yoffset=21 xadvance=28 page=0 chnl=15 -char id=232 x=402 y=146 width=28 height=41 xoffset=1 yoffset=10 xadvance=31 page=0 chnl=15 -char id=233 x=373 y=146 width=28 height=41 xoffset=1 yoffset=10 xadvance=31 page=0 chnl=15 -char id=234 x=431 y=146 width=28 height=41 xoffset=1 yoffset=10 xadvance=31 page=0 chnl=15 -char id=235 x=461 y=311 width=28 height=38 xoffset=1 yoffset=13 xadvance=31 page=0 chnl=15 -char id=236 x=225 y=192 width=10 height=41 xoffset=1 yoffset=10 xadvance=15 page=0 chnl=15 -char id=237 x=213 y=196 width=11 height=41 xoffset=4 yoffset=10 xadvance=15 page=0 chnl=15 -char id=238 x=489 y=144 width=18 height=41 xoffset=-1 yoffset=10 xadvance=15 page=0 chnl=15 -char id=239 x=490 y=311 width=16 height=38 xoffset=0 yoffset=13 xadvance=15 page=0 chnl=15 -char id=240 x=158 y=279 width=29 height=40 xoffset=1 yoffset=11 xadvance=31 page=0 chnl=15 -char id=241 x=445 y=270 width=25 height=40 xoffset=3 yoffset=11 xadvance=31 page=0 chnl=15 -char id=242 x=285 y=149 width=29 height=41 xoffset=1 yoffset=10 xadvance=31 page=0 chnl=15 -char id=243 x=225 y=150 width=29 height=41 xoffset=1 yoffset=10 xadvance=31 page=0 chnl=15 -char id=244 x=255 y=150 width=29 height=41 xoffset=1 yoffset=10 xadvance=31 page=0 chnl=15 -char id=245 x=188 y=279 width=29 height=40 xoffset=1 yoffset=11 xadvance=31 page=0 chnl=15 -char id=246 x=402 y=313 width=29 height=38 xoffset=1 yoffset=13 xadvance=31 page=0 chnl=15 -char id=247 x=219 y=391 width=28 height=21 xoffset=1 yoffset=21 xadvance=30 page=0 chnl=15 -char id=248 x=63 y=362 width=28 height=32 xoffset=3 yoffset=20 xadvance=34 page=0 chnl=15 -char id=249 x=163 y=196 width=25 height=41 xoffset=3 yoffset=10 xadvance=31 page=0 chnl=15 -char id=250 x=137 y=196 width=25 height=41 xoffset=3 yoffset=10 xadvance=31 page=0 chnl=15 -char id=251 x=111 y=196 width=25 height=41 xoffset=3 yoffset=10 xadvance=31 page=0 chnl=15 -char id=252 x=0 y=362 width=25 height=38 xoffset=3 yoffset=13 xadvance=31 page=0 chnl=15 -char id=253 x=309 y=0 width=27 height=52 xoffset=0 yoffset=10 xadvance=28 page=0 chnl=15 -char id=254 x=133 y=53 width=27 height=51 xoffset=3 yoffset=11 xadvance=31 page=0 chnl=15 -char id=255 x=33 y=105 width=27 height=49 xoffset=0 yoffset=13 xadvance=28 page=0 chnl=15 -kernings count=92 -kerning first=32 second=65 amount=-3 -kerning first=32 second=84 amount=-1 -kerning first=32 second=89 amount=-1 -kerning first=121 second=46 amount=-4 -kerning first=121 second=44 amount=-4 -kerning first=119 second=46 amount=-3 -kerning first=119 second=44 amount=-3 -kerning first=118 second=46 amount=-4 -kerning first=118 second=44 amount=-4 -kerning first=114 second=46 amount=-3 -kerning first=49 second=49 amount=-4 -kerning first=65 second=32 amount=-3 -kerning first=65 second=84 amount=-4 -kerning first=65 second=86 amount=-4 -kerning first=65 second=87 amount=-2 -kerning first=65 second=89 amount=-4 -kerning first=65 second=118 amount=-1 -kerning first=65 second=119 amount=-1 -kerning first=65 second=121 amount=-1 -kerning first=114 second=44 amount=-3 -kerning first=70 second=44 amount=-6 -kerning first=70 second=46 amount=-6 -kerning first=70 second=65 amount=-3 -kerning first=76 second=32 amount=-2 -kerning first=76 second=84 amount=-4 -kerning first=76 second=86 amount=-4 -kerning first=76 second=87 amount=-4 -kerning first=76 second=89 amount=-4 -kerning first=76 second=121 amount=-2 -kerning first=102 second=102 amount=-1 -kerning first=80 second=32 amount=-1 -kerning first=80 second=44 amount=-7 -kerning first=80 second=46 amount=-7 -kerning first=80 second=65 amount=-4 -kerning first=82 second=84 amount=-1 -kerning first=82 second=86 amount=-1 -kerning first=82 second=87 amount=-1 -kerning first=82 second=89 amount=-1 -kerning first=84 second=32 amount=-1 -kerning first=84 second=44 amount=-6 -kerning first=84 second=45 amount=-3 -kerning first=84 second=46 amount=-6 -kerning first=84 second=58 amount=-6 -kerning first=89 second=118 amount=-3 -kerning first=84 second=65 amount=-4 -kerning first=84 second=79 amount=-1 -kerning first=84 second=97 amount=-6 -kerning first=84 second=99 amount=-6 -kerning first=84 second=101 amount=-6 -kerning first=84 second=105 amount=-2 -kerning first=84 second=111 amount=-6 -kerning first=84 second=114 amount=-2 -kerning first=84 second=115 amount=-6 -kerning first=84 second=117 amount=-2 -kerning first=84 second=119 amount=-3 -kerning first=84 second=121 amount=-3 -kerning first=86 second=44 amount=-5 -kerning first=86 second=45 amount=-3 -kerning first=86 second=46 amount=-5 -kerning first=86 second=58 amount=-2 -kerning first=89 second=117 amount=-3 -kerning first=86 second=65 amount=-4 -kerning first=86 second=97 amount=-4 -kerning first=86 second=101 amount=-3 -kerning first=86 second=105 amount=-1 -kerning first=86 second=111 amount=-3 -kerning first=86 second=114 amount=-2 -kerning first=86 second=117 amount=-2 -kerning first=86 second=121 amount=-2 -kerning first=87 second=44 amount=-3 -kerning first=87 second=45 amount=-1 -kerning first=87 second=46 amount=-3 -kerning first=87 second=58 amount=-1 -kerning first=89 second=113 amount=-5 -kerning first=87 second=65 amount=-2 -kerning first=87 second=97 amount=-2 -kerning first=87 second=101 amount=-1 -kerning first=89 second=112 amount=-4 -kerning first=87 second=111 amount=-1 -kerning first=87 second=114 amount=-1 -kerning first=87 second=117 amount=-1 -kerning first=87 second=121 amount=-1 -kerning first=89 second=32 amount=-1 -kerning first=89 second=44 amount=-7 -kerning first=89 second=45 amount=-5 -kerning first=89 second=46 amount=-7 -kerning first=89 second=58 amount=-3 -kerning first=89 second=111 amount=-5 -kerning first=89 second=65 amount=-4 -kerning first=89 second=97 amount=-4 -kerning first=89 second=101 amount=-5 -kerning first=89 second=105 amount=-2 diff --git a/External tools/Myra.1.2.1.0/Assets/fonts/arial64_0.png b/External tools/Myra.1.2.1.0/Assets/fonts/arial64_0.png deleted file mode 100644 index ddb24df..0000000 Binary files a/External tools/Myra.1.2.1.0/Assets/fonts/arial64_0.png and /dev/null differ diff --git a/External tools/Myra.1.2.1.0/Assets/fonts/calibri32.fnt b/External tools/Myra.1.2.1.0/Assets/fonts/calibri32.fnt deleted file mode 100644 index 32e8475..0000000 --- a/External tools/Myra.1.2.1.0/Assets/fonts/calibri32.fnt +++ /dev/null @@ -1,985 +0,0 @@ -info face="Calibri" size=32 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 outline=0 -common lineHeight=32 base=25 scaleW=256 scaleH=256 pages=1 packed=0 alphaChnl=1 redChnl=0 greenChnl=0 blueChnl=0 -page id=0 file="calibri32_0.png" -chars count=193 -char id=0 x=254 y=0 width=0 height=1 xoffset=0 yoffset=31 xadvance=0 page=0 chnl=15 -char id=13 x=253 y=0 width=0 height=1 xoffset=0 yoffset=31 xadvance=0 page=0 chnl=15 -char id=32 x=247 y=41 width=3 height=1 xoffset=-1 yoffset=31 xadvance=6 page=0 chnl=15 -char id=33 x=216 y=62 width=4 height=18 xoffset=3 yoffset=7 xadvance=8 page=0 chnl=15 -char id=34 x=202 y=146 width=8 height=7 xoffset=1 yoffset=7 xadvance=10 page=0 chnl=15 -char id=35 x=238 y=97 width=13 height=16 xoffset=0 yoffset=9 xadvance=13 page=0 chnl=15 -char id=36 x=79 y=0 width=12 height=22 xoffset=1 yoffset=6 xadvance=13 page=0 chnl=15 -char id=37 x=226 y=62 width=18 height=17 xoffset=0 yoffset=8 xadvance=19 page=0 chnl=15 -char id=38 x=112 y=45 width=16 height=18 xoffset=1 yoffset=7 xadvance=18 page=0 chnl=15 -char id=39 x=217 y=146 width=4 height=7 xoffset=1 yoffset=7 xadvance=6 page=0 chnl=15 -char id=40 x=39 y=0 width=6 height=23 xoffset=1 yoffset=7 xadvance=8 page=0 chnl=15 -char id=41 x=46 y=0 width=6 height=23 xoffset=1 yoffset=7 xadvance=8 page=0 chnl=15 -char id=42 x=126 y=148 width=11 height=10 xoffset=1 yoffset=7 xadvance=13 page=0 chnl=15 -char id=43 x=181 y=133 width=13 height=12 xoffset=0 yoffset=12 xadvance=13 page=0 chnl=15 -char id=44 x=211 y=146 width=5 height=7 xoffset=0 yoffset=22 xadvance=6 page=0 chnl=15 -char id=45 x=68 y=166 width=8 height=2 xoffset=0 yoffset=17 xadvance=8 page=0 chnl=15 -char id=46 x=29 y=168 width=4 height=3 xoffset=1 yoffset=22 xadvance=7 page=0 chnl=15 -char id=47 x=26 y=0 width=12 height=23 xoffset=-1 yoffset=6 xadvance=10 page=0 chnl=15 -char id=48 x=210 y=99 width=13 height=16 xoffset=0 yoffset=9 xadvance=13 page=0 chnl=15 -char id=49 x=209 y=116 width=11 height=16 xoffset=1 yoffset=9 xadvance=13 page=0 chnl=15 -char id=50 x=185 y=116 width=11 height=16 xoffset=1 yoffset=9 xadvance=13 page=0 chnl=15 -char id=51 x=233 y=116 width=11 height=16 xoffset=1 yoffset=9 xadvance=13 page=0 chnl=15 -char id=52 x=196 y=99 width=13 height=16 xoffset=0 yoffset=9 xadvance=13 page=0 chnl=15 -char id=53 x=81 y=120 width=12 height=16 xoffset=0 yoffset=9 xadvance=13 page=0 chnl=15 -char id=54 x=42 y=121 width=12 height=16 xoffset=1 yoffset=9 xadvance=13 page=0 chnl=15 -char id=55 x=94 y=120 width=12 height=16 xoffset=1 yoffset=9 xadvance=13 page=0 chnl=15 -char id=56 x=140 y=100 width=13 height=16 xoffset=0 yoffset=9 xadvance=13 page=0 chnl=15 -char id=57 x=107 y=118 width=12 height=16 xoffset=0 yoffset=9 xadvance=13 page=0 chnl=15 -char id=58 x=84 y=151 width=4 height=12 xoffset=2 yoffset=13 xadvance=7 page=0 chnl=15 -char id=59 x=248 y=79 width=6 height=16 xoffset=0 yoffset=13 xadvance=7 page=0 chnl=15 -char id=60 x=221 y=133 width=12 height=12 xoffset=0 yoffset=12 xadvance=13 page=0 chnl=15 -char id=61 x=189 y=146 width=12 height=7 xoffset=0 yoffset=14 xadvance=13 page=0 chnl=15 -char id=62 x=208 y=133 width=12 height=12 xoffset=1 yoffset=12 xadvance=13 page=0 chnl=15 -char id=63 x=103 y=64 width=11 height=18 xoffset=1 yoffset=7 xadvance=12 page=0 chnl=15 -char id=64 x=37 y=46 width=21 height=19 xoffset=1 yoffset=9 xadvance=23 page=0 chnl=15 -char id=65 x=232 y=80 width=15 height=16 xoffset=0 yoffset=9 xadvance=15 page=0 chnl=15 -char id=66 x=14 y=121 width=13 height=16 xoffset=1 yoffset=9 xadvance=14 page=0 chnl=15 -char id=67 x=0 y=121 width=13 height=16 xoffset=1 yoffset=9 xadvance=14 page=0 chnl=15 -char id=68 x=64 y=103 width=15 height=16 xoffset=1 yoffset=9 xadvance=16 page=0 chnl=15 -char id=69 x=0 y=138 width=10 height=16 xoffset=2 yoffset=9 xadvance=13 page=0 chnl=15 -char id=70 x=197 y=116 width=11 height=16 xoffset=1 yoffset=9 xadvance=12 page=0 chnl=15 -char id=71 x=48 y=104 width=15 height=16 xoffset=0 yoffset=9 xadvance=16 page=0 chnl=15 -char id=72 x=95 y=101 width=14 height=16 xoffset=1 yoffset=9 xadvance=16 page=0 chnl=15 -char id=73 x=252 y=96 width=3 height=16 xoffset=2 yoffset=9 xadvance=7 page=0 chnl=15 -char id=74 x=20 y=138 width=8 height=16 xoffset=-1 yoffset=9 xadvance=8 page=0 chnl=15 -char id=75 x=120 y=118 width=12 height=16 xoffset=2 yoffset=9 xadvance=14 page=0 chnl=15 -char id=76 x=245 y=62 width=10 height=16 xoffset=1 yoffset=9 xadvance=11 page=0 chnl=15 -char id=77 x=177 y=82 width=20 height=16 xoffset=1 yoffset=9 xadvance=22 page=0 chnl=15 -char id=78 x=0 y=104 width=15 height=16 xoffset=1 yoffset=9 xadvance=17 page=0 chnl=15 -char id=79 x=215 y=82 width=16 height=16 xoffset=0 yoffset=9 xadvance=17 page=0 chnl=15 -char id=80 x=146 y=117 width=12 height=16 xoffset=1 yoffset=9 xadvance=13 page=0 chnl=15 -char id=81 x=93 y=45 width=18 height=18 xoffset=1 yoffset=9 xadvance=18 page=0 chnl=15 -char id=82 x=224 y=99 width=13 height=16 xoffset=1 yoffset=9 xadvance=14 page=0 chnl=15 -char id=83 x=159 y=117 width=12 height=16 xoffset=0 yoffset=9 xadvance=12 page=0 chnl=15 -char id=84 x=168 y=99 width=13 height=16 xoffset=0 yoffset=9 xadvance=13 page=0 chnl=15 -char id=85 x=32 y=104 width=15 height=16 xoffset=1 yoffset=9 xadvance=17 page=0 chnl=15 -char id=86 x=16 y=104 width=15 height=16 xoffset=0 yoffset=9 xadvance=15 page=0 chnl=15 -char id=87 x=132 y=83 width=23 height=16 xoffset=0 yoffset=9 xadvance=23 page=0 chnl=15 -char id=88 x=80 y=103 width=14 height=16 xoffset=0 yoffset=9 xadvance=14 page=0 chnl=15 -char id=89 x=28 y=121 width=13 height=16 xoffset=0 yoffset=9 xadvance=13 page=0 chnl=15 -char id=90 x=172 y=116 width=12 height=16 xoffset=0 yoffset=9 xadvance=12 page=0 chnl=15 -char id=91 x=123 y=0 width=6 height=22 xoffset=2 yoffset=7 xadvance=8 page=0 chnl=15 -char id=92 x=92 y=0 width=12 height=22 xoffset=-1 yoffset=6 xadvance=10 page=0 chnl=15 -char id=93 x=130 y=0 width=6 height=22 xoffset=0 yoffset=7 xadvance=8 page=0 chnl=15 -char id=94 x=177 y=147 width=11 height=9 xoffset=1 yoffset=9 xadvance=13 page=0 chnl=15 -char id=95 x=34 y=168 width=15 height=2 xoffset=-1 yoffset=28 xadvance=13 page=0 chnl=15 -char id=96 x=15 y=168 width=6 height=4 xoffset=1 yoffset=7 xadvance=8 page=0 chnl=15 -char id=97 x=26 y=155 width=11 height=12 xoffset=0 yoffset=13 xadvance=12 page=0 chnl=15 -char id=98 x=216 y=43 width=12 height=18 xoffset=1 yoffset=7 xadvance=14 page=0 chnl=15 -char id=99 x=50 y=154 width=11 height=12 xoffset=0 yoffset=13 xadvance=11 page=0 chnl=15 -char id=100 x=229 y=43 width=12 height=18 xoffset=1 yoffset=7 xadvance=14 page=0 chnl=15 -char id=101 x=0 y=155 width=12 height=12 xoffset=0 yoffset=13 xadvance=13 page=0 chnl=15 -char id=102 x=187 y=63 width=9 height=18 xoffset=0 yoffset=7 xadvance=8 page=0 chnl=15 -char id=103 x=107 y=83 width=12 height=17 xoffset=0 yoffset=13 xadvance=12 page=0 chnl=15 -char id=104 x=52 y=66 width=12 height=18 xoffset=1 yoffset=7 xadvance=14 page=0 chnl=15 -char id=105 x=29 y=138 width=4 height=16 xoffset=1 yoffset=9 xadvance=6 page=0 chnl=15 -char id=106 x=193 y=22 width=6 height=21 xoffset=-1 yoffset=9 xadvance=6 page=0 chnl=15 -char id=107 x=127 y=64 width=11 height=18 xoffset=1 yoffset=7 xadvance=12 page=0 chnl=15 -char id=108 x=211 y=63 width=4 height=18 xoffset=1 yoffset=7 xadvance=6 page=0 chnl=15 -char id=109 x=112 y=135 width=19 height=12 xoffset=1 yoffset=13 xadvance=21 page=0 chnl=15 -char id=110 x=13 y=155 width=12 height=12 xoffset=1 yoffset=13 xadvance=14 page=0 chnl=15 -char id=111 x=152 y=134 width=14 height=12 xoffset=0 yoffset=13 xadvance=14 page=0 chnl=15 -char id=112 x=81 y=83 width=12 height=17 xoffset=1 yoffset=13 xadvance=14 page=0 chnl=15 -char id=113 x=94 y=83 width=12 height=17 xoffset=1 yoffset=13 xadvance=14 page=0 chnl=15 -char id=114 x=247 y=131 width=8 height=12 xoffset=1 yoffset=13 xadvance=9 page=0 chnl=15 -char id=115 x=73 y=151 width=10 height=12 xoffset=0 yoffset=13 xadvance=10 page=0 chnl=15 -char id=116 x=48 y=138 width=9 height=15 xoffset=0 yoffset=10 xadvance=9 page=0 chnl=15 -char id=117 x=234 y=133 width=12 height=12 xoffset=1 yoffset=13 xadvance=14 page=0 chnl=15 -char id=118 x=195 y=133 width=12 height=12 xoffset=0 yoffset=13 xadvance=12 page=0 chnl=15 -char id=119 x=132 y=135 width=19 height=12 xoffset=0 yoffset=13 xadvance=19 page=0 chnl=15 -char id=120 x=38 y=154 width=11 height=12 xoffset=0 yoffset=13 xadvance=11 page=0 chnl=15 -char id=121 x=68 y=85 width=12 height=17 xoffset=0 yoffset=13 xadvance=12 page=0 chnl=15 -char id=122 x=62 y=153 width=10 height=12 xoffset=0 yoffset=13 xadvance=10 page=0 chnl=15 -char id=123 x=114 y=0 width=8 height=22 xoffset=0 yoffset=7 xadvance=8 page=0 chnl=15 -char id=124 x=53 y=0 width=4 height=23 xoffset=4 yoffset=7 xadvance=12 page=0 chnl=15 -char id=125 x=105 y=0 width=8 height=22 xoffset=1 yoffset=7 xadvance=8 page=0 chnl=15 -char id=126 x=236 y=146 width=13 height=5 xoffset=0 yoffset=10 xadvance=13 page=0 chnl=15 -char id=160 x=251 y=41 width=3 height=1 xoffset=-1 yoffset=31 xadvance=6 page=0 chnl=15 -char id=161 x=221 y=62 width=4 height=18 xoffset=2 yoffset=10 xadvance=8 page=0 chnl=15 -char id=162 x=245 y=114 width=10 height=16 xoffset=2 yoffset=9 xadvance=13 page=0 chnl=15 -char id=163 x=154 y=100 width=13 height=16 xoffset=0 yoffset=9 xadvance=13 page=0 chnl=15 -char id=164 x=58 y=138 width=13 height=14 xoffset=0 yoffset=11 xadvance=13 page=0 chnl=15 -char id=165 x=182 y=99 width=13 height=16 xoffset=0 yoffset=9 xadvance=13 page=0 chnl=15 -char id=166 x=58 y=0 width=3 height=23 xoffset=5 yoffset=7 xadvance=13 page=0 chnl=15 -char id=167 x=137 y=22 width=11 height=21 xoffset=1 yoffset=7 xadvance=13 page=0 chnl=15 -char id=168 x=77 y=164 width=8 height=2 xoffset=1 yoffset=9 xadvance=10 page=0 chnl=15 -char id=169 x=73 y=45 width=19 height=18 xoffset=1 yoffset=7 xadvance=22 page=0 chnl=15 -char id=170 x=82 y=137 width=8 height=13 xoffset=1 yoffset=9 xadvance=10 page=0 chnl=15 -char id=171 x=114 y=148 width=11 height=11 xoffset=1 yoffset=13 xadvance=13 page=0 chnl=15 -char id=172 x=222 y=146 width=13 height=5 xoffset=0 yoffset=17 xadvance=13 page=0 chnl=15 -char id=173 x=50 y=167 width=8 height=2 xoffset=0 yoffset=17 xadvance=8 page=0 chnl=15 -char id=174 x=138 y=148 width=11 height=10 xoffset=1 yoffset=7 xadvance=13 page=0 chnl=15 -char id=175 x=59 y=167 width=8 height=2 xoffset=1 yoffset=8 xadvance=10 page=0 chnl=15 -char id=176 x=0 y=168 width=7 height=5 xoffset=1 yoffset=8 xadvance=9 page=0 chnl=15 -char id=177 x=34 y=138 width=13 height=15 xoffset=0 yoffset=10 xadvance=13 page=0 chnl=15 -char id=178 x=150 y=148 width=9 height=10 xoffset=0 yoffset=6 xadvance=9 page=0 chnl=15 -char id=179 x=160 y=147 width=9 height=10 xoffset=0 yoffset=6 xadvance=9 page=0 chnl=15 -char id=180 x=22 y=168 width=6 height=4 xoffset=1 yoffset=7 xadvance=8 page=0 chnl=15 -char id=181 x=53 y=85 width=14 height=17 xoffset=1 yoffset=13 xadvance=14 page=0 chnl=15 -char id=182 x=59 y=46 width=13 height=19 xoffset=1 yoffset=9 xadvance=15 page=0 chnl=15 -char id=183 x=250 y=144 width=5 height=3 xoffset=1 yoffset=16 xadvance=7 page=0 chnl=15 -char id=184 x=8 y=168 width=6 height=5 xoffset=1 yoffset=25 xadvance=8 page=0 chnl=15 -char id=185 x=170 y=147 width=6 height=10 xoffset=-1 yoffset=6 xadvance=6 page=0 chnl=15 -char id=186 x=72 y=137 width=9 height=13 xoffset=1 yoffset=9 xadvance=11 page=0 chnl=15 -char id=187 x=89 y=151 width=12 height=11 xoffset=1 yoffset=13 xadvance=13 page=0 chnl=15 -char id=188 x=36 y=86 width=16 height=17 xoffset=0 yoffset=8 xadvance=17 page=0 chnl=15 -char id=189 x=18 y=86 width=17 height=17 xoffset=0 yoffset=8 xadvance=17 page=0 chnl=15 -char id=190 x=0 y=86 width=17 height=17 xoffset=0 yoffset=8 xadvance=18 page=0 chnl=15 -char id=191 x=91 y=64 width=11 height=18 xoffset=0 yoffset=10 xadvance=12 page=0 chnl=15 -char id=192 x=48 y=24 width=15 height=21 xoffset=0 yoffset=4 xadvance=15 page=0 chnl=15 -char id=193 x=64 y=23 width=15 height=21 xoffset=0 yoffset=4 xadvance=15 page=0 chnl=15 -char id=194 x=32 y=24 width=15 height=21 xoffset=0 yoffset=4 xadvance=15 page=0 chnl=15 -char id=195 x=16 y=24 width=15 height=21 xoffset=0 yoffset=4 xadvance=15 page=0 chnl=15 -char id=196 x=0 y=46 width=15 height=20 xoffset=0 yoffset=5 xadvance=15 page=0 chnl=15 -char id=197 x=0 y=24 width=15 height=21 xoffset=0 yoffset=4 xadvance=15 page=0 chnl=15 -char id=198 x=156 y=82 width=20 height=16 xoffset=-1 yoffset=9 xadvance=20 page=0 chnl=15 -char id=199 x=110 y=23 width=13 height=21 xoffset=1 yoffset=9 xadvance=14 page=0 chnl=15 -char id=200 x=149 y=22 width=10 height=21 xoffset=2 yoffset=4 xadvance=13 page=0 chnl=15 -char id=201 x=182 y=22 width=10 height=21 xoffset=2 yoffset=4 xadvance=13 page=0 chnl=15 -char id=202 x=171 y=22 width=10 height=21 xoffset=2 yoffset=4 xadvance=13 page=0 chnl=15 -char id=203 x=16 y=46 width=10 height=20 xoffset=2 yoffset=5 xadvance=13 page=0 chnl=15 -char id=204 x=207 y=22 width=6 height=21 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=15 -char id=205 x=200 y=22 width=6 height=21 xoffset=2 yoffset=4 xadvance=7 page=0 chnl=15 -char id=206 x=160 y=22 width=10 height=21 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=15 -char id=207 x=27 y=46 width=9 height=20 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=15 -char id=208 x=198 y=82 width=16 height=16 xoffset=0 yoffset=9 xadvance=16 page=0 chnl=15 -char id=209 x=237 y=0 width=15 height=21 xoffset=1 yoffset=4 xadvance=17 page=0 chnl=15 -char id=210 x=171 y=0 width=16 height=21 xoffset=0 yoffset=4 xadvance=17 page=0 chnl=15 -char id=211 x=154 y=0 width=16 height=21 xoffset=0 yoffset=4 xadvance=17 page=0 chnl=15 -char id=212 x=137 y=0 width=16 height=21 xoffset=0 yoffset=4 xadvance=17 page=0 chnl=15 -char id=213 x=188 y=0 width=16 height=21 xoffset=0 yoffset=4 xadvance=17 page=0 chnl=15 -char id=214 x=214 y=22 width=16 height=20 xoffset=0 yoffset=5 xadvance=17 page=0 chnl=15 -char id=215 x=102 y=150 width=11 height=11 xoffset=1 yoffset=12 xadvance=13 page=0 chnl=15 -char id=216 x=62 y=0 width=16 height=22 xoffset=1 yoffset=6 xadvance=17 page=0 chnl=15 -char id=217 x=221 y=0 width=15 height=21 xoffset=1 yoffset=4 xadvance=17 page=0 chnl=15 -char id=218 x=80 y=23 width=15 height=21 xoffset=1 yoffset=4 xadvance=17 page=0 chnl=15 -char id=219 x=205 y=0 width=15 height=21 xoffset=1 yoffset=4 xadvance=17 page=0 chnl=15 -char id=220 x=231 y=22 width=15 height=20 xoffset=1 yoffset=5 xadvance=17 page=0 chnl=15 -char id=221 x=96 y=23 width=13 height=21 xoffset=0 yoffset=4 xadvance=13 page=0 chnl=15 -char id=222 x=55 y=121 width=12 height=16 xoffset=1 yoffset=9 xadvance=13 page=0 chnl=15 -char id=223 x=189 y=44 width=13 height=18 xoffset=1 yoffset=7 xadvance=14 page=0 chnl=15 -char id=224 x=115 y=64 width=11 height=18 xoffset=0 yoffset=7 xadvance=12 page=0 chnl=15 -char id=225 x=175 y=63 width=11 height=18 xoffset=0 yoffset=7 xadvance=12 page=0 chnl=15 -char id=226 x=163 y=63 width=11 height=18 xoffset=0 yoffset=7 xadvance=12 page=0 chnl=15 -char id=227 x=151 y=63 width=11 height=18 xoffset=0 yoffset=7 xadvance=12 page=0 chnl=15 -char id=228 x=221 y=116 width=11 height=16 xoffset=0 yoffset=9 xadvance=12 page=0 chnl=15 -char id=229 x=139 y=64 width=11 height=18 xoffset=0 yoffset=7 xadvance=12 page=0 chnl=15 -char id=230 x=91 y=137 width=20 height=12 xoffset=0 yoffset=13 xadvance=20 page=0 chnl=15 -char id=231 x=120 y=83 width=11 height=17 xoffset=0 yoffset=13 xadvance=11 page=0 chnl=15 -char id=232 x=0 y=67 width=12 height=18 xoffset=0 yoffset=7 xadvance=13 page=0 chnl=15 -char id=233 x=13 y=67 width=12 height=18 xoffset=0 yoffset=7 xadvance=13 page=0 chnl=15 -char id=234 x=26 y=67 width=12 height=18 xoffset=0 yoffset=7 xadvance=13 page=0 chnl=15 -char id=235 x=68 y=120 width=12 height=16 xoffset=0 yoffset=9 xadvance=13 page=0 chnl=15 -char id=236 x=197 y=63 width=6 height=18 xoffset=-1 yoffset=7 xadvance=6 page=0 chnl=15 -char id=237 x=204 y=63 width=6 height=18 xoffset=1 yoffset=7 xadvance=6 page=0 chnl=15 -char id=238 x=247 y=22 width=8 height=18 xoffset=-1 yoffset=7 xadvance=6 page=0 chnl=15 -char id=239 x=11 y=138 width=8 height=16 xoffset=-1 yoffset=9 xadvance=6 page=0 chnl=15 -char id=240 x=39 y=66 width=12 height=18 xoffset=1 yoffset=7 xadvance=14 page=0 chnl=15 -char id=241 x=242 y=43 width=12 height=18 xoffset=1 yoffset=7 xadvance=14 page=0 chnl=15 -char id=242 x=144 y=44 width=14 height=18 xoffset=0 yoffset=7 xadvance=14 page=0 chnl=15 -char id=243 x=129 y=45 width=14 height=18 xoffset=0 yoffset=7 xadvance=14 page=0 chnl=15 -char id=244 x=174 y=44 width=14 height=18 xoffset=0 yoffset=7 xadvance=14 page=0 chnl=15 -char id=245 x=159 y=44 width=14 height=18 xoffset=0 yoffset=7 xadvance=14 page=0 chnl=15 -char id=246 x=110 y=101 width=14 height=16 xoffset=0 yoffset=9 xadvance=14 page=0 chnl=15 -char id=247 x=167 y=134 width=13 height=12 xoffset=0 yoffset=12 xadvance=13 page=0 chnl=15 -char id=248 x=125 y=101 width=14 height=16 xoffset=0 yoffset=11 xadvance=14 page=0 chnl=15 -char id=249 x=65 y=66 width=12 height=18 xoffset=1 yoffset=7 xadvance=14 page=0 chnl=15 -char id=250 x=78 y=64 width=12 height=18 xoffset=1 yoffset=7 xadvance=14 page=0 chnl=15 -char id=251 x=203 y=44 width=12 height=18 xoffset=1 yoffset=7 xadvance=14 page=0 chnl=15 -char id=252 x=133 y=118 width=12 height=16 xoffset=1 yoffset=9 xadvance=14 page=0 chnl=15 -char id=253 x=0 y=0 width=12 height=23 xoffset=0 yoffset=7 xadvance=12 page=0 chnl=15 -char id=254 x=13 y=0 width=12 height=23 xoffset=1 yoffset=7 xadvance=14 page=0 chnl=15 -char id=255 x=124 y=23 width=12 height=21 xoffset=0 yoffset=9 xadvance=12 page=0 chnl=15 -kernings count=787 -kerning first=179 second=47 amount=-4 -kerning first=178 second=47 amount=-4 -kerning first=185 second=47 amount=-4 -kerning first=40 second=106 amount=1 -kerning first=47 second=179 amount=-3 -kerning first=47 second=178 amount=-3 -kerning first=47 second=185 amount=-2 -kerning first=47 second=198 amount=-1 -kerning first=47 second=197 amount=-1 -kerning first=47 second=196 amount=-1 -kerning first=47 second=195 amount=-1 -kerning first=47 second=194 amount=-1 -kerning first=47 second=193 amount=-1 -kerning first=47 second=192 amount=-1 -kerning first=47 second=65 amount=-1 -kerning first=46 second=255 amount=-1 -kerning first=46 second=253 amount=-1 -kerning first=46 second=121 amount=-1 -kerning first=46 second=119 amount=-1 -kerning first=46 second=118 amount=-1 -kerning first=46 second=116 amount=-1 -kerning first=46 second=102 amount=-1 -kerning first=46 second=221 amount=-2 -kerning first=46 second=89 amount=-2 -kerning first=65 second=84 amount=-2 -kerning first=46 second=87 amount=-2 -kerning first=46 second=86 amount=-2 -kerning first=46 second=84 amount=-2 -kerning first=44 second=116 amount=-1 -kerning first=44 second=221 amount=-2 -kerning first=44 second=89 amount=-2 -kerning first=44 second=87 amount=-2 -kerning first=44 second=86 amount=-2 -kerning first=44 second=84 amount=-2 -kerning first=191 second=255 amount=-1 -kerning first=191 second=253 amount=-1 -kerning first=191 second=121 amount=-1 -kerning first=191 second=119 amount=-1 -kerning first=65 second=86 amount=-1 -kerning first=65 second=87 amount=-1 -kerning first=191 second=118 amount=-1 -kerning first=191 second=102 amount=-1 -kerning first=191 second=221 amount=-1 -kerning first=191 second=89 amount=-1 -kerning first=65 second=89 amount=-2 -kerning first=191 second=86 amount=-1 -kerning first=65 second=221 amount=-2 -kerning first=191 second=84 amount=-1 -kerning first=122 second=113 amount=-1 -kerning first=65 second=116 amount=-1 -kerning first=122 second=248 amount=-1 -kerning first=122 second=246 amount=-1 -kerning first=122 second=245 amount=-1 -kerning first=65 second=121 amount=-1 -kerning first=122 second=244 amount=-1 -kerning first=65 second=253 amount=-1 -kerning first=122 second=243 amount=-1 -kerning first=65 second=255 amount=-1 -kerning first=65 second=63 amount=-1 -kerning first=122 second=242 amount=-1 -kerning first=122 second=111 amount=-1 -kerning first=122 second=235 amount=-1 -kerning first=122 second=234 amount=-1 -kerning first=122 second=233 amount=-1 -kerning first=122 second=232 amount=-1 -kerning first=122 second=101 amount=-1 -kerning first=122 second=100 amount=-1 -kerning first=122 second=231 amount=-1 -kerning first=122 second=99 amount=-1 -kerning first=255 second=46 amount=-2 -kerning first=255 second=44 amount=-2 -kerning first=253 second=46 amount=-2 -kerning first=253 second=44 amount=-2 -kerning first=121 second=46 amount=-2 -kerning first=121 second=44 amount=-2 -kerning first=120 second=113 amount=-1 -kerning first=120 second=248 amount=-1 -kerning first=120 second=246 amount=-1 -kerning first=120 second=245 amount=-1 -kerning first=120 second=244 amount=-1 -kerning first=120 second=243 amount=-1 -kerning first=120 second=242 amount=-1 -kerning first=120 second=111 amount=-1 -kerning first=120 second=235 amount=-1 -kerning first=120 second=234 amount=-1 -kerning first=120 second=233 amount=-1 -kerning first=120 second=232 amount=-1 -kerning first=120 second=101 amount=-1 -kerning first=120 second=100 amount=-1 -kerning first=120 second=231 amount=-1 -kerning first=120 second=99 amount=-1 -kerning first=119 second=46 amount=-2 -kerning first=119 second=44 amount=-2 -kerning first=118 second=46 amount=-2 -kerning first=118 second=44 amount=-2 -kerning first=223 second=255 amount=-1 -kerning first=223 second=253 amount=-1 -kerning first=223 second=121 amount=-1 -kerning first=114 second=46 amount=-3 -kerning first=114 second=44 amount=-2 -kerning first=114 second=230 amount=-1 -kerning first=114 second=229 amount=-1 -kerning first=114 second=228 amount=-1 -kerning first=114 second=227 amount=-1 -kerning first=114 second=226 amount=-1 -kerning first=114 second=225 amount=-1 -kerning first=114 second=224 amount=-1 -kerning first=114 second=97 amount=-1 -kerning first=254 second=120 amount=-1 -kerning first=112 second=120 amount=-1 -kerning first=248 second=120 amount=-1 -kerning first=246 second=120 amount=-1 -kerning first=245 second=120 amount=-1 -kerning first=244 second=120 amount=-1 -kerning first=243 second=120 amount=-1 -kerning first=242 second=120 amount=-1 -kerning first=111 second=120 amount=-1 -kerning first=192 second=84 amount=-2 -kerning first=107 second=113 amount=-1 -kerning first=107 second=248 amount=-1 -kerning first=107 second=246 amount=-1 -kerning first=107 second=245 amount=-1 -kerning first=107 second=244 amount=-1 -kerning first=107 second=243 amount=-1 -kerning first=107 second=242 amount=-1 -kerning first=107 second=111 amount=-1 -kerning first=107 second=235 amount=-1 -kerning first=107 second=234 amount=-1 -kerning first=107 second=233 amount=-1 -kerning first=107 second=232 amount=-1 -kerning first=107 second=101 amount=-1 -kerning first=192 second=86 amount=-1 -kerning first=192 second=87 amount=-1 -kerning first=107 second=100 amount=-1 -kerning first=107 second=231 amount=-1 -kerning first=107 second=99 amount=-1 -kerning first=103 second=47 amount=1 -kerning first=192 second=89 amount=-2 -kerning first=102 second=46 amount=-2 -kerning first=192 second=221 amount=-2 -kerning first=102 second=44 amount=-2 -kerning first=102 second=113 amount=-1 -kerning first=192 second=116 amount=-1 -kerning first=102 second=248 amount=-1 -kerning first=102 second=246 amount=-1 -kerning first=102 second=245 amount=-1 -kerning first=192 second=121 amount=-1 -kerning first=102 second=244 amount=-1 -kerning first=192 second=253 amount=-1 -kerning first=102 second=243 amount=-1 -kerning first=192 second=255 amount=-1 -kerning first=192 second=63 amount=-1 -kerning first=102 second=242 amount=-1 -kerning first=102 second=111 amount=-1 -kerning first=102 second=103 amount=-1 -kerning first=102 second=235 amount=-1 -kerning first=102 second=234 amount=-1 -kerning first=102 second=233 amount=-1 -kerning first=102 second=232 amount=-1 -kerning first=102 second=101 amount=-1 -kerning first=102 second=100 amount=-1 -kerning first=102 second=231 amount=-1 -kerning first=102 second=99 amount=-1 -kerning first=102 second=230 amount=-1 -kerning first=102 second=229 amount=-1 -kerning first=102 second=228 amount=-1 -kerning first=102 second=227 amount=-1 -kerning first=102 second=226 amount=-1 -kerning first=102 second=225 amount=-1 -kerning first=102 second=224 amount=-1 -kerning first=102 second=97 amount=-1 -kerning first=98 second=120 amount=-1 -kerning first=90 second=118 amount=-1 -kerning first=90 second=239 amount=1 -kerning first=90 second=238 amount=1 -kerning first=221 second=47 amount=-2 -kerning first=221 second=46 amount=-3 -kerning first=221 second=58 amount=-2 -kerning first=221 second=59 amount=-2 -kerning first=221 second=44 amount=-3 -kerning first=221 second=122 amount=-1 -kerning first=221 second=255 amount=-1 -kerning first=221 second=253 amount=-1 -kerning first=221 second=121 amount=-1 -kerning first=221 second=120 amount=-1 -kerning first=221 second=119 amount=-1 -kerning first=221 second=118 amount=-1 -kerning first=221 second=252 amount=-1 -kerning first=221 second=251 amount=-1 -kerning first=221 second=250 amount=-1 -kerning first=221 second=249 amount=-1 -kerning first=221 second=117 amount=-1 -kerning first=221 second=116 amount=-1 -kerning first=221 second=223 amount=-1 -kerning first=221 second=115 amount=-1 -kerning first=221 second=114 amount=-1 -kerning first=221 second=113 amount=-2 -kerning first=221 second=112 amount=-1 -kerning first=221 second=248 amount=-2 -kerning first=221 second=246 amount=-2 -kerning first=221 second=245 amount=-2 -kerning first=221 second=244 amount=-2 -kerning first=221 second=243 amount=-2 -kerning first=221 second=242 amount=-2 -kerning first=221 second=111 amount=-2 -kerning first=221 second=241 amount=-1 -kerning first=221 second=110 amount=-1 -kerning first=221 second=109 amount=-1 -kerning first=221 second=106 amount=-1 -kerning first=221 second=239 amount=1 -kerning first=193 second=84 amount=-2 -kerning first=221 second=238 amount=1 -kerning first=221 second=237 amount=-1 -kerning first=221 second=236 amount=1 -kerning first=221 second=103 amount=-2 -kerning first=221 second=102 amount=-1 -kerning first=221 second=235 amount=-2 -kerning first=221 second=234 amount=-2 -kerning first=221 second=233 amount=-2 -kerning first=221 second=232 amount=-2 -kerning first=221 second=101 amount=-2 -kerning first=221 second=100 amount=-2 -kerning first=221 second=231 amount=-2 -kerning first=221 second=99 amount=-2 -kerning first=193 second=86 amount=-1 -kerning first=193 second=87 amount=-1 -kerning first=221 second=230 amount=-2 -kerning first=221 second=229 amount=-2 -kerning first=221 second=228 amount=-2 -kerning first=221 second=227 amount=-2 -kerning first=193 second=89 amount=-2 -kerning first=221 second=226 amount=-2 -kerning first=193 second=221 amount=-2 -kerning first=221 second=225 amount=-2 -kerning first=221 second=224 amount=-2 -kerning first=193 second=116 amount=-1 -kerning first=221 second=97 amount=-2 -kerning first=221 second=81 amount=-1 -kerning first=221 second=214 amount=-1 -kerning first=193 second=121 amount=-1 -kerning first=221 second=213 amount=-1 -kerning first=193 second=253 amount=-1 -kerning first=221 second=212 amount=-1 -kerning first=193 second=255 amount=-1 -kerning first=193 second=63 amount=-1 -kerning first=221 second=211 amount=-1 -kerning first=221 second=210 amount=-1 -kerning first=221 second=79 amount=-1 -kerning first=221 second=74 amount=-1 -kerning first=221 second=71 amount=-1 -kerning first=221 second=199 amount=-1 -kerning first=221 second=67 amount=-1 -kerning first=221 second=198 amount=-2 -kerning first=221 second=197 amount=-2 -kerning first=221 second=196 amount=-2 -kerning first=221 second=195 amount=-2 -kerning first=221 second=194 amount=-2 -kerning first=221 second=193 amount=-2 -kerning first=221 second=192 amount=-2 -kerning first=221 second=65 amount=-2 -kerning first=89 second=47 amount=-2 -kerning first=89 second=46 amount=-3 -kerning first=89 second=58 amount=-2 -kerning first=89 second=59 amount=-2 -kerning first=89 second=44 amount=-3 -kerning first=89 second=122 amount=-1 -kerning first=89 second=255 amount=-1 -kerning first=89 second=253 amount=-1 -kerning first=89 second=121 amount=-1 -kerning first=89 second=120 amount=-1 -kerning first=89 second=119 amount=-1 -kerning first=89 second=118 amount=-1 -kerning first=89 second=252 amount=-1 -kerning first=89 second=251 amount=-1 -kerning first=89 second=250 amount=-1 -kerning first=89 second=249 amount=-1 -kerning first=89 second=117 amount=-1 -kerning first=89 second=116 amount=-1 -kerning first=89 second=223 amount=-1 -kerning first=89 second=115 amount=-1 -kerning first=89 second=114 amount=-1 -kerning first=89 second=113 amount=-2 -kerning first=89 second=112 amount=-1 -kerning first=89 second=248 amount=-2 -kerning first=89 second=246 amount=-2 -kerning first=89 second=245 amount=-2 -kerning first=89 second=244 amount=-2 -kerning first=89 second=243 amount=-2 -kerning first=89 second=242 amount=-2 -kerning first=89 second=111 amount=-2 -kerning first=89 second=241 amount=-1 -kerning first=89 second=110 amount=-1 -kerning first=89 second=109 amount=-1 -kerning first=89 second=106 amount=-1 -kerning first=89 second=239 amount=1 -kerning first=89 second=238 amount=1 -kerning first=89 second=237 amount=-1 -kerning first=89 second=236 amount=1 -kerning first=89 second=103 amount=-2 -kerning first=89 second=102 amount=-1 -kerning first=89 second=235 amount=-2 -kerning first=89 second=234 amount=-2 -kerning first=89 second=233 amount=-2 -kerning first=194 second=84 amount=-2 -kerning first=89 second=232 amount=-2 -kerning first=89 second=101 amount=-2 -kerning first=89 second=100 amount=-2 -kerning first=89 second=231 amount=-2 -kerning first=89 second=99 amount=-2 -kerning first=89 second=230 amount=-2 -kerning first=89 second=229 amount=-2 -kerning first=89 second=228 amount=-2 -kerning first=89 second=227 amount=-2 -kerning first=89 second=226 amount=-2 -kerning first=89 second=225 amount=-2 -kerning first=89 second=224 amount=-2 -kerning first=89 second=97 amount=-2 -kerning first=194 second=86 amount=-1 -kerning first=194 second=87 amount=-1 -kerning first=89 second=81 amount=-1 -kerning first=89 second=214 amount=-1 -kerning first=89 second=213 amount=-1 -kerning first=89 second=212 amount=-1 -kerning first=194 second=89 amount=-2 -kerning first=89 second=211 amount=-1 -kerning first=194 second=221 amount=-2 -kerning first=89 second=210 amount=-1 -kerning first=89 second=79 amount=-1 -kerning first=194 second=116 amount=-1 -kerning first=89 second=74 amount=-1 -kerning first=89 second=71 amount=-1 -kerning first=89 second=199 amount=-1 -kerning first=194 second=121 amount=-1 -kerning first=89 second=67 amount=-1 -kerning first=194 second=253 amount=-1 -kerning first=89 second=198 amount=-2 -kerning first=194 second=255 amount=-1 -kerning first=194 second=63 amount=-1 -kerning first=89 second=197 amount=-2 -kerning first=89 second=196 amount=-2 -kerning first=89 second=195 amount=-2 -kerning first=89 second=194 amount=-2 -kerning first=89 second=193 amount=-2 -kerning first=89 second=192 amount=-2 -kerning first=89 second=65 amount=-2 -kerning first=88 second=255 amount=-1 -kerning first=88 second=253 amount=-1 -kerning first=88 second=121 amount=-1 -kerning first=88 second=119 amount=-1 -kerning first=88 second=118 amount=-1 -kerning first=88 second=113 amount=-1 -kerning first=88 second=100 amount=-1 -kerning first=88 second=81 amount=-1 -kerning first=88 second=214 amount=-1 -kerning first=88 second=213 amount=-1 -kerning first=88 second=212 amount=-1 -kerning first=88 second=211 amount=-1 -kerning first=88 second=210 amount=-1 -kerning first=88 second=79 amount=-1 -kerning first=88 second=71 amount=-1 -kerning first=88 second=199 amount=-1 -kerning first=88 second=67 amount=-1 -kerning first=87 second=46 amount=-3 -kerning first=87 second=59 amount=-2 -kerning first=87 second=44 amount=-3 -kerning first=87 second=255 amount=-1 -kerning first=87 second=253 amount=-1 -kerning first=87 second=121 amount=-1 -kerning first=87 second=252 amount=-1 -kerning first=87 second=251 amount=-1 -kerning first=87 second=250 amount=-1 -kerning first=87 second=249 amount=-1 -kerning first=87 second=117 amount=-1 -kerning first=87 second=115 amount=-1 -kerning first=87 second=114 amount=-1 -kerning first=87 second=113 amount=-1 -kerning first=87 second=112 amount=-1 -kerning first=87 second=248 amount=-1 -kerning first=87 second=246 amount=-1 -kerning first=87 second=245 amount=-1 -kerning first=87 second=244 amount=-1 -kerning first=87 second=243 amount=-1 -kerning first=87 second=242 amount=-1 -kerning first=87 second=111 amount=-1 -kerning first=87 second=241 amount=-1 -kerning first=87 second=110 amount=-1 -kerning first=87 second=109 amount=-1 -kerning first=87 second=239 amount=1 -kerning first=87 second=103 amount=-1 -kerning first=87 second=235 amount=-1 -kerning first=87 second=234 amount=-1 -kerning first=87 second=233 amount=-1 -kerning first=87 second=232 amount=-1 -kerning first=87 second=101 amount=-1 -kerning first=87 second=100 amount=-1 -kerning first=87 second=231 amount=-1 -kerning first=195 second=84 amount=-2 -kerning first=87 second=99 amount=-1 -kerning first=87 second=230 amount=-1 -kerning first=87 second=229 amount=-1 -kerning first=87 second=228 amount=-1 -kerning first=87 second=227 amount=-1 -kerning first=87 second=226 amount=-1 -kerning first=87 second=225 amount=-1 -kerning first=87 second=224 amount=-1 -kerning first=87 second=97 amount=-1 -kerning first=87 second=74 amount=-1 -kerning first=87 second=198 amount=-2 -kerning first=87 second=197 amount=-1 -kerning first=87 second=196 amount=-1 -kerning first=195 second=86 amount=-1 -kerning first=195 second=87 amount=-1 -kerning first=87 second=195 amount=-1 -kerning first=87 second=194 amount=-1 -kerning first=87 second=193 amount=-1 -kerning first=87 second=192 amount=-1 -kerning first=195 second=89 amount=-2 -kerning first=87 second=65 amount=-1 -kerning first=195 second=221 amount=-2 -kerning first=86 second=47 amount=-1 -kerning first=86 second=46 amount=-3 -kerning first=195 second=116 amount=-1 -kerning first=86 second=58 amount=-1 -kerning first=86 second=59 amount=-1 -kerning first=86 second=44 amount=-2 -kerning first=195 second=121 amount=-1 -kerning first=86 second=122 amount=-1 -kerning first=195 second=253 amount=-1 -kerning first=86 second=252 amount=-1 -kerning first=195 second=255 amount=-1 -kerning first=195 second=63 amount=-1 -kerning first=86 second=251 amount=-1 -kerning first=86 second=250 amount=-1 -kerning first=86 second=249 amount=-1 -kerning first=86 second=117 amount=-1 -kerning first=86 second=115 amount=-1 -kerning first=86 second=114 amount=-1 -kerning first=86 second=113 amount=-1 -kerning first=86 second=112 amount=-1 -kerning first=86 second=248 amount=-1 -kerning first=86 second=246 amount=-1 -kerning first=86 second=245 amount=-1 -kerning first=86 second=244 amount=-1 -kerning first=86 second=243 amount=-1 -kerning first=86 second=242 amount=-1 -kerning first=86 second=111 amount=-1 -kerning first=86 second=241 amount=-1 -kerning first=86 second=110 amount=-1 -kerning first=86 second=109 amount=-1 -kerning first=86 second=239 amount=1 -kerning first=86 second=238 amount=1 -kerning first=86 second=236 amount=1 -kerning first=86 second=103 amount=-1 -kerning first=86 second=235 amount=-1 -kerning first=86 second=234 amount=-1 -kerning first=86 second=233 amount=-1 -kerning first=86 second=232 amount=-1 -kerning first=86 second=101 amount=-1 -kerning first=86 second=100 amount=-1 -kerning first=86 second=231 amount=-1 -kerning first=86 second=99 amount=-1 -kerning first=86 second=230 amount=-1 -kerning first=86 second=229 amount=-1 -kerning first=86 second=228 amount=-1 -kerning first=86 second=227 amount=-1 -kerning first=86 second=226 amount=-1 -kerning first=86 second=225 amount=-1 -kerning first=86 second=224 amount=-1 -kerning first=86 second=97 amount=-1 -kerning first=86 second=74 amount=-1 -kerning first=86 second=198 amount=-2 -kerning first=86 second=197 amount=-1 -kerning first=86 second=196 amount=-1 -kerning first=86 second=195 amount=-1 -kerning first=86 second=194 amount=-1 -kerning first=86 second=193 amount=-1 -kerning first=86 second=192 amount=-1 -kerning first=86 second=65 amount=-1 -kerning first=220 second=74 amount=-1 -kerning first=220 second=197 amount=-1 -kerning first=220 second=196 amount=-1 -kerning first=220 second=195 amount=-1 -kerning first=220 second=194 amount=-1 -kerning first=220 second=193 amount=-1 -kerning first=220 second=192 amount=-1 -kerning first=220 second=65 amount=-1 -kerning first=219 second=74 amount=-1 -kerning first=219 second=197 amount=-1 -kerning first=219 second=196 amount=-1 -kerning first=196 second=84 amount=-2 -kerning first=219 second=195 amount=-1 -kerning first=219 second=194 amount=-1 -kerning first=219 second=193 amount=-1 -kerning first=219 second=192 amount=-1 -kerning first=219 second=65 amount=-1 -kerning first=218 second=74 amount=-1 -kerning first=218 second=197 amount=-1 -kerning first=218 second=196 amount=-1 -kerning first=218 second=195 amount=-1 -kerning first=218 second=194 amount=-1 -kerning first=218 second=193 amount=-1 -kerning first=218 second=192 amount=-1 -kerning first=218 second=65 amount=-1 -kerning first=196 second=86 amount=-1 -kerning first=196 second=87 amount=-1 -kerning first=217 second=74 amount=-1 -kerning first=217 second=197 amount=-1 -kerning first=217 second=196 amount=-1 -kerning first=217 second=195 amount=-1 -kerning first=196 second=89 amount=-2 -kerning first=217 second=194 amount=-1 -kerning first=196 second=221 amount=-2 -kerning first=217 second=193 amount=-1 -kerning first=217 second=192 amount=-1 -kerning first=196 second=116 amount=-1 -kerning first=217 second=65 amount=-1 -kerning first=85 second=74 amount=-1 -kerning first=85 second=197 amount=-1 -kerning first=196 second=121 amount=-1 -kerning first=85 second=196 amount=-1 -kerning first=196 second=253 amount=-1 -kerning first=85 second=195 amount=-1 -kerning first=196 second=255 amount=-1 -kerning first=196 second=63 amount=-1 -kerning first=85 second=194 amount=-1 -kerning first=85 second=193 amount=-1 -kerning first=85 second=192 amount=-1 -kerning first=85 second=65 amount=-1 -kerning first=84 second=47 amount=-1 -kerning first=84 second=46 amount=-3 -kerning first=84 second=58 amount=-2 -kerning first=84 second=59 amount=-1 -kerning first=84 second=44 amount=-3 -kerning first=84 second=122 amount=-2 -kerning first=84 second=255 amount=-1 -kerning first=84 second=253 amount=-1 -kerning first=84 second=121 amount=-1 -kerning first=84 second=120 amount=-1 -kerning first=84 second=119 amount=-1 -kerning first=84 second=118 amount=-1 -kerning first=84 second=252 amount=-2 -kerning first=84 second=251 amount=-2 -kerning first=84 second=250 amount=-2 -kerning first=84 second=249 amount=-2 -kerning first=84 second=117 amount=-2 -kerning first=84 second=115 amount=-2 -kerning first=84 second=114 amount=-2 -kerning first=84 second=113 amount=-2 -kerning first=84 second=112 amount=-2 -kerning first=84 second=248 amount=-2 -kerning first=84 second=246 amount=-2 -kerning first=84 second=245 amount=-2 -kerning first=84 second=244 amount=-2 -kerning first=84 second=243 amount=-2 -kerning first=84 second=242 amount=-2 -kerning first=84 second=111 amount=-2 -kerning first=84 second=241 amount=-2 -kerning first=84 second=110 amount=-2 -kerning first=84 second=109 amount=-2 -kerning first=84 second=239 amount=1 -kerning first=84 second=238 amount=1 -kerning first=84 second=103 amount=-2 -kerning first=84 second=235 amount=-2 -kerning first=84 second=234 amount=-2 -kerning first=84 second=233 amount=-2 -kerning first=84 second=232 amount=-2 -kerning first=84 second=101 amount=-2 -kerning first=84 second=100 amount=-2 -kerning first=84 second=231 amount=-2 -kerning first=84 second=99 amount=-2 -kerning first=84 second=230 amount=-2 -kerning first=84 second=229 amount=-2 -kerning first=84 second=228 amount=-2 -kerning first=84 second=227 amount=-2 -kerning first=84 second=226 amount=-2 -kerning first=84 second=225 amount=-2 -kerning first=84 second=224 amount=-2 -kerning first=84 second=97 amount=-2 -kerning first=84 second=81 amount=-1 -kerning first=84 second=214 amount=-1 -kerning first=84 second=213 amount=-1 -kerning first=84 second=212 amount=-1 -kerning first=84 second=211 amount=-1 -kerning first=84 second=210 amount=-1 -kerning first=84 second=79 amount=-1 -kerning first=84 second=74 amount=-1 -kerning first=84 second=71 amount=-1 -kerning first=84 second=199 amount=-1 -kerning first=84 second=67 amount=-1 -kerning first=84 second=198 amount=-2 -kerning first=84 second=197 amount=-2 -kerning first=84 second=196 amount=-2 -kerning first=84 second=195 amount=-2 -kerning first=84 second=194 amount=-2 -kerning first=84 second=193 amount=-2 -kerning first=84 second=192 amount=-2 -kerning first=84 second=65 amount=-2 -kerning first=82 second=248 amount=-1 -kerning first=82 second=246 amount=-1 -kerning first=82 second=245 amount=-1 -kerning first=82 second=244 amount=-1 -kerning first=82 second=243 amount=-1 -kerning first=82 second=242 amount=-1 -kerning first=82 second=111 amount=-1 -kerning first=81 second=47 amount=2 -kerning first=81 second=59 amount=1 -kerning first=81 second=44 amount=1 -kerning first=81 second=106 amount=1 -kerning first=81 second=103 amount=1 -kerning first=81 second=221 amount=-1 -kerning first=81 second=89 amount=-1 -kerning first=81 second=84 amount=-1 -kerning first=81 second=74 amount=1 -kerning first=81 second=198 amount=1 -kerning first=80 second=47 amount=-1 -kerning first=80 second=46 amount=-3 -kerning first=80 second=44 amount=-3 -kerning first=80 second=248 amount=-1 -kerning first=80 second=246 amount=-1 -kerning first=80 second=245 amount=-1 -kerning first=80 second=244 amount=-1 -kerning first=80 second=243 amount=-1 -kerning first=80 second=242 amount=-1 -kerning first=80 second=111 amount=-1 -kerning first=80 second=235 amount=-1 -kerning first=80 second=234 amount=-1 -kerning first=80 second=233 amount=-1 -kerning first=80 second=232 amount=-1 -kerning first=80 second=101 amount=-1 -kerning first=80 second=231 amount=-1 -kerning first=80 second=99 amount=-1 -kerning first=80 second=230 amount=-1 -kerning first=80 second=229 amount=-1 -kerning first=80 second=228 amount=-1 -kerning first=80 second=227 amount=-1 -kerning first=80 second=226 amount=-1 -kerning first=80 second=225 amount=-1 -kerning first=80 second=224 amount=-1 -kerning first=80 second=97 amount=-1 -kerning first=80 second=74 amount=-2 -kerning first=80 second=198 amount=-2 -kerning first=80 second=197 amount=-2 -kerning first=80 second=196 amount=-2 -kerning first=80 second=195 amount=-2 -kerning first=80 second=194 amount=-2 -kerning first=80 second=193 amount=-2 -kerning first=80 second=192 amount=-2 -kerning first=80 second=65 amount=-2 -kerning first=214 second=44 amount=-1 -kerning first=214 second=221 amount=-1 -kerning first=214 second=89 amount=-1 -kerning first=214 second=88 amount=-1 -kerning first=214 second=84 amount=-1 -kerning first=213 second=44 amount=-1 -kerning first=213 second=221 amount=-1 -kerning first=213 second=89 amount=-1 -kerning first=213 second=88 amount=-1 -kerning first=213 second=84 amount=-1 -kerning first=212 second=44 amount=-1 -kerning first=212 second=221 amount=-1 -kerning first=212 second=89 amount=-1 -kerning first=212 second=88 amount=-1 -kerning first=212 second=84 amount=-1 -kerning first=211 second=44 amount=-1 -kerning first=211 second=221 amount=-1 -kerning first=211 second=89 amount=-1 -kerning first=211 second=88 amount=-1 -kerning first=211 second=84 amount=-1 -kerning first=210 second=44 amount=-1 -kerning first=210 second=221 amount=-1 -kerning first=210 second=89 amount=-1 -kerning first=210 second=88 amount=-1 -kerning first=210 second=84 amount=-1 -kerning first=79 second=44 amount=-1 -kerning first=79 second=221 amount=-1 -kerning first=79 second=89 amount=-1 -kerning first=79 second=88 amount=-1 -kerning first=79 second=84 amount=-1 -kerning first=76 second=255 amount=-1 -kerning first=76 second=253 amount=-1 -kerning first=76 second=121 amount=-1 -kerning first=76 second=119 amount=-1 -kerning first=76 second=118 amount=-1 -kerning first=76 second=221 amount=-2 -kerning first=76 second=89 amount=-2 -kerning first=76 second=87 amount=-2 -kerning first=76 second=86 amount=-2 -kerning first=76 second=220 amount=-1 -kerning first=76 second=219 amount=-1 -kerning first=76 second=218 amount=-1 -kerning first=76 second=217 amount=-1 -kerning first=76 second=85 amount=-1 -kerning first=76 second=84 amount=-2 -kerning first=76 second=81 amount=-1 -kerning first=76 second=214 amount=-1 -kerning first=76 second=213 amount=-1 -kerning first=76 second=212 amount=-1 -kerning first=76 second=211 amount=-1 -kerning first=76 second=210 amount=-1 -kerning first=76 second=79 amount=-1 -kerning first=76 second=71 amount=-1 -kerning first=76 second=198 amount=1 -kerning first=75 second=255 amount=-1 -kerning first=75 second=253 amount=-1 -kerning first=75 second=121 amount=-1 -kerning first=75 second=119 amount=-1 -kerning first=75 second=118 amount=-1 -kerning first=75 second=231 amount=-1 -kerning first=75 second=99 amount=-1 -kerning first=75 second=81 amount=-1 -kerning first=75 second=214 amount=-1 -kerning first=75 second=213 amount=-1 -kerning first=75 second=212 amount=-1 -kerning first=75 second=211 amount=-1 -kerning first=75 second=210 amount=-1 -kerning first=75 second=79 amount=-1 -kerning first=75 second=71 amount=-1 -kerning first=75 second=199 amount=-1 -kerning first=75 second=67 amount=-1 -kerning first=70 second=47 amount=-1 -kerning first=70 second=46 amount=-2 -kerning first=70 second=44 amount=-3 -kerning first=70 second=230 amount=-1 -kerning first=70 second=229 amount=-1 -kerning first=70 second=228 amount=-1 -kerning first=70 second=227 amount=-1 -kerning first=70 second=226 amount=-1 -kerning first=70 second=225 amount=-1 -kerning first=70 second=224 amount=-1 -kerning first=70 second=97 amount=-1 -kerning first=70 second=74 amount=-1 -kerning first=70 second=198 amount=-1 -kerning first=70 second=197 amount=-1 -kerning first=70 second=196 amount=-1 -kerning first=70 second=195 amount=-1 -kerning first=70 second=194 amount=-1 -kerning first=70 second=193 amount=-1 -kerning first=70 second=192 amount=-1 -kerning first=70 second=65 amount=-1 -kerning first=203 second=255 amount=-1 -kerning first=203 second=253 amount=-1 -kerning first=203 second=121 amount=-1 -kerning first=203 second=118 amount=-1 -kerning first=203 second=102 amount=-1 -kerning first=202 second=255 amount=-1 -kerning first=202 second=253 amount=-1 -kerning first=202 second=121 amount=-1 -kerning first=202 second=118 amount=-1 -kerning first=202 second=102 amount=-1 -kerning first=201 second=255 amount=-1 -kerning first=201 second=253 amount=-1 -kerning first=201 second=121 amount=-1 -kerning first=201 second=118 amount=-1 -kerning first=201 second=102 amount=-1 -kerning first=200 second=255 amount=-1 -kerning first=200 second=253 amount=-1 -kerning first=200 second=121 amount=-1 -kerning first=200 second=118 amount=-1 -kerning first=200 second=102 amount=-1 -kerning first=69 second=255 amount=-1 -kerning first=69 second=253 amount=-1 -kerning first=69 second=121 amount=-1 -kerning first=69 second=118 amount=-1 -kerning first=69 second=102 amount=-1 -kerning first=208 second=46 amount=-1 -kerning first=208 second=44 amount=-1 -kerning first=68 second=46 amount=-1 -kerning first=68 second=44 amount=-1 -kerning first=197 second=84 amount=-2 -kerning first=66 second=221 amount=-1 -kerning first=66 second=89 amount=-1 -kerning first=66 second=88 amount=-1 -kerning first=66 second=84 amount=-1 -kerning first=198 second=255 amount=-1 -kerning first=198 second=253 amount=-1 -kerning first=198 second=121 amount=-1 -kerning first=198 second=118 amount=-1 -kerning first=198 second=102 amount=-1 -kerning first=197 second=63 amount=-1 -kerning first=197 second=255 amount=-1 -kerning first=197 second=253 amount=-1 -kerning first=197 second=121 amount=-1 -kerning first=197 second=86 amount=-1 -kerning first=197 second=87 amount=-1 -kerning first=197 second=116 amount=-1 -kerning first=197 second=221 amount=-2 -kerning first=197 second=89 amount=-2 diff --git a/External tools/Myra.1.2.1.0/Assets/fonts/calibri32_0.png b/External tools/Myra.1.2.1.0/Assets/fonts/calibri32_0.png deleted file mode 100644 index 686ae0f..0000000 Binary files a/External tools/Myra.1.2.1.0/Assets/fonts/calibri32_0.png and /dev/null differ diff --git a/External tools/Myra.1.2.1.0/Assets/fonts/comicSans48.fnt b/External tools/Myra.1.2.1.0/Assets/fonts/comicSans48.fnt deleted file mode 100644 index 0ba8894..0000000 --- a/External tools/Myra.1.2.1.0/Assets/fonts/comicSans48.fnt +++ /dev/null @@ -1,195 +0,0 @@ -info face="Comic Sans MS" size=48 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 outline=0 -common lineHeight=47 base=37 scaleW=512 scaleH=512 pages=1 packed=0 alphaChnl=1 redChnl=0 greenChnl=0 blueChnl=0 -page id=0 file="comicSans48_0.png" -chars count=191 -char id=32 x=507 y=30 width=3 height=1 xoffset=-1 yoffset=46 xadvance=10 page=0 chnl=15 -char id=33 x=341 y=67 width=5 height=28 xoffset=1 yoffset=10 xadvance=8 page=0 chnl=15 -char id=34 x=269 y=172 width=11 height=11 xoffset=1 yoffset=11 xadvance=14 page=0 chnl=15 -char id=35 x=293 y=97 width=29 height=26 xoffset=0 yoffset=11 xadvance=29 page=0 chnl=15 -char id=36 x=441 y=0 width=20 height=34 xoffset=1 yoffset=9 xadvance=24 page=0 chnl=15 -char id=37 x=439 y=65 width=26 height=27 xoffset=2 yoffset=10 xadvance=28 page=0 chnl=15 -char id=38 x=49 y=74 width=22 height=28 xoffset=0 yoffset=11 xadvance=22 page=0 chnl=15 -char id=39 x=308 y=170 width=5 height=9 xoffset=4 yoffset=9 xadvance=13 page=0 chnl=15 -char id=40 x=82 y=38 width=11 height=34 xoffset=1 yoffset=10 xadvance=12 page=0 chnl=15 -char id=41 x=94 y=38 width=11 height=34 xoffset=1 yoffset=10 xadvance=12 page=0 chnl=15 -char id=42 x=110 y=181 width=17 height=14 xoffset=0 yoffset=10 xadvance=18 page=0 chnl=15 -char id=43 x=175 y=179 width=16 height=13 xoffset=0 yoffset=20 xadvance=16 page=0 chnl=15 -char id=44 x=370 y=168 width=6 height=8 xoffset=3 yoffset=35 xadvance=9 page=0 chnl=15 -char id=45 x=465 y=165 width=12 height=3 xoffset=1 yoffset=26 xadvance=13 page=0 chnl=15 -char id=46 x=383 y=168 width=5 height=4 xoffset=2 yoffset=35 xadvance=8 page=0 chnl=15 -char id=47 x=284 y=68 width=16 height=28 xoffset=1 yoffset=11 xadvance=17 page=0 chnl=15 -char id=48 x=112 y=130 width=21 height=26 xoffset=0 yoffset=11 xadvance=21 page=0 chnl=15 -char id=49 x=497 y=93 width=12 height=26 xoffset=2 yoffset=11 xadvance=15 page=0 chnl=15 -char id=50 x=330 y=123 width=17 height=26 xoffset=2 yoffset=11 xadvance=21 page=0 chnl=15 -char id=51 x=348 y=123 width=17 height=26 xoffset=2 yoffset=11 xadvance=21 page=0 chnl=15 -char id=52 x=134 y=128 width=21 height=26 xoffset=0 yoffset=11 xadvance=21 page=0 chnl=15 -char id=53 x=177 y=128 width=19 height=26 xoffset=1 yoffset=11 xadvance=21 page=0 chnl=15 -char id=54 x=255 y=125 width=18 height=26 xoffset=1 yoffset=11 xadvance=21 page=0 chnl=15 -char id=55 x=90 y=130 width=21 height=26 xoffset=0 yoffset=11 xadvance=21 page=0 chnl=15 -char id=56 x=197 y=127 width=19 height=26 xoffset=1 yoffset=11 xadvance=21 page=0 chnl=15 -char id=57 x=115 y=71 width=19 height=28 xoffset=1 yoffset=11 xadvance=21 page=0 chnl=15 -char id=58 x=32 y=185 width=6 height=17 xoffset=2 yoffset=18 xadvance=10 page=0 chnl=15 -char id=59 x=202 y=154 width=7 height=22 xoffset=1 yoffset=18 xadvance=10 page=0 chnl=15 -char id=60 x=140 y=181 width=11 height=14 xoffset=0 yoffset=20 xadvance=13 page=0 chnl=15 -char id=61 x=239 y=174 width=14 height=12 xoffset=1 yoffset=20 xadvance=17 page=0 chnl=15 -char id=62 x=56 y=184 width=13 height=16 xoffset=0 yoffset=18 xadvance=13 page=0 chnl=15 -char id=63 x=456 y=120 width=16 height=26 xoffset=0 yoffset=12 xadvance=17 page=0 chnl=15 -char id=64 x=423 y=35 width=27 height=29 xoffset=1 yoffset=10 xadvance=30 page=0 chnl=15 -char id=65 x=0 y=132 width=22 height=26 xoffset=1 yoffset=11 xadvance=24 page=0 chnl=15 -char id=66 x=19 y=104 width=18 height=27 xoffset=2 yoffset=11 xadvance=21 page=0 chnl=15 -char id=67 x=466 y=65 width=20 height=27 xoffset=1 yoffset=10 xadvance=20 page=0 chnl=15 -char id=68 x=26 y=75 width=22 height=28 xoffset=2 yoffset=11 xadvance=25 page=0 chnl=15 -char id=69 x=95 y=73 width=19 height=28 xoffset=2 yoffset=11 xadvance=21 page=0 chnl=15 -char id=70 x=135 y=71 width=19 height=28 xoffset=2 yoffset=11 xadvance=21 page=0 chnl=15 -char id=71 x=23 y=132 width=22 height=26 xoffset=1 yoffset=11 xadvance=23 page=0 chnl=15 -char id=72 x=450 y=93 width=23 height=26 xoffset=2 yoffset=11 xadvance=26 page=0 chnl=15 -char id=73 x=402 y=121 width=17 height=26 xoffset=1 yoffset=11 xadvance=19 page=0 chnl=15 -char id=74 x=72 y=73 width=22 height=28 xoffset=1 yoffset=11 xadvance=23 page=0 chnl=15 -char id=75 x=174 y=70 width=18 height=28 xoffset=3 yoffset=11 xadvance=21 page=0 chnl=15 -char id=76 x=212 y=69 width=18 height=28 xoffset=1 yoffset=11 xadvance=19 page=0 chnl=15 -char id=77 x=382 y=66 width=28 height=27 xoffset=1 yoffset=11 xadvance=29 page=0 chnl=15 -char id=78 x=349 y=94 width=25 height=26 xoffset=1 yoffset=11 xadvance=27 page=0 chnl=15 -char id=79 x=323 y=96 width=25 height=26 xoffset=1 yoffset=11 xadvance=27 page=0 chnl=15 -char id=80 x=420 y=121 width=17 height=26 xoffset=1 yoffset=11 xadvance=18 page=0 chnl=15 -char id=81 x=106 y=37 width=29 height=33 xoffset=1 yoffset=11 xadvance=30 page=0 chnl=15 -char id=82 x=156 y=128 width=20 height=26 xoffset=1 yoffset=11 xadvance=21 page=0 chnl=15 -char id=83 x=473 y=120 width=21 height=25 xoffset=2 yoffset=13 xadvance=24 page=0 chnl=15 -char id=84 x=375 y=94 width=24 height=26 xoffset=1 yoffset=11 xadvance=23 page=0 chnl=15 -char id=85 x=474 y=93 width=22 height=26 xoffset=2 yoffset=11 xadvance=25 page=0 chnl=15 -char id=86 x=46 y=132 width=21 height=26 xoffset=2 yoffset=11 xadvance=22 page=0 chnl=15 -char id=87 x=347 y=66 width=34 height=27 xoffset=2 yoffset=11 xadvance=35 page=0 chnl=15 -char id=88 x=425 y=93 width=24 height=26 xoffset=0 yoffset=11 xadvance=25 page=0 chnl=15 -char id=89 x=68 y=131 width=21 height=26 xoffset=0 yoffset=12 xadvance=22 page=0 chnl=15 -char id=90 x=400 y=94 width=24 height=26 xoffset=0 yoffset=11 xadvance=24 page=0 chnl=15 -char id=91 x=238 y=36 width=11 height=32 xoffset=2 yoffset=12 xadvance=13 page=0 chnl=15 -char id=92 x=318 y=67 width=16 height=28 xoffset=2 yoffset=11 xadvance=19 page=0 chnl=15 -char id=93 x=226 y=36 width=11 height=32 xoffset=2 yoffset=12 xadvance=13 page=0 chnl=15 -char id=94 x=281 y=171 width=15 height=9 xoffset=3 yoffset=10 xadvance=19 page=0 chnl=15 -char id=95 x=413 y=166 width=23 height=3 xoffset=-1 yoffset=40 xadvance=21 page=0 chnl=15 -char id=96 x=361 y=169 width=8 height=8 xoffset=2 yoffset=10 xadvance=19 page=0 chnl=15 -char id=97 x=460 y=147 width=17 height=17 xoffset=0 yoffset=20 xadvance=17 page=0 chnl=15 -char id=98 x=114 y=102 width=17 height=27 xoffset=2 yoffset=10 xadvance=20 page=0 chnl=15 -char id=99 x=0 y=185 width=15 height=17 xoffset=1 yoffset=20 xadvance=17 page=0 chnl=15 -char id=100 x=38 y=104 width=18 height=27 xoffset=1 yoffset=10 xadvance=20 page=0 chnl=15 -char id=101 x=405 y=148 width=18 height=17 xoffset=1 yoffset=20 xadvance=19 page=0 chnl=15 -char id=102 x=494 y=35 width=16 height=29 xoffset=0 yoffset=10 xadvance=17 page=0 chnl=15 -char id=103 x=366 y=121 width=17 height=26 xoffset=0 yoffset=20 xadvance=18 page=0 chnl=15 -char id=104 x=132 y=100 width=17 height=27 xoffset=2 yoffset=10 xadvance=20 page=0 chnl=15 -char id=105 x=101 y=157 width=6 height=24 xoffset=2 yoffset=13 xadvance=10 page=0 chnl=15 -char id=106 x=40 y=39 width=13 height=34 xoffset=-1 yoffset=13 xadvance=14 page=0 chnl=15 -char id=107 x=150 y=100 width=17 height=27 xoffset=2 yoffset=11 xadvance=18 page=0 chnl=15 -char id=108 x=335 y=67 width=5 height=28 xoffset=2 yoffset=10 xadvance=9 page=0 chnl=15 -char id=109 x=276 y=152 width=25 height=18 xoffset=1 yoffset=20 xadvance=26 page=0 chnl=15 -char id=110 x=442 y=147 width=17 height=17 xoffset=1 yoffset=20 xadvance=18 page=0 chnl=15 -char id=111 x=495 y=146 width=16 height=17 xoffset=1 yoffset=20 xadvance=18 page=0 chnl=15 -char id=112 x=301 y=68 width=16 height=28 xoffset=1 yoffset=19 xadvance=18 page=0 chnl=15 -char id=113 x=312 y=124 width=17 height=26 xoffset=0 yoffset=20 xadvance=18 page=0 chnl=15 -char id=114 x=16 y=185 width=15 height=17 xoffset=1 yoffset=20 xadvance=16 page=0 chnl=15 -char id=115 x=227 y=154 width=16 height=19 xoffset=0 yoffset=18 xadvance=17 page=0 chnl=15 -char id=116 x=145 y=155 width=16 height=23 xoffset=0 yoffset=14 xadvance=16 page=0 chnl=15 -char id=117 x=478 y=146 width=16 height=17 xoffset=1 yoffset=20 xadvance=18 page=0 chnl=15 -char id=118 x=345 y=150 width=17 height=18 xoffset=0 yoffset=20 xadvance=17 page=0 chnl=15 -char id=119 x=363 y=150 width=22 height=17 xoffset=1 yoffset=20 xadvance=23 page=0 chnl=15 -char id=120 x=324 y=151 width=20 height=18 xoffset=0 yoffset=20 xadvance=20 page=0 chnl=15 -char id=121 x=487 y=65 width=19 height=27 xoffset=-1 yoffset=20 xadvance=18 page=0 chnl=15 -char id=122 x=424 y=148 width=17 height=17 xoffset=1 yoffset=20 xadvance=18 page=0 chnl=15 -char id=123 x=68 y=38 width=13 height=34 xoffset=-1 yoffset=10 xadvance=12 page=0 chnl=15 -char id=124 x=502 y=0 width=4 height=34 xoffset=5 yoffset=9 xadvance=14 page=0 chnl=15 -char id=125 x=54 y=39 width=13 height=34 xoffset=-1 yoffset=10 xadvance=12 page=0 chnl=15 -char id=126 x=314 y=170 width=19 height=8 xoffset=1 yoffset=21 xadvance=19 page=0 chnl=15 -char id=160 x=507 y=28 width=3 height=1 xoffset=-1 yoffset=46 xadvance=10 page=0 chnl=15 -char id=161 x=287 y=97 width=5 height=27 xoffset=1 yoffset=11 xadvance=8 page=0 chnl=15 -char id=162 x=193 y=70 width=18 height=28 xoffset=1 yoffset=8 xadvance=21 page=0 chnl=15 -char id=163 x=317 y=36 width=25 height=30 xoffset=0 yoffset=10 xadvance=27 page=0 chnl=15 -char id=164 x=302 y=151 width=21 height=18 xoffset=0 yoffset=16 xadvance=21 page=0 chnl=15 -char id=165 x=81 y=158 width=19 height=24 xoffset=2 yoffset=13 xadvance=22 page=0 chnl=15 -char id=166 x=507 y=0 width=4 height=27 xoffset=5 yoffset=10 xadvance=14 page=0 chnl=15 -char id=167 x=236 y=126 width=18 height=26 xoffset=1 yoffset=11 xadvance=22 page=0 chnl=15 -char id=168 x=437 y=166 width=14 height=3 xoffset=3 yoffset=14 xadvance=19 page=0 chnl=15 -char id=169 x=177 y=155 width=24 height=22 xoffset=1 yoffset=10 xadvance=26 page=0 chnl=15 -char id=170 x=225 y=174 width=13 height=13 xoffset=1 yoffset=9 xadvance=16 page=0 chnl=15 -char id=171 x=90 y=183 width=19 height=14 xoffset=0 yoffset=20 xadvance=20 page=0 chnl=15 -char id=172 x=334 y=170 width=16 height=8 xoffset=0 yoffset=25 xadvance=16 page=0 chnl=15 -char id=173 x=452 y=165 width=12 height=3 xoffset=1 yoffset=26 xadvance=13 page=0 chnl=15 -char id=174 x=35 y=159 width=24 height=24 xoffset=1 yoffset=10 xadvance=26 page=0 chnl=15 -char id=175 x=389 y=166 width=23 height=3 xoffset=-1 yoffset=6 xadvance=21 page=0 chnl=15 -char id=176 x=254 y=172 width=14 height=12 xoffset=0 yoffset=9 xadvance=14 page=0 chnl=15 -char id=177 x=210 y=154 width=16 height=19 xoffset=0 yoffset=20 xadvance=16 page=0 chnl=15 -char id=178 x=128 y=181 width=11 height=14 xoffset=6 yoffset=8 xadvance=22 page=0 chnl=15 -char id=179 x=164 y=179 width=10 height=14 xoffset=6 yoffset=9 xadvance=22 page=0 chnl=15 -char id=180 x=351 y=169 width=9 height=8 xoffset=3 yoffset=10 xadvance=17 page=0 chnl=15 -char id=181 x=60 y=159 width=20 height=24 xoffset=0 yoffset=20 xadvance=18 page=0 chnl=15 -char id=182 x=451 y=35 width=23 height=29 xoffset=0 yoffset=11 xadvance=24 page=0 chnl=15 -char id=183 x=377 y=168 width=5 height=4 xoffset=2 yoffset=24 xadvance=8 page=0 chnl=15 -char id=184 x=297 y=171 width=10 height=9 xoffset=5 yoffset=35 xadvance=19 page=0 chnl=15 -char id=185 x=152 y=179 width=11 height=14 xoffset=6 yoffset=8 xadvance=22 page=0 chnl=15 -char id=186 x=192 y=178 width=16 height=13 xoffset=0 yoffset=9 xadvance=16 page=0 chnl=15 -char id=187 x=70 y=184 width=19 height=14 xoffset=0 yoffset=20 xadvance=20 page=0 chnl=15 -char id=188 x=20 y=40 width=19 height=34 xoffset=2 yoffset=9 xadvance=22 page=0 chnl=15 -char id=189 x=0 y=40 width=19 height=34 xoffset=2 yoffset=9 xadvance=22 page=0 chnl=15 -char id=190 x=482 y=0 width=19 height=34 xoffset=2 yoffset=9 xadvance=22 page=0 chnl=15 -char id=191 x=438 y=120 width=17 height=26 xoffset=0 yoffset=12 xadvance=17 page=0 chnl=15 -char id=192 x=241 y=0 width=22 height=35 xoffset=1 yoffset=2 xadvance=24 page=0 chnl=15 -char id=193 x=418 y=0 width=22 height=34 xoffset=1 yoffset=3 xadvance=24 page=0 chnl=15 -char id=194 x=218 y=0 width=22 height=35 xoffset=1 yoffset=2 xadvance=24 page=0 chnl=15 -char id=195 x=136 y=37 width=24 height=33 xoffset=1 yoffset=4 xadvance=24 page=0 chnl=15 -char id=196 x=343 y=35 width=22 height=30 xoffset=1 yoffset=7 xadvance=24 page=0 chnl=15 -char id=197 x=161 y=36 width=22 height=33 xoffset=1 yoffset=4 xadvance=24 page=0 chnl=15 -char id=198 x=383 y=35 width=39 height=29 xoffset=0 yoffset=10 xadvance=38 page=0 chnl=15 -char id=199 x=205 y=36 width=20 height=32 xoffset=1 yoffset=11 xadvance=20 page=0 chnl=15 -char id=200 x=40 y=0 width=19 height=38 xoffset=2 yoffset=1 xadvance=21 page=0 chnl=15 -char id=201 x=20 y=0 width=19 height=39 xoffset=2 yoffset=0 xadvance=21 page=0 chnl=15 -char id=202 x=0 y=0 width=19 height=39 xoffset=2 yoffset=0 xadvance=21 page=0 chnl=15 -char id=203 x=462 y=0 width=19 height=34 xoffset=2 yoffset=5 xadvance=21 page=0 chnl=15 -char id=204 x=287 y=0 width=17 height=35 xoffset=1 yoffset=2 xadvance=19 page=0 chnl=15 -char id=205 x=305 y=0 width=17 height=35 xoffset=1 yoffset=2 xadvance=19 page=0 chnl=15 -char id=206 x=125 y=0 width=17 height=36 xoffset=1 yoffset=1 xadvance=19 page=0 chnl=15 -char id=207 x=299 y=36 width=17 height=31 xoffset=1 yoffset=6 xadvance=19 page=0 chnl=15 -char id=208 x=0 y=75 width=25 height=28 xoffset=-1 yoffset=11 xadvance=25 page=0 chnl=15 -char id=209 x=340 y=0 width=25 height=34 xoffset=1 yoffset=3 xadvance=27 page=0 chnl=15 -char id=210 x=169 y=0 width=25 height=35 xoffset=1 yoffset=2 xadvance=27 page=0 chnl=15 -char id=211 x=392 y=0 width=25 height=34 xoffset=1 yoffset=3 xadvance=27 page=0 chnl=15 -char id=212 x=143 y=0 width=25 height=35 xoffset=1 yoffset=2 xadvance=27 page=0 chnl=15 -char id=213 x=366 y=0 width=25 height=34 xoffset=1 yoffset=3 xadvance=27 page=0 chnl=15 -char id=214 x=250 y=36 width=25 height=31 xoffset=1 yoffset=6 xadvance=27 page=0 chnl=15 -char id=215 x=209 y=177 width=15 height=13 xoffset=0 yoffset=20 xadvance=16 page=0 chnl=15 -char id=216 x=411 y=65 width=27 height=27 xoffset=1 yoffset=11 xadvance=27 page=0 chnl=15 -char id=217 x=195 y=0 width=22 height=35 xoffset=2 yoffset=2 xadvance=25 page=0 chnl=15 -char id=218 x=264 y=0 width=22 height=35 xoffset=2 yoffset=2 xadvance=25 page=0 chnl=15 -char id=219 x=102 y=0 width=22 height=36 xoffset=2 yoffset=1 xadvance=25 page=0 chnl=15 -char id=220 x=276 y=36 width=22 height=31 xoffset=2 yoffset=6 xadvance=25 page=0 chnl=15 -char id=221 x=60 y=0 width=21 height=37 xoffset=0 yoffset=1 xadvance=22 page=0 chnl=15 -char id=222 x=384 y=121 width=17 height=26 xoffset=1 yoffset=11 xadvance=18 page=0 chnl=15 -char id=223 x=366 y=35 width=16 height=30 xoffset=0 yoffset=10 xadvance=16 page=0 chnl=15 -char id=224 x=0 y=104 width=18 height=27 xoffset=0 yoffset=10 xadvance=17 page=0 chnl=15 -char id=225 x=76 y=102 width=18 height=27 xoffset=0 yoffset=10 xadvance=17 page=0 chnl=15 -char id=226 x=231 y=69 width=18 height=28 xoffset=0 yoffset=9 xadvance=17 page=0 chnl=15 -char id=227 x=217 y=127 width=18 height=26 xoffset=0 yoffset=11 xadvance=17 page=0 chnl=15 -char id=228 x=108 y=157 width=18 height=23 xoffset=0 yoffset=14 xadvance=17 page=0 chnl=15 -char id=229 x=475 y=35 width=18 height=29 xoffset=0 yoffset=8 xadvance=17 page=0 chnl=15 -char id=230 x=244 y=153 width=31 height=18 xoffset=0 yoffset=20 xadvance=31 page=0 chnl=15 -char id=231 x=19 y=159 width=15 height=25 xoffset=1 yoffset=20 xadvance=17 page=0 chnl=15 -char id=232 x=57 y=103 width=18 height=27 xoffset=1 yoffset=10 xadvance=19 page=0 chnl=15 -char id=233 x=95 y=102 width=18 height=27 xoffset=1 yoffset=10 xadvance=19 page=0 chnl=15 -char id=234 x=155 y=71 width=18 height=28 xoffset=1 yoffset=9 xadvance=19 page=0 chnl=15 -char id=235 x=0 y=159 width=18 height=25 xoffset=1 yoffset=12 xadvance=19 page=0 chnl=15 -char id=236 x=278 y=97 width=8 height=27 xoffset=0 yoffset=10 xadvance=10 page=0 chnl=15 -char id=237 x=268 y=97 width=9 height=27 xoffset=1 yoffset=10 xadvance=10 page=0 chnl=15 -char id=238 x=252 y=97 width=15 height=27 xoffset=-3 yoffset=10 xadvance=10 page=0 chnl=15 -char id=239 x=162 y=155 width=14 height=23 xoffset=-2 yoffset=14 xadvance=10 page=0 chnl=15 -char id=240 x=236 y=98 width=15 height=27 xoffset=2 yoffset=10 xadvance=17 page=0 chnl=15 -char id=241 x=274 y=125 width=18 height=26 xoffset=1 yoffset=11 xadvance=18 page=0 chnl=15 -char id=242 x=168 y=100 width=16 height=27 xoffset=1 yoffset=10 xadvance=18 page=0 chnl=15 -char id=243 x=185 y=99 width=16 height=27 xoffset=1 yoffset=10 xadvance=18 page=0 chnl=15 -char id=244 x=267 y=68 width=16 height=28 xoffset=1 yoffset=9 xadvance=18 page=0 chnl=15 -char id=245 x=293 y=124 width=18 height=26 xoffset=1 yoffset=11 xadvance=18 page=0 chnl=15 -char id=246 x=127 y=157 width=17 height=23 xoffset=1 yoffset=14 xadvance=18 page=0 chnl=15 -char id=247 x=39 y=184 width=16 height=16 xoffset=0 yoffset=18 xadvance=16 page=0 chnl=15 -char id=248 x=386 y=148 width=18 height=17 xoffset=0 yoffset=20 xadvance=18 page=0 chnl=15 -char id=249 x=219 y=98 width=16 height=27 xoffset=1 yoffset=10 xadvance=18 page=0 chnl=15 -char id=250 x=202 y=99 width=16 height=27 xoffset=1 yoffset=10 xadvance=18 page=0 chnl=15 -char id=251 x=250 y=68 width=16 height=28 xoffset=1 yoffset=9 xadvance=18 page=0 chnl=15 -char id=252 x=495 y=120 width=16 height=25 xoffset=1 yoffset=12 xadvance=18 page=0 chnl=15 -char id=253 x=82 y=0 width=19 height=37 xoffset=-1 yoffset=10 xadvance=18 page=0 chnl=15 -char id=254 x=323 y=0 width=16 height=35 xoffset=1 yoffset=12 xadvance=18 page=0 chnl=15 -char id=255 x=184 y=36 width=20 height=33 xoffset=-1 yoffset=14 xadvance=18 page=0 chnl=15 diff --git a/External tools/Myra.1.2.1.0/Assets/fonts/comicSans48_0.png b/External tools/Myra.1.2.1.0/Assets/fonts/comicSans48_0.png deleted file mode 100644 index c34875b..0000000 Binary files a/External tools/Myra.1.2.1.0/Assets/fonts/comicSans48_0.png and /dev/null differ diff --git a/External tools/Myra.1.2.1.0/Assets/images/LogoOnly_64px.png b/External tools/Myra.1.2.1.0/Assets/images/LogoOnly_64px.png deleted file mode 100644 index f772cea..0000000 Binary files a/External tools/Myra.1.2.1.0/Assets/images/LogoOnly_64px.png and /dev/null differ diff --git a/External tools/Myra.1.2.1.0/Cyotek.Drawing.BitmapFont.dll b/External tools/Myra.1.2.1.0/Cyotek.Drawing.BitmapFont.dll deleted file mode 100644 index c1ac309..0000000 Binary files a/External tools/Myra.1.2.1.0/Cyotek.Drawing.BitmapFont.dll and /dev/null differ diff --git a/External tools/Myra.1.2.1.0/FontStashSharp.MonoGame.dll b/External tools/Myra.1.2.1.0/FontStashSharp.MonoGame.dll deleted file mode 100644 index 726576c..0000000 Binary files a/External tools/Myra.1.2.1.0/FontStashSharp.MonoGame.dll and /dev/null differ diff --git a/External tools/Myra.1.2.1.0/MonoGame.Framework.dll b/External tools/Myra.1.2.1.0/MonoGame.Framework.dll deleted file mode 100644 index 9625655..0000000 Binary files a/External tools/Myra.1.2.1.0/MonoGame.Framework.dll and /dev/null differ diff --git a/External tools/Myra.1.2.1.0/MonoGame.Framework.dll.config b/External tools/Myra.1.2.1.0/MonoGame.Framework.dll.config deleted file mode 100644 index 09710ae..0000000 --- a/External tools/Myra.1.2.1.0/MonoGame.Framework.dll.config +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/External tools/Myra.1.2.1.0/Myra.Samples.AllWidgets.exe b/External tools/Myra.1.2.1.0/Myra.Samples.AllWidgets.exe deleted file mode 100644 index 76d1d54..0000000 Binary files a/External tools/Myra.1.2.1.0/Myra.Samples.AllWidgets.exe and /dev/null differ diff --git a/External tools/Myra.1.2.1.0/Myra.Samples.AssetManagement.exe b/External tools/Myra.1.2.1.0/Myra.Samples.AssetManagement.exe deleted file mode 100644 index d3fe2c1..0000000 Binary files a/External tools/Myra.1.2.1.0/Myra.Samples.AssetManagement.exe and /dev/null differ diff --git a/External tools/Myra.1.2.1.0/Myra.Samples.CustomUIStylesheet.exe b/External tools/Myra.1.2.1.0/Myra.Samples.CustomUIStylesheet.exe deleted file mode 100644 index a07c836..0000000 Binary files a/External tools/Myra.1.2.1.0/Myra.Samples.CustomUIStylesheet.exe and /dev/null differ diff --git a/External tools/Myra.1.2.1.0/Myra.Samples.CustomWidgets.exe b/External tools/Myra.1.2.1.0/Myra.Samples.CustomWidgets.exe deleted file mode 100644 index f9e4116..0000000 Binary files a/External tools/Myra.1.2.1.0/Myra.Samples.CustomWidgets.exe and /dev/null differ diff --git a/External tools/Myra.1.2.1.0/Myra.Samples.DebugConsole.exe b/External tools/Myra.1.2.1.0/Myra.Samples.DebugConsole.exe deleted file mode 100644 index 676ed3c..0000000 Binary files a/External tools/Myra.1.2.1.0/Myra.Samples.DebugConsole.exe and /dev/null differ diff --git a/External tools/Myra.1.2.1.0/Myra.Samples.GridContainer.exe b/External tools/Myra.1.2.1.0/Myra.Samples.GridContainer.exe deleted file mode 100644 index 3c75f3f..0000000 Binary files a/External tools/Myra.1.2.1.0/Myra.Samples.GridContainer.exe and /dev/null differ diff --git a/External tools/Myra.1.2.1.0/Myra.Samples.NonModalWindows.exe b/External tools/Myra.1.2.1.0/Myra.Samples.NonModalWindows.exe deleted file mode 100644 index b86c9b5..0000000 Binary files a/External tools/Myra.1.2.1.0/Myra.Samples.NonModalWindows.exe and /dev/null differ diff --git a/External tools/Myra.1.2.1.0/Myra.Samples.Notepad.exe b/External tools/Myra.1.2.1.0/Myra.Samples.Notepad.exe deleted file mode 100644 index ff20055..0000000 Binary files a/External tools/Myra.1.2.1.0/Myra.Samples.Notepad.exe and /dev/null differ diff --git a/External tools/Myra.1.2.1.0/Myra.Samples.ObjectEditor.exe b/External tools/Myra.1.2.1.0/Myra.Samples.ObjectEditor.exe deleted file mode 100644 index 379de96..0000000 Binary files a/External tools/Myra.1.2.1.0/Myra.Samples.ObjectEditor.exe and /dev/null differ diff --git a/External tools/Myra.1.2.1.0/Myra.Samples.SplitPaneContainer.exe b/External tools/Myra.1.2.1.0/Myra.Samples.SplitPaneContainer.exe deleted file mode 100644 index 9e117cb..0000000 Binary files a/External tools/Myra.1.2.1.0/Myra.Samples.SplitPaneContainer.exe and /dev/null differ diff --git a/External tools/Myra.1.2.1.0/Myra.dll b/External tools/Myra.1.2.1.0/Myra.dll deleted file mode 100644 index 6681c3b..0000000 Binary files a/External tools/Myra.1.2.1.0/Myra.dll and /dev/null differ diff --git a/External tools/Myra.1.2.1.0/MyraPad.exe b/External tools/Myra.1.2.1.0/MyraPad.exe deleted file mode 100644 index a30dbf1..0000000 Binary files a/External tools/Myra.1.2.1.0/MyraPad.exe and /dev/null differ diff --git a/External tools/Myra.1.2.1.0/StbImageSharp.dll b/External tools/Myra.1.2.1.0/StbImageSharp.dll deleted file mode 100644 index 2e60d67..0000000 Binary files a/External tools/Myra.1.2.1.0/StbImageSharp.dll and /dev/null differ diff --git a/External tools/Myra.1.2.1.0/StbTrueTypeSharp.dll b/External tools/Myra.1.2.1.0/StbTrueTypeSharp.dll deleted file mode 100644 index a3a030e..0000000 Binary files a/External tools/Myra.1.2.1.0/StbTrueTypeSharp.dll and /dev/null differ diff --git a/External tools/Myra.1.2.1.0/Stylesheets/allControls.xmmp b/External tools/Myra.1.2.1.0/Stylesheets/allControls.xmmp deleted file mode 100644 index 3d9ffaa..0000000 --- a/External tools/Myra.1.2.1.0/Stylesheets/allControls.xmmp +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/External tools/Myra.1.2.1.0/Stylesheets/commodore-64/commodore-64.fnt b/External tools/Myra.1.2.1.0/Stylesheets/commodore-64/commodore-64.fnt deleted file mode 100644 index b6cec83..0000000 --- a/External tools/Myra.1.2.1.0/Stylesheets/commodore-64/commodore-64.fnt +++ /dev/null @@ -1,101 +0,0 @@ -info face="Commodore 64 Pixelized" size=20 bold=0 italic=0 charset="" unicode=0 stretchH=100 smooth=1 aa=1 padding=1,1,1,1 spacing=-2,-2 -common lineHeight=20 base=18 scaleW=512 scaleH=64 pages=1 packed=0 -page id=0 file="ui_stylesheet.atlas:commodore-64" -chars count=96 -char id=10 x=0 y=0 width=0 height=0 xoffset=0 yoffset=0 xadvance=0 page=0 chnl=0 -char id=32 x=0 y=0 width=0 height=0 xoffset=-1 yoffset=17 xadvance=16 page=0 chnl=0 -char id=33 x=502 y=0 width=6 height=16 xoffset=5 yoffset=3 xadvance=16 page=0 chnl=0 -char id=34 x=188 y=34 width=14 height=6 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=35 x=248 y=18 width=18 height=16 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=36 x=220 y=18 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=37 x=234 y=18 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=38 x=266 y=18 width=16 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=39 x=142 y=34 width=10 height=8 xoffset=5 yoffset=3 xadvance=16 page=0 chnl=0 -char id=40 x=90 y=18 width=10 height=16 xoffset=3 yoffset=3 xadvance=16 page=0 chnl=0 -char id=41 x=100 y=18 width=10 height=16 xoffset=3 yoffset=3 xadvance=16 page=0 chnl=0 -char id=42 x=114 y=34 width=18 height=12 xoffset=-1 yoffset=5 xadvance=16 page=0 chnl=0 -char id=43 x=100 y=34 width=14 height=12 xoffset=1 yoffset=5 xadvance=16 page=0 chnl=0 -char id=44 x=152 y=34 width=8 height=8 xoffset=3 yoffset=13 xadvance=16 page=0 chnl=0 -char id=45 x=208 y=34 width=14 height=4 xoffset=1 yoffset=9 xadvance=16 page=0 chnl=0 -char id=46 x=202 y=34 width=6 height=6 xoffset=5 yoffset=13 xadvance=16 page=0 chnl=0 -char id=47 x=392 y=18 width=16 height=14 xoffset=1 yoffset=5 xadvance=16 page=0 chnl=0 -char id=48 x=56 y=18 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=49 x=430 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=50 x=444 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=51 x=458 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=52 x=472 y=0 width=16 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=53 x=488 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=54 x=0 y=18 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=55 x=14 y=18 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=56 x=28 y=18 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=57 x=42 y=18 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=58 x=84 y=18 width=6 height=16 xoffset=5 yoffset=3 xadvance=16 page=0 chnl=0 -char id=59 x=0 y=0 width=8 height=18 xoffset=3 yoffset=3 xadvance=16 page=0 chnl=0 -char id=60 x=158 y=18 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=61 x=160 y=34 width=14 height=8 xoffset=1 yoffset=7 xadvance=16 page=0 chnl=0 -char id=62 x=172 y=18 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=63 x=70 y=18 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=64 x=192 y=18 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=65 x=8 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=66 x=22 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=67 x=36 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=68 x=50 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=69 x=64 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=15 page=0 chnl=0 -char id=70 x=78 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=15 page=0 chnl=0 -char id=71 x=92 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=72 x=106 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=73 x=120 y=0 width=10 height=16 xoffset=3 yoffset=3 xadvance=16 page=0 chnl=0 -char id=74 x=130 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=75 x=144 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=76 x=158 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=15 page=0 chnl=0 -char id=77 x=172 y=0 width=16 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=78 x=188 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=79 x=202 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=80 x=216 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=81 x=230 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=82 x=244 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=83 x=258 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=84 x=272 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=85 x=286 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=86 x=300 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=87 x=314 y=0 width=16 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=88 x=330 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=89 x=344 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=90 x=358 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=91 x=110 y=18 width=10 height=16 xoffset=3 yoffset=3 xadvance=16 page=0 chnl=0 -char id=92 x=408 y=18 width=16 height=14 xoffset=1 yoffset=5 xadvance=16 page=0 chnl=0 -char id=93 x=120 y=18 width=10 height=16 xoffset=3 yoffset=3 xadvance=16 page=0 chnl=0 -char id=94 x=206 y=18 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=95 x=222 y=34 width=18 height=4 xoffset=-1 yoffset=15 xadvance=16 page=0 chnl=0 -char id=96 x=132 y=34 width=10 height=8 xoffset=5 yoffset=3 xadvance=16 page=0 chnl=0 -char id=97 x=424 y=18 width=14 height=12 xoffset=1 yoffset=7 xadvance=16 page=0 chnl=0 -char id=98 x=282 y=18 width=14 height=14 xoffset=1 yoffset=5 xadvance=16 page=0 chnl=0 -char id=99 x=438 y=18 width=12 height=12 xoffset=1 yoffset=7 xadvance=16 page=0 chnl=0 -char id=100 x=296 y=18 width=14 height=14 xoffset=1 yoffset=5 xadvance=16 page=0 chnl=0 -char id=101 x=450 y=18 width=14 height=12 xoffset=1 yoffset=7 xadvance=16 page=0 chnl=0 -char id=102 x=310 y=18 width=12 height=14 xoffset=3 yoffset=5 xadvance=16 page=0 chnl=0 -char id=103 x=322 y=18 width=14 height=14 xoffset=1 yoffset=7 xadvance=16 page=0 chnl=0 -char id=104 x=372 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=105 x=386 y=0 width=10 height=16 xoffset=3 yoffset=3 xadvance=16 page=0 chnl=0 -char id=106 x=396 y=0 width=10 height=16 xoffset=3 yoffset=5 xadvance=16 page=0 chnl=0 -char id=107 x=406 y=0 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=108 x=420 y=0 width=10 height=16 xoffset=3 yoffset=3 xadvance=16 page=0 chnl=0 -char id=109 x=464 y=18 width=16 height=12 xoffset=1 yoffset=7 xadvance=16 page=0 chnl=0 -char id=110 x=480 y=18 width=14 height=12 xoffset=1 yoffset=7 xadvance=16 page=0 chnl=0 -char id=111 x=494 y=18 width=14 height=12 xoffset=1 yoffset=7 xadvance=16 page=0 chnl=0 -char id=112 x=336 y=18 width=14 height=14 xoffset=1 yoffset=7 xadvance=16 page=0 chnl=0 -char id=113 x=350 y=18 width=14 height=14 xoffset=1 yoffset=7 xadvance=16 page=0 chnl=0 -char id=114 x=0 y=34 width=14 height=12 xoffset=1 yoffset=7 xadvance=16 page=0 chnl=0 -char id=115 x=14 y=34 width=14 height=12 xoffset=1 yoffset=7 xadvance=16 page=0 chnl=0 -char id=116 x=364 y=18 width=14 height=14 xoffset=1 yoffset=5 xadvance=16 page=0 chnl=0 -char id=117 x=28 y=34 width=14 height=12 xoffset=1 yoffset=7 xadvance=16 page=0 chnl=0 -char id=118 x=42 y=34 width=14 height=12 xoffset=1 yoffset=7 xadvance=16 page=0 chnl=0 -char id=119 x=56 y=34 width=16 height=12 xoffset=1 yoffset=7 xadvance=16 page=0 chnl=0 -char id=120 x=72 y=34 width=14 height=12 xoffset=1 yoffset=7 xadvance=16 page=0 chnl=0 -char id=121 x=378 y=18 width=14 height=14 xoffset=1 yoffset=7 xadvance=16 page=0 chnl=0 -char id=122 x=86 y=34 width=14 height=12 xoffset=1 yoffset=7 xadvance=16 page=0 chnl=0 -char id=123 x=130 y=18 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=124 x=186 y=18 width=6 height=16 xoffset=5 yoffset=3 xadvance=16 page=0 chnl=0 -char id=125 x=144 y=18 width=14 height=16 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -char id=126 x=174 y=34 width=14 height=8 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=0 -kernings count=0 diff --git a/External tools/Myra.1.2.1.0/Stylesheets/commodore-64/ui_stylesheet.atlas b/External tools/Myra.1.2.1.0/Stylesheets/commodore-64/ui_stylesheet.atlas deleted file mode 100644 index 28ec4b0..0000000 --- a/External tools/Myra.1.2.1.0/Stylesheets/commodore-64/ui_stylesheet.atlas +++ /dev/null @@ -1,274 +0,0 @@ - -ui_stylesheet_atlas.png -size: 860,229 -format: RGBA8888 -filter: Nearest,Nearest -repeat: none -blue - rotate: false - xy: 106, 137 - size: 2, 2 - orig: 2, 2 - offset: 0, 0 - index: -1 -button - rotate: false - xy: 715, 139 - size: 36, 24 - split: 18, 17, 11, 12 - pad: 14, 14, 4, 4 - orig: 36, 24 - offset: 0, 0 - index: -1 -button-down - rotate: false - xy: 106, 140 - size: 36, 24 - split: 18, 17, 12, 11 - pad: 14, 14, 4, 4 - orig: 36, 24 - offset: 0, 0 - index: -1 -check-box - rotate: false - xy: 162, 152 - size: 12, 12 - orig: 12, 12 - offset: 0, 0 - index: -1 -check-box-off - rotate: false - xy: 715, 109 - size: 12, 12 - orig: 12, 12 - offset: 0, 0 - index: -1 -commodore-64 - rotate: false - xy: 1, 165 - size: 512, 64 - orig: 512, 64 - offset: 0, 0 - index: -1 -cursor - rotate: false - xy: 143, 148 - size: 18, 16 - split: 9, 8, 7, 8 - pad: 2, 0, 0, 0 - orig: 18, 16 - offset: 0, 0 - index: -1 -cursor-black - rotate: false - xy: 1, 14 - size: 18, 16 - split: 9, 8, 7, 8 - pad: 2, 0, 0, 0 - orig: 18, 16 - offset: 0, 0 - index: -1 -dialog - rotate: false - xy: 1, 31 - size: 38, 38 - split: 19, 18, 18, 19 - pad: 13, 13, 24, 13 - orig: 38, 38 - offset: 0, 0 - index: -1 -grey - rotate: false - xy: 752, 161 - size: 2, 2 - orig: 2, 2 - offset: 0, 0 - index: -1 -horizontal-split-pane - rotate: false - xy: 732, 128 - size: 14, 10 - split: 6, 6, 0, 0 - pad: 0, 0, 0, 0 - orig: 14, 10 - offset: 0, 0 - index: -1 -light-blue - rotate: false - xy: 143, 145 - size: 2, 2 - orig: 2, 2 - offset: 0, 0 - index: -1 -list - rotate: false - xy: 821, 215 - size: 22, 14 - split: 0, 21, 0, 13 - pad: 0, 17, 0, 2 - orig: 22, 14 - offset: 0, 0 - index: -1 -minus - rotate: false - xy: 78, 117 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -music - rotate: false - xy: 715, 164 - size: 46, 32 - orig: 46, 32 - offset: 0, 0 - index: -1 -music-off - rotate: false - xy: 774, 197 - size: 46, 32 - orig: 46, 32 - offset: 0, 0 - index: -1 -plus - rotate: false - xy: 821, 200 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -progress-bar - rotate: false - xy: 777, 180 - size: 16, 16 - split: 7, 8, 7, 8 - pad: 2, 2, 2, 2 - orig: 16, 16 - offset: 0, 0 - index: -1 -progress-bar-knob - rotate: false - xy: 715, 122 - size: 16, 16 - split: 4, 4, 4, 4 - pad: 0, 0, 0, 0 - orig: 16, 16 - offset: 0, 0 - index: -1 -radio-button - rotate: false - xy: 844, 217 - size: 16, 12 - orig: 16, 12 - offset: 0, 0 - index: -1 -radio-button - rotate: false - xy: 844, 217 - size: 16, 12 - split: 14, 0, 5, 5 - pad: 13, 0, 0, 0 - orig: 16, 12 - offset: 0, 0 - index: -1 -radio-button-off - rotate: false - xy: 1, 1 - size: 16, 12 - orig: 16, 12 - offset: 0, 0 - index: -1 -scroll-bar - rotate: false - xy: 20, 16 - size: 14, 14 - split: 6, 6, 6, 6 - pad: 0, 0, 0, 0 - orig: 14, 14 - offset: 0, 0 - index: -1 -scroll-bar-horizontal-knob - rotate: false - xy: 47, 117 - size: 30, 14 - split: 15, 14, 7, 6 - pad: 0, 0, 0, 0 - orig: 30, 14 - offset: 0, 0 - index: -1 -scroll-bar-vertical-knob - rotate: false - xy: 762, 166 - size: 14, 30 - split: 7, 6, 16, 13 - pad: 0, 0, 0, 0 - orig: 14, 30 - offset: 0, 0 - index: -1 -slider - rotate: false - xy: 40, 65 - size: 4, 4 - orig: 4, 4 - offset: 0, 0 - index: -1 -slider-knob - rotate: false - xy: 777, 167 - size: 10, 12 - orig: 10, 12 - offset: 0, 0 - index: -1 -sound - rotate: false - xy: 715, 197 - size: 58, 32 - orig: 58, 32 - offset: 0, 0 - index: -1 -sound-off - rotate: false - xy: 47, 132 - size: 58, 32 - orig: 58, 32 - offset: 0, 0 - index: -1 -touchpad - rotate: false - xy: 514, 29 - size: 200, 200 - orig: 200, 200 - offset: 0, 0 - index: -1 -touchpad-knob - rotate: false - xy: 1, 70 - size: 44, 44 - orig: 44, 44 - offset: 0, 0 - index: -1 -vertical-split-pane - rotate: false - xy: 794, 182 - size: 10, 14 - split: 0, 0, 6, 6 - pad: 0, 1, 0, 0 - orig: 10, 14 - offset: 0, 0 - index: -1 -white - rotate: false - xy: 93, 129 - size: 2, 2 - orig: 2, 2 - offset: 0, 0 - index: -1 -window - rotate: false - xy: 1, 115 - size: 45, 49 - split: 20, 20, 22, 22 - pad: 22, 22, 24, 24 - orig: 45, 49 - offset: 0, 0 - index: -1 diff --git a/External tools/Myra.1.2.1.0/Stylesheets/commodore-64/ui_stylesheet.xmms b/External tools/Myra.1.2.1.0/Stylesheets/commodore-64/ui_stylesheet.xmms deleted file mode 100644 index 33906fa..0000000 --- a/External tools/Myra.1.2.1.0/Stylesheets/commodore-64/ui_stylesheet.xmms +++ /dev/null @@ -1,87 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/External tools/Myra.1.2.1.0/Stylesheets/commodore-64/ui_stylesheet_atlas.png b/External tools/Myra.1.2.1.0/Stylesheets/commodore-64/ui_stylesheet_atlas.png deleted file mode 100644 index 04554a5..0000000 Binary files a/External tools/Myra.1.2.1.0/Stylesheets/commodore-64/ui_stylesheet_atlas.png and /dev/null differ diff --git a/External tools/Myra.1.2.1.0/Stylesheets/libgdx/ui_font.fnt b/External tools/Myra.1.2.1.0/Stylesheets/libgdx/ui_font.fnt deleted file mode 100644 index 60ea417..0000000 --- a/External tools/Myra.1.2.1.0/Stylesheets/libgdx/ui_font.fnt +++ /dev/null @@ -1,101 +0,0 @@ -info face="Droid Sans" size=17 bold=0 italic=0 charset="" unicode=0 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 -common lineHeight=20 base=18 scaleW=256 scaleH=128 pages=1 packed=0 -page id=0 file="ui_stylesheet.atlas:default" -chars count=95 -char id=32 x=0 y=0 width=0 height=0 xoffset=0 yoffset=16 xadvance=4 page=0 chnl=0 -char id=124 x=0 y=0 width=6 height=20 xoffset=1 yoffset=3 xadvance=9 page=0 chnl=0 -char id=106 x=6 y=0 width=9 height=20 xoffset=-4 yoffset=3 xadvance=4 page=0 chnl=0 -char id=81 x=15 y=0 width=15 height=19 xoffset=-2 yoffset=3 xadvance=12 page=0 chnl=0 -char id=74 x=30 y=0 width=11 height=19 xoffset=-5 yoffset=3 xadvance=4 page=0 chnl=0 -char id=125 x=41 y=0 width=10 height=18 xoffset=-3 yoffset=3 xadvance=6 page=0 chnl=0 -char id=123 x=51 y=0 width=10 height=18 xoffset=-3 yoffset=3 xadvance=6 page=0 chnl=0 -char id=93 x=61 y=0 width=8 height=18 xoffset=-3 yoffset=3 xadvance=5 page=0 chnl=0 -char id=91 x=69 y=0 width=8 height=18 xoffset=-2 yoffset=3 xadvance=5 page=0 chnl=0 -char id=41 x=77 y=0 width=9 height=18 xoffset=-3 yoffset=3 xadvance=5 page=0 chnl=0 -char id=40 x=86 y=0 width=9 height=18 xoffset=-3 yoffset=3 xadvance=5 page=0 chnl=0 -char id=64 x=95 y=0 width=18 height=17 xoffset=-3 yoffset=3 xadvance=14 page=0 chnl=0 -char id=121 x=113 y=0 width=13 height=17 xoffset=-3 yoffset=6 xadvance=8 page=0 chnl=0 -char id=113 x=126 y=0 width=13 height=17 xoffset=-3 yoffset=6 xadvance=9 page=0 chnl=0 -char id=112 x=139 y=0 width=13 height=17 xoffset=-2 yoffset=6 xadvance=9 page=0 chnl=0 -char id=103 x=152 y=0 width=13 height=17 xoffset=-3 yoffset=6 xadvance=8 page=0 chnl=0 -char id=38 x=165 y=0 width=16 height=16 xoffset=-3 yoffset=3 xadvance=11 page=0 chnl=0 -char id=37 x=181 y=0 width=18 height=16 xoffset=-3 yoffset=3 xadvance=14 page=0 chnl=0 -char id=36 x=199 y=0 width=12 height=16 xoffset=-2 yoffset=3 xadvance=9 page=0 chnl=0 -char id=63 x=211 y=0 width=11 height=16 xoffset=-3 yoffset=3 xadvance=7 page=0 chnl=0 -char id=33 x=222 y=0 width=7 height=16 xoffset=-2 yoffset=3 xadvance=4 page=0 chnl=0 -char id=48 x=229 y=0 width=13 height=16 xoffset=-3 yoffset=3 xadvance=9 page=0 chnl=0 -char id=57 x=242 y=0 width=13 height=16 xoffset=-3 yoffset=3 xadvance=9 page=0 chnl=0 -char id=56 x=0 y=20 width=13 height=16 xoffset=-3 yoffset=3 xadvance=9 page=0 chnl=0 -char id=54 x=13 y=20 width=13 height=16 xoffset=-3 yoffset=3 xadvance=9 page=0 chnl=0 -char id=53 x=26 y=20 width=12 height=16 xoffset=-2 yoffset=3 xadvance=9 page=0 chnl=0 -char id=51 x=38 y=20 width=13 height=16 xoffset=-3 yoffset=3 xadvance=9 page=0 chnl=0 -char id=100 x=51 y=20 width=13 height=16 xoffset=-3 yoffset=3 xadvance=9 page=0 chnl=0 -char id=98 x=64 y=20 width=13 height=16 xoffset=-2 yoffset=3 xadvance=9 page=0 chnl=0 -char id=85 x=77 y=20 width=14 height=16 xoffset=-2 yoffset=3 xadvance=11 page=0 chnl=0 -char id=83 x=91 y=20 width=13 height=16 xoffset=-3 yoffset=3 xadvance=8 page=0 chnl=0 -char id=79 x=104 y=20 width=15 height=16 xoffset=-2 yoffset=3 xadvance=12 page=0 chnl=0 -char id=71 x=119 y=20 width=14 height=16 xoffset=-2 yoffset=3 xadvance=11 page=0 chnl=0 -char id=67 x=133 y=20 width=13 height=16 xoffset=-2 yoffset=3 xadvance=10 page=0 chnl=0 -char id=127 x=146 y=20 width=12 height=15 xoffset=-2 yoffset=3 xadvance=10 page=0 chnl=0 -char id=35 x=158 y=20 width=15 height=15 xoffset=-3 yoffset=3 xadvance=10 page=0 chnl=0 -char id=92 x=173 y=20 width=11 height=15 xoffset=-3 yoffset=3 xadvance=6 page=0 chnl=0 -char id=47 x=184 y=20 width=11 height=15 xoffset=-3 yoffset=3 xadvance=6 page=0 chnl=0 -char id=59 x=195 y=20 width=8 height=15 xoffset=-3 yoffset=6 xadvance=4 page=0 chnl=0 -char id=55 x=203 y=20 width=13 height=15 xoffset=-3 yoffset=3 xadvance=9 page=0 chnl=0 -char id=52 x=216 y=20 width=14 height=15 xoffset=-3 yoffset=3 xadvance=9 page=0 chnl=0 -char id=50 x=230 y=20 width=13 height=15 xoffset=-3 yoffset=3 xadvance=9 page=0 chnl=0 -char id=49 x=243 y=20 width=9 height=15 xoffset=-2 yoffset=3 xadvance=9 page=0 chnl=0 -char id=116 x=0 y=36 width=10 height=15 xoffset=-3 yoffset=4 xadvance=5 page=0 chnl=0 -char id=108 x=10 y=36 width=6 height=15 xoffset=-2 yoffset=3 xadvance=4 page=0 chnl=0 -char id=107 x=16 y=36 width=12 height=15 xoffset=-2 yoffset=3 xadvance=8 page=0 chnl=0 -char id=105 x=28 y=36 width=7 height=15 xoffset=-2 yoffset=3 xadvance=4 page=0 chnl=0 -char id=104 x=35 y=36 width=12 height=15 xoffset=-2 yoffset=3 xadvance=10 page=0 chnl=0 -char id=102 x=47 y=36 width=11 height=15 xoffset=-3 yoffset=3 xadvance=5 page=0 chnl=0 -char id=90 x=58 y=36 width=13 height=15 xoffset=-3 yoffset=3 xadvance=9 page=0 chnl=0 -char id=89 x=71 y=36 width=13 height=15 xoffset=-3 yoffset=3 xadvance=8 page=0 chnl=0 -char id=88 x=84 y=36 width=14 height=15 xoffset=-3 yoffset=3 xadvance=9 page=0 chnl=0 -char id=87 x=98 y=36 width=19 height=15 xoffset=-3 yoffset=3 xadvance=15 page=0 chnl=0 -char id=86 x=117 y=36 width=14 height=15 xoffset=-3 yoffset=3 xadvance=9 page=0 chnl=0 -char id=84 x=131 y=36 width=13 height=15 xoffset=-3 yoffset=3 xadvance=8 page=0 chnl=0 -char id=82 x=144 y=36 width=13 height=15 xoffset=-2 yoffset=3 xadvance=10 page=0 chnl=0 -char id=80 x=157 y=36 width=12 height=15 xoffset=-2 yoffset=3 xadvance=9 page=0 chnl=0 -char id=78 x=169 y=36 width=14 height=15 xoffset=-2 yoffset=3 xadvance=12 page=0 chnl=0 -char id=77 x=183 y=36 width=17 height=15 xoffset=-2 yoffset=3 xadvance=14 page=0 chnl=0 -char id=76 x=200 y=36 width=11 height=15 xoffset=-2 yoffset=3 xadvance=8 page=0 chnl=0 -char id=75 x=211 y=36 width=13 height=15 xoffset=-2 yoffset=3 xadvance=9 page=0 chnl=0 -char id=73 x=224 y=36 width=10 height=15 xoffset=-3 yoffset=3 xadvance=5 page=0 chnl=0 -char id=72 x=234 y=36 width=14 height=15 xoffset=-2 yoffset=3 xadvance=11 page=0 chnl=0 -char id=70 x=0 y=51 width=11 height=15 xoffset=-2 yoffset=3 xadvance=8 page=0 chnl=0 -char id=69 x=11 y=51 width=11 height=15 xoffset=-2 yoffset=3 xadvance=8 page=0 chnl=0 -char id=68 x=22 y=51 width=14 height=15 xoffset=-2 yoffset=3 xadvance=11 page=0 chnl=0 -char id=66 x=36 y=51 width=13 height=15 xoffset=-2 yoffset=3 xadvance=10 page=0 chnl=0 -char id=65 x=49 y=51 width=15 height=15 xoffset=-3 yoffset=3 xadvance=10 page=0 chnl=0 -char id=58 x=64 y=51 width=7 height=13 xoffset=-2 yoffset=6 xadvance=4 page=0 chnl=0 -char id=117 x=71 y=51 width=12 height=13 xoffset=-2 yoffset=6 xadvance=10 page=0 chnl=0 -char id=115 x=83 y=51 width=11 height=13 xoffset=-3 yoffset=6 xadvance=7 page=0 chnl=0 -char id=111 x=94 y=51 width=13 height=13 xoffset=-3 yoffset=6 xadvance=9 page=0 chnl=0 -char id=101 x=107 y=51 width=13 height=13 xoffset=-3 yoffset=6 xadvance=9 page=0 chnl=0 -char id=99 x=120 y=51 width=12 height=13 xoffset=-3 yoffset=6 xadvance=7 page=0 chnl=0 -char id=97 x=132 y=51 width=12 height=13 xoffset=-3 yoffset=6 xadvance=9 page=0 chnl=0 -char id=60 x=144 y=51 width=13 height=12 xoffset=-3 yoffset=5 xadvance=9 page=0 chnl=0 -char id=122 x=157 y=51 width=11 height=12 xoffset=-3 yoffset=6 xadvance=7 page=0 chnl=0 -char id=120 x=168 y=51 width=13 height=12 xoffset=-3 yoffset=6 xadvance=8 page=0 chnl=0 -char id=119 x=181 y=51 width=17 height=12 xoffset=-3 yoffset=6 xadvance=12 page=0 chnl=0 -char id=118 x=198 y=51 width=13 height=12 xoffset=-3 yoffset=6 xadvance=8 page=0 chnl=0 -char id=114 x=211 y=51 width=10 height=12 xoffset=-2 yoffset=6 xadvance=6 page=0 chnl=0 -char id=110 x=221 y=51 width=12 height=12 xoffset=-2 yoffset=6 xadvance=10 page=0 chnl=0 -char id=109 x=233 y=51 width=17 height=12 xoffset=-2 yoffset=6 xadvance=15 page=0 chnl=0 -char id=94 x=0 y=66 width=13 height=11 xoffset=-3 yoffset=3 xadvance=9 page=0 chnl=0 -char id=62 x=13 y=66 width=13 height=11 xoffset=-3 yoffset=5 xadvance=9 page=0 chnl=0 -char id=42 x=26 y=66 width=13 height=10 xoffset=-3 yoffset=3 xadvance=9 page=0 chnl=0 -char id=43 x=39 y=66 width=13 height=10 xoffset=-3 yoffset=6 xadvance=9 page=0 chnl=0 -char id=61 x=52 y=66 width=13 height=8 xoffset=-3 yoffset=7 xadvance=9 page=0 chnl=0 -char id=39 x=65 y=66 width=6 height=8 xoffset=-2 yoffset=3 xadvance=3 page=0 chnl=0 -char id=34 x=71 y=66 width=9 height=8 xoffset=-2 yoffset=3 xadvance=6 page=0 chnl=0 -char id=44 x=80 y=66 width=8 height=7 xoffset=-3 yoffset=14 xadvance=4 page=0 chnl=0 -char id=126 x=88 y=66 width=13 height=6 xoffset=-3 yoffset=8 xadvance=9 page=0 chnl=0 -char id=46 x=101 y=66 width=7 height=6 xoffset=-2 yoffset=13 xadvance=4 page=0 chnl=0 -char id=96 x=108 y=66 width=8 height=6 xoffset=0 yoffset=2 xadvance=9 page=0 chnl=0 -char id=45 x=116 y=66 width=9 height=5 xoffset=-3 yoffset=10 xadvance=5 page=0 chnl=0 -char id=95 x=125 y=66 width=13 height=4 xoffset=-4 yoffset=17 xadvance=6 page=0 chnl=0 -kernings count=-1 diff --git a/External tools/Myra.1.2.1.0/Stylesheets/libgdx/ui_stylesheet.atlas b/External tools/Myra.1.2.1.0/Stylesheets/libgdx/ui_stylesheet.atlas deleted file mode 100644 index 32d78c1..0000000 --- a/External tools/Myra.1.2.1.0/Stylesheets/libgdx/ui_stylesheet.atlas +++ /dev/null @@ -1,201 +0,0 @@ - -ui_stylesheet_atlas.png -size: 256,128 -format: RGBA8888 -filter: Linear,Linear -repeat: none -check-off - rotate: false - xy: 11, 5 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -textfield - rotate: false - xy: 11, 5 - size: 14, 14 - split: 3, 3, 3, 3 - orig: 14, 14 - offset: 0, 0 - index: -1 -check-on - rotate: false - xy: 125, 35 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -cursor - rotate: false - xy: 23, 1 - size: 3, 3 - split: 1, 1, 1, 1 - orig: 3, 3 - offset: 0, 0 - index: -1 -default - rotate: false - xy: 1, 50 - size: 254, 77 - orig: 254, 77 - offset: 0, 0 - index: -1 -default-pane - rotate: false - xy: 11, 1 - size: 5, 3 - split: 1, 1, 1, 1 - orig: 5, 3 - offset: 0, 0 - index: -1 -default-rect-pad - rotate: false - xy: 11, 1 - size: 5, 3 - split: 1, 1, 1, 1 - orig: 5, 3 - offset: 0, 0 - index: -1 -default-pane-noborder - rotate: false - xy: 170, 44 - size: 1, 1 - split: 0, 0, 0, 0 - orig: 1, 1 - offset: 0, 0 - index: -1 -default-rect - rotate: false - xy: 38, 25 - size: 3, 3 - split: 1, 1, 1, 1 - orig: 3, 3 - offset: 0, 0 - index: -1 -default-rect-down - rotate: false - xy: 170, 46 - size: 3, 3 - split: 1, 1, 1, 1 - orig: 3, 3 - offset: 0, 0 - index: -1 -default-round - rotate: false - xy: 112, 29 - size: 12, 20 - split: 5, 5, 5, 4 - pad: 4, 4, 1, 1 - orig: 12, 20 - offset: 0, 0 - index: -1 -default-round-down - rotate: false - xy: 99, 29 - size: 12, 20 - split: 5, 5, 5, 4 - pad: 4, 4, 1, 1 - orig: 12, 20 - offset: 0, 0 - index: -1 -default-round-large - rotate: false - xy: 57, 29 - size: 20, 20 - split: 5, 5, 5, 4 - orig: 20, 20 - offset: 0, 0 - index: -1 -default-scroll - rotate: false - xy: 78, 29 - size: 20, 20 - split: 2, 2, 2, 2 - orig: 20, 20 - offset: 0, 0 - index: -1 -default-select - rotate: false - xy: 29, 29 - size: 27, 20 - split: 4, 14, 4, 4 - orig: 27, 20 - offset: 0, 0 - index: -1 -default-select-selection - rotate: false - xy: 26, 16 - size: 3, 3 - split: 1, 1, 1, 1 - orig: 3, 3 - offset: 0, 0 - index: -1 -default-slider - rotate: false - xy: 29, 20 - size: 8, 8 - split: 2, 2, 2, 2 - orig: 8, 8 - offset: 0, 0 - index: -1 -default-slider-knob - rotate: false - xy: 1, 1 - size: 9, 18 - orig: 9, 18 - offset: 0, 0 - index: -1 -default-splitpane - rotate: false - xy: 17, 1 - size: 5, 3 - split: 0, 5, 0, 0 - orig: 5, 3 - offset: 0, 0 - index: -1 -default-splitpane-vertical - rotate: false - xy: 125, 29 - size: 3, 5 - split: 0, 0, 0, 5 - orig: 3, 5 - offset: 0, 0 - index: -1 -default-window - rotate: false - xy: 1, 20 - size: 27, 29 - split: 4, 3, 20, 3 - orig: 27, 29 - offset: 0, 0 - index: -1 -selection - rotate: false - xy: 174, 48 - size: 1, 1 - orig: 1, 1 - offset: 0, 0 - index: -1 -tree-minus - rotate: false - xy: 140, 35 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -tree-plus - rotate: false - xy: 155, 35 - size: 14, 14 - orig: 14, 14 - offset: 0, 0 - index: -1 -white - rotate: false - xy: 129, 31 - size: 3, 3 - orig: 3, 3 - offset: 0, 0 - index: -1 - diff --git a/External tools/Myra.1.2.1.0/Stylesheets/libgdx/ui_stylesheet.xmms b/External tools/Myra.1.2.1.0/Stylesheets/libgdx/ui_stylesheet.xmms deleted file mode 100644 index 16c1204..0000000 --- a/External tools/Myra.1.2.1.0/Stylesheets/libgdx/ui_stylesheet.xmms +++ /dev/null @@ -1,112 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/External tools/Myra.1.2.1.0/Stylesheets/libgdx/ui_stylesheet_atlas.png b/External tools/Myra.1.2.1.0/Stylesheets/libgdx/ui_stylesheet_atlas.png deleted file mode 100644 index f51c5bd..0000000 Binary files a/External tools/Myra.1.2.1.0/Stylesheets/libgdx/ui_stylesheet_atlas.png and /dev/null differ diff --git a/External tools/Myra.1.2.1.0/image.png b/External tools/Myra.1.2.1.0/image.png deleted file mode 100644 index 2567fe7..0000000 Binary files a/External tools/Myra.1.2.1.0/image.png and /dev/null differ diff --git a/External tools/Myra.1.2.1.0/info.lundin.math.dll b/External tools/Myra.1.2.1.0/info.lundin.math.dll deleted file mode 100644 index 45cad3a..0000000 Binary files a/External tools/Myra.1.2.1.0/info.lundin.math.dll and /dev/null differ diff --git a/External tools/Myra.1.2.1.0/libSDL2-2.0.0.dylib b/External tools/Myra.1.2.1.0/libSDL2-2.0.0.dylib deleted file mode 100644 index 221b678..0000000 Binary files a/External tools/Myra.1.2.1.0/libSDL2-2.0.0.dylib and /dev/null differ diff --git a/External tools/Myra.1.2.1.0/libopenal.1.dylib b/External tools/Myra.1.2.1.0/libopenal.1.dylib deleted file mode 100644 index 883af95..0000000 Binary files a/External tools/Myra.1.2.1.0/libopenal.1.dylib and /dev/null differ diff --git a/README.md b/README.md index 7169fbe..a4a586e 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,38 @@ # Map +to start the container run: + +``` +docker run --name= -p:5000:80 -v /home/michele/sledgemapper/:/app/db -d privateregistry.michelescandura.com/michele/sledgemapper: +``` + +Curl + +Register user +``` + curl -i -X POST -H "Content-Type: application/json" http://localhost:5000/users/register -d '{\"FirstName\":\"Michele\",\"LastName\":\"Scandura\", \"Username\":\"michele.scandura@outlook.com\", \"Password\":\"password1\", \"Initials\":\"MS\"}' +``` + +Login +``` + curl -i -X POST -H "Content-Type: application/json" http://localhost:5000/users/authenticate -d '{\"Username\":\"michele.scandura@outlook.com\", \"Password\":\"password1\"}' +``` + +New Campaign +``` +curl -i -X POST -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6IjEiLCJuYmYiOjE2MTM3MjgzMjksImV4cCI6MTYxNDMzMzEyOCwiaWF0IjoxNjEzNzI4MzI5fQ.VEsDbYUTnnvpgWnB5buE88JyGx_cg3TJb5ybC3eLvmc" http://localhost:5000/campaign/highfell -d '""' +``` + +Get Campaigns +``` +curl -i -X GET -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6IjEiLCJuYmYiOjE2MTM3MjgzMjksImV4cCI6MTYxNDMzMzEyOCwiaWF0IjoxNjEzNzI4MzI5fQ.VEsDbYUTnnvpgWnB5buE88JyGx_cg3TJb5ybC3eLvmc" http://localhost:5000/campaign -d '""' +``` + + +``` +curl -i -X POST -H "Content-Type: application/json" http://localhost:5000/AuthManagement/register -d '{\"FirstName\":\"Michele\",\"LastName\":\"Scandura\", \"UserName\":\"michele\", \"Password\":\"Password1!\", \"Initials\":\"MS\", \"Email\":\"michele.scandura@outlook.com\"}' +``` + +``` +curl -i -X POST -H "Content-Type: application/json" http://localhost:5000/AuthManagement/login -d '{ \"Password\":\"Password1!\", \"Email\":\"michele.scandura@outlook.com\"}' +``` \ No newline at end of file diff --git a/Sledgemapper.Api/Commands/BaseCommand.cs b/Sledgemapper.Api/Commands/BaseCommand.cs index ec640ea..08d526b 100644 --- a/Sledgemapper.Api/Commands/BaseCommand.cs +++ b/Sledgemapper.Api/Commands/BaseCommand.cs @@ -7,13 +7,31 @@ namespace Sledgemapper.Api.Commands { public double Timestamp { get; private set; } public string SessionName { get; private set; } - public int UserId { get; private set; } + public Guid SessionId { get; private set; } + public Guid Campaign { get; private set; } + public string UserId { get; private set; } - public BaseCommand(string sessionName, int userId) + public BaseCommand(string sessionName, string userId) { Timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); SessionName = sessionName; UserId = userId; } + + public BaseCommand(string campaign, string sessionName, string userId) + { + Timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); + SessionName = sessionName; + Campaign = new Guid(campaign); + UserId = userId; + } + + public BaseCommand(Guid campaign, Guid sessionId, string userId) + { + Timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); + SessionId = sessionId; + Campaign = campaign; + UserId = userId; + } } } diff --git a/Sledgemapper.Api/Commands/DeleteNoteCommand.cs b/Sledgemapper.Api/Commands/DeleteNoteCommand.cs index f1a0e9e..c60bfb0 100644 --- a/Sledgemapper.Api/Commands/DeleteNoteCommand.cs +++ b/Sledgemapper.Api/Commands/DeleteNoteCommand.cs @@ -1,3 +1,4 @@ +using System; using Sledgemapper.Shared.Entities; namespace Sledgemapper.Api.Commands @@ -6,7 +7,7 @@ namespace Sledgemapper.Api.Commands { public Note Note { get; private set; } - public DeleteNoteCommand(string sessionName, Note note, int userId) : base(sessionName, userId) + public DeleteNoteCommand(Guid campaign, Guid mapName, Note note, string userId) : base(campaign, mapName, userId) { Note = note; } diff --git a/Sledgemapper.Api/Commands/DeleteOverlayCommand.cs b/Sledgemapper.Api/Commands/DeleteOverlayCommand.cs index e3731d5..abd504d 100644 --- a/Sledgemapper.Api/Commands/DeleteOverlayCommand.cs +++ b/Sledgemapper.Api/Commands/DeleteOverlayCommand.cs @@ -1,12 +1,13 @@ +using System; using Sledgemapper.Shared.Entities; namespace Sledgemapper.Api.Commands { - public class DeleteOverlayCommand : BaseCommand + public class DeleteOverlayCommand : BaseCommand { public Overlay Overlay { get; private set; } - public DeleteOverlayCommand(string sessionName, Overlay overlay, int userId) : base(sessionName, userId) + public DeleteOverlayCommand(Guid campaign, Guid mapName, Overlay overlay, string userId) : base(campaign, mapName, userId) { Overlay = overlay; } diff --git a/Sledgemapper.Api/Commands/DeleteTileCommand.cs b/Sledgemapper.Api/Commands/DeleteTileCommand.cs index 491a7a2..bfc2d31 100644 --- a/Sledgemapper.Api/Commands/DeleteTileCommand.cs +++ b/Sledgemapper.Api/Commands/DeleteTileCommand.cs @@ -1,3 +1,4 @@ +using System; using Sledgemapper.Shared.Entities; namespace Sledgemapper.Api.Commands @@ -6,7 +7,7 @@ namespace Sledgemapper.Api.Commands { public Tile Tile { get; private set; } - public DeleteTileCommand(string sessionName, Tile tile, int userId) : base(sessionName, userId) + public DeleteTileCommand(Guid campaign, Guid mapName, Tile tile, string userId) : base(campaign, mapName, userId) { Tile = tile; } diff --git a/Sledgemapper.Api/Commands/DeleteWallCommand.cs b/Sledgemapper.Api/Commands/DeleteWallCommand.cs index f04edcf..4b38b77 100644 --- a/Sledgemapper.Api/Commands/DeleteWallCommand.cs +++ b/Sledgemapper.Api/Commands/DeleteWallCommand.cs @@ -1,3 +1,4 @@ +using System; using Sledgemapper.Shared.Entities; namespace Sledgemapper.Api.Commands @@ -6,7 +7,7 @@ namespace Sledgemapper.Api.Commands { public Wall Wall { get; private set; } - public DeleteWallCommand(string sessionName, Wall wall, int userId) : base(sessionName, userId) + public DeleteWallCommand(Guid campaign, Guid mapName, Wall wall, string userId) : base(campaign, mapName, userId) { Wall = wall; } diff --git a/Sledgemapper.Api/Commands/GetCampaignMapsCommand.cs b/Sledgemapper.Api/Commands/GetCampaignMapsCommand.cs new file mode 100644 index 0000000..ac420d1 --- /dev/null +++ b/Sledgemapper.Api/Commands/GetCampaignMapsCommand.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using MediatR; +using Sledgemapper.Shared.Entities; + +namespace Sledgemapper.Api.Commands +{ + public class GetCampaignMapsCommand : IRequest> + { + public double Timestamp { get; private set; } + public Guid CampaignId { get; private set; } + public string UserId { get; private set; } + + public GetCampaignMapsCommand(Guid campaignId, string userId) + { + Timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); + CampaignId = campaignId; + UserId = userId; + } + } +} \ No newline at end of file diff --git a/Sledgemapper.Api/Commands/GetCampaignPlayersCommand.cs b/Sledgemapper.Api/Commands/GetCampaignPlayersCommand.cs new file mode 100644 index 0000000..0b733f7 --- /dev/null +++ b/Sledgemapper.Api/Commands/GetCampaignPlayersCommand.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using MediatR; +using Sledgemapper.Shared.Entities; + +namespace Sledgemapper.Api.Commands +{ + public class GetCampaignPlayersCommand : IRequest> + { + public double Timestamp { get; private set; } + public string CampaignName { get; private set; } + public string UserId { get; private set; } + public Guid CampaignId { get; private set; } + + public GetCampaignPlayersCommand(string campaingName, string userId) + { + Timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); + CampaignName = campaingName; + UserId = userId; + } + + public GetCampaignPlayersCommand(Guid campaignId, string userId) + { + Timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); + CampaignId = campaignId; + UserId = userId; + } + } +} \ No newline at end of file diff --git a/Sledgemapper.Api/Commands/GetCampaignsCommand.cs b/Sledgemapper.Api/Commands/GetCampaignsCommand.cs new file mode 100644 index 0000000..520717d --- /dev/null +++ b/Sledgemapper.Api/Commands/GetCampaignsCommand.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using MediatR; +using Sledgemapper.Shared.Entities; + +namespace Sledgemapper.Api.Commands +{ + public class GetCampaignsCommand : IRequest> + { + public string UserId { get; private set; } + public GetCampaignsCommand(string userId) + { + UserId = userId; + } + } + +} \ No newline at end of file diff --git a/Sledgemapper.Api/Commands/GetMapSnapshotCommand.cs b/Sledgemapper.Api/Commands/GetMapSnapshotCommand.cs index 74047a8..228d855 100644 --- a/Sledgemapper.Api/Commands/GetMapSnapshotCommand.cs +++ b/Sledgemapper.Api/Commands/GetMapSnapshotCommand.cs @@ -1,14 +1,18 @@ using MediatR; using Sledgemapper.Shared.Entities; +using System; namespace Sledgemapper.Api.Commands { public class GetMapSnapshotCommand : IRequest { - public string SessionName { get; private set; } - public GetMapSnapshotCommand(string sessionName) + public Guid MapId { get; private set; } + public Guid CampaignId { get; private set; + } + public GetMapSnapshotCommand(Guid campaignId, Guid mapId) { - SessionName = sessionName; + MapId = mapId; + CampaignId = campaignId; } } } diff --git a/Sledgemapper.Api/Commands/InvitePlayerToCampaignCommand.cs b/Sledgemapper.Api/Commands/InvitePlayerToCampaignCommand.cs new file mode 100644 index 0000000..de5aa7c --- /dev/null +++ b/Sledgemapper.Api/Commands/InvitePlayerToCampaignCommand.cs @@ -0,0 +1,21 @@ +using System; +using MediatR; + +namespace Sledgemapper.Api.Commands +{ + public class InvitePlayerToCampaignCommand : IRequest + { + public double Timestamp { get; private set; } + public Guid CampaignId { get; private set; } + public string Email { get; private set; } + public string UserId { get; private set; } + public InvitePlayerToCampaignCommand(Guid campaignId, string email, string userId) + { + Timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); + CampaignId = campaignId; + UserId = userId; + Email = email; + } + } + +} \ No newline at end of file diff --git a/Sledgemapper.Api/Commands/NewCampaignCommand.cs b/Sledgemapper.Api/Commands/NewCampaignCommand.cs new file mode 100644 index 0000000..26399bf --- /dev/null +++ b/Sledgemapper.Api/Commands/NewCampaignCommand.cs @@ -0,0 +1,19 @@ +using System; +using MediatR; + +namespace Sledgemapper.Api.Commands +{ + public class NewCampaignCommand : IRequest + { + public double Timestamp { get; private set; } + public string CampaignName { get; private set; } + public string UserId { get; private set; } + public NewCampaignCommand(string campaingName, string userId) + { + Timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); + CampaignName = campaingName; + UserId = userId; + } + } + +} \ No newline at end of file diff --git a/Sledgemapper.Api/Commands/NewLineCommand.cs b/Sledgemapper.Api/Commands/NewLineCommand.cs index 3bfe3cf..ce98c1a 100644 --- a/Sledgemapper.Api/Commands/NewLineCommand.cs +++ b/Sledgemapper.Api/Commands/NewLineCommand.cs @@ -1,4 +1,5 @@ using Sledgemapper.Shared.Entities; +using System; namespace Sledgemapper.Api.Commands { @@ -6,7 +7,7 @@ namespace Sledgemapper.Api.Commands { public Line Line { get; private set; } - public NewLineCommand(string sessionName, Line line, int userId) : base(sessionName, userId) + public NewLineCommand(Guid campaign, Guid mapName, Line line, string userId) : base(campaign, mapName, userId) { Line = line; } diff --git a/Sledgemapper.Api/Commands/NewNoteCommand.cs b/Sledgemapper.Api/Commands/NewNoteCommand.cs index 5c2dfb6..97a9b31 100644 --- a/Sledgemapper.Api/Commands/NewNoteCommand.cs +++ b/Sledgemapper.Api/Commands/NewNoteCommand.cs @@ -1,4 +1,5 @@ using Sledgemapper.Shared.Entities; +using System; namespace Sledgemapper.Api.Commands { @@ -6,7 +7,7 @@ namespace Sledgemapper.Api.Commands { public Note Note { get; private set; } - public NewNoteCommand(string sessionName, Note note, int userId) : base(sessionName, userId) + public NewNoteCommand(Guid campaignId, Guid mapId, Note note, string userId) : base(campaignId, mapId, userId) { Note = note; } diff --git a/Sledgemapper.Api/Commands/NewOverlayCommand.cs b/Sledgemapper.Api/Commands/NewOverlayCommand.cs index 0aa4078..8d2d659 100644 --- a/Sledgemapper.Api/Commands/NewOverlayCommand.cs +++ b/Sledgemapper.Api/Commands/NewOverlayCommand.cs @@ -1,4 +1,5 @@ using Sledgemapper.Shared.Entities; +using System; namespace Sledgemapper.Api.Commands { @@ -6,7 +7,7 @@ namespace Sledgemapper.Api.Commands { public Overlay Overlay { get; private set; } - public NewOverlayCommand(string sessionName, Overlay overlay, int userId) : base(sessionName, userId) + public NewOverlayCommand(Guid campaignId, Guid mapId, Overlay overlay, string userId) : base(campaignId, mapId, userId) { Overlay = overlay; } diff --git a/Sledgemapper.Api/Commands/NewRoomCommand.cs b/Sledgemapper.Api/Commands/NewRoomCommand.cs index 5b7619e..a44c836 100644 --- a/Sledgemapper.Api/Commands/NewRoomCommand.cs +++ b/Sledgemapper.Api/Commands/NewRoomCommand.cs @@ -1,4 +1,5 @@ using Sledgemapper.Shared.Entities; +using System; namespace Sledgemapper.Api.Commands { @@ -6,7 +7,7 @@ namespace Sledgemapper.Api.Commands { public Room Room { get; private set; } - public NewRoomCommand(string sessionName, Room room, int userId) : base(sessionName, userId) + public NewRoomCommand(Guid campaignId, Guid mapId, Room room, string userId) : base(campaignId, mapId, userId) { Room = room; } diff --git a/Sledgemapper.Api/Commands/NewSessionCommand.cs b/Sledgemapper.Api/Commands/NewSessionCommand.cs index 4b184cb..ab42380 100644 --- a/Sledgemapper.Api/Commands/NewSessionCommand.cs +++ b/Sledgemapper.Api/Commands/NewSessionCommand.cs @@ -1,9 +1,12 @@ +using System; + namespace Sledgemapper.Api.Commands { - public class NewSessionCommand : BaseCommand + public class NewSessionCommand : BaseCommand { - public NewSessionCommand(string sessionName, int userId):base(sessionName, userId) + public NewSessionCommand(string campaign, string sessionName, string userId) : base(campaign, sessionName, userId) { } } + } \ No newline at end of file diff --git a/Sledgemapper.Api/Commands/NewSnapshotCommand.cs b/Sledgemapper.Api/Commands/NewSnapshotCommand.cs index 8ec87b1..057ec88 100644 --- a/Sledgemapper.Api/Commands/NewSnapshotCommand.cs +++ b/Sledgemapper.Api/Commands/NewSnapshotCommand.cs @@ -5,7 +5,7 @@ namespace Sledgemapper.Api.Commands public class NewSnapshotCommand : BaseCommand { public Session Session { get; private set; } - public NewSnapshotCommand(string sessionName, Session session, int userId) : base(sessionName, userId) + public NewSnapshotCommand(string sessionName, Session session, string userId) : base(sessionName, userId) { Session = session; } diff --git a/Sledgemapper.Api/Commands/NewTileCommand.cs b/Sledgemapper.Api/Commands/NewTileCommand.cs index 4fbd5f3..522adf6 100644 --- a/Sledgemapper.Api/Commands/NewTileCommand.cs +++ b/Sledgemapper.Api/Commands/NewTileCommand.cs @@ -5,7 +5,7 @@ namespace Sledgemapper.Api.Commands public class NewTileCommand : BaseCommand { public Tile Tile { get; private set; } - public NewTileCommand(string sessionName, Tile tile, int userId) : base(sessionName, userId) + public NewTileCommand(string sessionName, Tile tile, string userId) : base(sessionName, userId) { Tile = tile; } diff --git a/Sledgemapper.Api/Commands/NewWallCommand.cs b/Sledgemapper.Api/Commands/NewWallCommand.cs index c8c72fd..f9682fb 100644 --- a/Sledgemapper.Api/Commands/NewWallCommand.cs +++ b/Sledgemapper.Api/Commands/NewWallCommand.cs @@ -1,4 +1,5 @@ using Sledgemapper.Shared.Entities; +using System; namespace Sledgemapper.Api.Commands { @@ -6,7 +7,7 @@ namespace Sledgemapper.Api.Commands { public Wall Wall { get; private set; } - public NewWallCommand(string sessionName, Wall wall, int userId) : base(sessionName, userId) + public NewWallCommand(Guid campaignId, Guid mapId, Wall wall, string userId) : base(campaignId, mapId, userId) { Wall = wall; } diff --git a/Sledgemapper.Api/Controllers/AuthManagementController.cs b/Sledgemapper.Api/Controllers/AuthManagementController.cs new file mode 100644 index 0000000..33b088c --- /dev/null +++ b/Sledgemapper.Api/Controllers/AuthManagementController.cs @@ -0,0 +1,185 @@ +using AutoMapper; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; +using Microsoft.IdentityModel.Tokens; +using System; +using System.Collections.Generic; +using System.IdentityModel.Tokens.Jwt; +using System.Linq; +using System.Security.Claims; +using System.Text; +using System.Threading.Tasks; +using Sledgemapper.Api.Core.Entities; +using Sledgemapper.Api.Models; + +namespace Sledgemapper.Api.Controllers +{ + [Route("[controller]")] // api/authmanagement + [ApiController] + public class AuthManagementController : ControllerBase + { + private readonly UserManager _userManager; + private readonly JwtConfig _jwtConfig; + private readonly IMapper _mapper; + + public AuthManagementController(UserManager userManager, + IOptionsMonitor optionsMonitor, + IMapper mapper) + { + _userManager = userManager; + _jwtConfig = optionsMonitor.CurrentValue; + _mapper = mapper; + } + + [HttpPost] + [Route("Register")] + public async Task Register([FromBody] RegisterModel user) + { + // Check if the incoming request is valid + if (ModelState.IsValid) + { + // check i the user with the same email exist + var existingUser = await _userManager.FindByEmailAsync(user.Email); + + if (existingUser != null) + { + return BadRequest(new RegistrationResponse() + { + Result = false, + Errors = new List(){ + "Email already exist" + } + }); + } + + var newUser = _mapper.Map(user); + // var newUser = new User() { Email = user.Email, UserName = user.UserName }; + var isCreated = await _userManager.CreateAsync(newUser, user.Password); + if (isCreated.Succeeded) + { + var jwtToken = GenerateJwtToken(newUser); + + return Ok(new RegistrationResponse() + { + Result = true, + Token = jwtToken + }); + } + + return new JsonResult(new RegistrationResponse() + { + Result = false, + Errors = isCreated.Errors.Select(x => x.Description).ToList() + } + ) + { StatusCode = 500 }; + } + + return BadRequest(new RegistrationResponse() + { + Result = false, + Errors = new List(){ + "Invalid payload" + } + }); + } + + [HttpPost] + [Route("Login")] + public async Task Login([FromBody] UserLoginRequest user) + { + if (ModelState.IsValid) + { + // check if the user with the same email exist + var existingUser = await _userManager.FindByEmailAsync(user.Email); + + if (existingUser == null) + { + // We dont want to give to much information on why the request has failed for security reasons + return BadRequest(new RegistrationResponse() + { + Result = false, + Errors = new List(){ + "Invalid authentication request" + } + }); + } + + // Now we need to check if the user has inputed the right password + var isCorrect = await _userManager.CheckPasswordAsync(existingUser, user.Password); + + if (isCorrect) + { + var jwtToken = GenerateJwtToken(existingUser); + + return Ok(new LoginResponse() + { + Result = true, + Token = jwtToken, + Username = existingUser.Email, + Initials = existingUser.Initials, + Id = existingUser.Id + }); + } + else + { + // We dont want to give to much information on why the request has failed for security reasons + return BadRequest(new RegistrationResponse() + { + Result = false, + Errors = new List(){ + "Invalid authentication request" + } + }); + } + } + + return BadRequest(new RegistrationResponse() + { + Result = false, + Errors = new List(){ + "Invalid payload" + } + }); + } + + private string GenerateJwtToken(User user) + { + // Now its ime to define the jwt token which will be responsible of creating our tokens + var jwtTokenHandler = new JwtSecurityTokenHandler(); + + // We get our secret from the appsettings + var key = Encoding.ASCII.GetBytes(_jwtConfig.Secret); + + // we define our token descriptor + // We need to utilise claims which are properties in our token which gives information about the token + // which belong to the specific user who it belongs to + // so it could contain their id, name, email the good part is that these information + // are generated by our server and identity framework which is valid and trusted + var tokenDescriptor = new SecurityTokenDescriptor + { + + Subject = new ClaimsIdentity(new[] + { + new Claim("Id", user.Id), + new Claim(JwtRegisteredClaimNames.Sub, user.Email), + new Claim(JwtRegisteredClaimNames.Email, user.Email), + // the JTI is used for our refresh token which we will be convering in the next video + new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()) + }), + // the life span of the token needs to be shorter and utilise refresh token to keep the user signedin + // but since this is a demo app we can extend it to fit our current need + Expires = DateTime.UtcNow.AddHours(6), + // here we are adding the encryption alogorithim information which will be used to decrypt our token + SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha512Signature) + }; + + var token = jwtTokenHandler.CreateToken(tokenDescriptor); + + var jwtToken = jwtTokenHandler.WriteToken(token); + + return jwtToken; + } + } +} diff --git a/Sledgemapper.Api/Controllers/CampaignController.cs b/Sledgemapper.Api/Controllers/CampaignController.cs new file mode 100644 index 0000000..77a6dc5 --- /dev/null +++ b/Sledgemapper.Api/Controllers/CampaignController.cs @@ -0,0 +1,76 @@ +using MediatR; +using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Sledgemapper.Api.Commands; +using Sledgemapper.Shared.Entities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Sledgemapper.Api.Controllers +{ + [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] + [Route("[controller]")] + public class CampaignController : ControllerBase + { + private readonly IMediator _mediator; + private string UserId => HttpContext.User.Claims.FirstOrDefault(m => m.Type == "Id").Value; + + public CampaignController(IMediator mediator) => _mediator = mediator; + + [HttpPost] + [Route("{campaignName}")] + public async Task> Post(string campaignName) + { + var result = await _mediator.Send(new NewCampaignCommand(campaignName, UserId)); + if (!result) + { + return BadRequest(); + } + return result; + } + + //[HttpPost] + //[Route("{campaignName}")] + //public async Task Get(string campaignName) + //{ + // var result = await _mediator.Send(new GetCampaignCommand(campaignName, UserId.ToString())); + // return result; + //} + + [HttpGet] + public async Task> Get() + { + var result = await _mediator.Send(new GetCampaignsCommand(UserId)); + return result; + } + + [HttpPost] + [Route("{campaignId}/players/{email}")] + public async Task Invite(Guid campaignId, string email) + { + var result = await _mediator.Send(new InvitePlayerToCampaignCommand(campaignId, email, UserId)); + return result; + } + + [HttpGet] + [Route("{campaignName}/players")] + public async Task> GetPlayers(Guid campaignName) + { + var result = await _mediator.Send(new GetCampaignPlayersCommand(campaignName, UserId)); + return result; + } + + + [HttpGet] + [Route("{campaignName}/maps")] + public async Task> GetMaps(Guid campaignName) + { + var result = await _mediator.Send(new GetCampaignMapsCommand(campaignName, UserId)); + return result; + } + + } +} \ No newline at end of file diff --git a/Sledgemapper.Api/Controllers/MapController.cs b/Sledgemapper.Api/Controllers/MapController.cs new file mode 100644 index 0000000..361a9a8 --- /dev/null +++ b/Sledgemapper.Api/Controllers/MapController.cs @@ -0,0 +1,100 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using MediatR; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Sledgemapper.Api.Commands; +using Sledgemapper.Shared.Entities; + +namespace Sledgemapper.Api.Controllers +{ + [Authorize] + [Route("[controller]/{campaign}/{mapName}")] + public class MapController : ControllerBase + { + private readonly IMediator _mediator; + + public MapController(IMediator mediator) + { + _mediator = mediator; + } + + private string UserId => HttpContext.User.Claims.FirstOrDefault(m => m.Type == "Id").Value; + + [HttpDelete("overlay")] + public async Task Delete(Guid campaign, Guid mapName, [FromBody] Overlay overlay) + { + await _mediator.Send(new DeleteOverlayCommand(campaign, mapName, overlay, UserId)); + } + + [HttpDelete("wall")] + public async Task Delete(Guid campaign, Guid mapName, [FromBody] Wall wall) + { + await _mediator.Send(new DeleteWallCommand(campaign, mapName, wall, UserId)); + } + + [HttpDelete("note")] + public async Task Delete(Guid campaign, Guid mapName, [FromBody] Note note) + { + await _mediator.Send(new DeleteNoteCommand(campaign, mapName, note, UserId)); + } + + + [HttpDelete("tile")] + public async Task Delete(Guid campaign, Guid mapName, [FromBody] Tile tile) + { + await _mediator.Send(new DeleteTileCommand(campaign, mapName, tile, UserId)); + } + + [HttpGet] + public async Task Get(Guid campaign, Guid mapName) + { + var result = await _mediator.Send(new GetMapSnapshotCommand(campaign, mapName)); + return result; + } + + [HttpPost] + public async Task Post(string campaign, string mapName) + { + var result = await _mediator.Send(new NewSessionCommand(campaign, mapName, UserId)); + return result; + } + + [HttpPost("snapshot")] + public async Task Post(string campaign, string mapName, [FromBody] Session session) + { + await _mediator.Send(new NewSnapshotCommand(mapName, session, UserId)); + } + + [HttpPost("overlay")] + public async Task Post(Guid campaign, Guid mapName, [FromBody] Overlay overlay) + { + await _mediator.Send(new NewOverlayCommand(campaign, mapName, overlay, UserId)); + } + + [HttpPost("wall")] + public async Task Post(Guid campaign, Guid mapName, [FromBody] Wall wall) + { + await _mediator.Send(new NewWallCommand(campaign, mapName, wall, UserId)); + } + + [HttpPost("note")] + public async Task Post(Guid campaign, Guid mapName, [FromBody] Note note) + { + await _mediator.Send(new NewNoteCommand(campaign, mapName, note, UserId)); + } + + [HttpPost("room")] + public async Task Post(Guid campaign, Guid mapName, [FromBody] Room room) + { + await _mediator.Send(new NewRoomCommand(campaign, mapName, room, UserId)); + } + + [HttpPost("line")] + public async Task Post(Guid campaign, Guid mapName, [FromBody] Line line) + { + await _mediator.Send(new NewLineCommand(campaign, mapName, line, UserId)); + } + } +} \ No newline at end of file diff --git a/Sledgemapper.Api/Controllers/SessionController.cs b/Sledgemapper.Api/Controllers/SessionController.cs deleted file mode 100644 index 4926ba2..0000000 --- a/Sledgemapper.Api/Controllers/SessionController.cs +++ /dev/null @@ -1,106 +0,0 @@ -using MediatR; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using Sledgemapper.Api.Commands; -using Sledgemapper.Api.Notifications; -using Sledgemapper.Shared.Entities; -using System.Threading.Tasks; - -namespace Sledgemapper.Api.Controllers -{ - [Authorize] - [Route("[controller]/{sessionName}")] - public class SessionController : ControllerBase - { - private readonly IMediator _mediator; - private int UserId => int.Parse(HttpContext.User.Identity.Name); - - public SessionController(IMediator mediator) => _mediator = mediator; - - [HttpPost] - public async Task Post(string sessionName) - { - var result = await _mediator.Send(new NewSessionCommand(sessionName, UserId)); - return result; - } - - [HttpGet] - public async Task Get(string sessionName) - { - var result = await _mediator.Send(new GetMapSnapshotCommand(sessionName)); - return result; - } - - // [HttpPost("ping")] - // public async Task Post(string sessionName, [FromBody] Ping pingLocation) - // { - // await _mediator.Send(new PingCommand(sessionName, pingLocation, UserId)); - // } - - [HttpPost("snapshot")] - public async Task Post(string sessionName, [FromBody] Session session) - { - await _mediator.Send(new NewSnapshotCommand(sessionName, session, UserId)); - } - - [HttpPost("tile")] - public async Task Post(string sessionName, [FromBody] Tile tile) - { - await _mediator.Send(new NewTileCommand(sessionName, tile, UserId)); - } - - [HttpPost("overlay")] - public async Task Post(string sessionName, [FromBody] Overlay overlay) - { - await _mediator.Send(new NewOverlayCommand(sessionName, overlay, UserId)); - } - - [HttpPost("wall")] - public async Task Post(string sessionName, [FromBody] Wall wall) - { - await _mediator.Send(new NewWallCommand(sessionName, wall, UserId)); - } - - [HttpPost("note")] - public async Task Post(string sessionName, [FromBody] Note note) - { - await _mediator.Send(new NewNoteCommand(sessionName, note, UserId)); - } - - [HttpPost("room")] - public async Task Post(string sessionName, [FromBody] Room room) - { - await _mediator.Send(new NewRoomCommand(sessionName, room, UserId)); - } - - [HttpPost("line")] - public async Task Post(string sessionName, [FromBody] Line line) - { - await _mediator.Send(new NewLineCommand(sessionName, line, UserId)); - } - - [HttpDelete("tile")] - public async Task Delete(string sessionName, [FromBody] Tile tile) - { - await _mediator.Send(new DeleteTileCommand(sessionName, tile, UserId)); - } - - [HttpDelete("overlay")] - public async Task Delete(string sessionName, [FromBody] Overlay overlay) - { - await _mediator.Send(new DeleteOverlayCommand(sessionName, overlay, UserId)); - } - - [HttpDelete("wall")] - public async Task Delete(string sessionName, [FromBody] Wall wall) - { - await _mediator.Send(new DeleteWallCommand(sessionName, wall, UserId)); - } - - [HttpDelete("note")] - public async Task Delete(string sessionName, [FromBody] Note note) - { - await _mediator.Send(new DeleteNoteCommand(sessionName, note, UserId)); - } - } -} \ No newline at end of file diff --git a/Sledgemapper.Api/Controllers/UsersController.cs b/Sledgemapper.Api/Controllers/UsersController.cs deleted file mode 100644 index 7988025..0000000 --- a/Sledgemapper.Api/Controllers/UsersController.cs +++ /dev/null @@ -1,136 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.AspNetCore.Mvc; -using AutoMapper; -using System.IdentityModel.Tokens.Jwt; - -using Microsoft.Extensions.Options; -using System.Text; -using Microsoft.IdentityModel.Tokens; -using System.Security.Claims; -using Microsoft.AspNetCore.Authorization; -using Sledgemapper.Services; -using Sledgemapper.Entities; -using Sledgemapper.Models.Users; -using Sledgemapper.Helpers; - -namespace Sledgemapper.Controllers -{ - [Authorize] - [ApiController] - [Route("[controller]")] - public class UsersController : ControllerBase - { - private IUserService _userService; - private IMapper _mapper; - private readonly AppSettings _appSettings; - - public UsersController( - IUserService userService, - IMapper mapper, - IOptions appSettings) - { - _userService = userService; - _mapper = mapper; - _appSettings = appSettings.Value; - } - - [AllowAnonymous] - [HttpPost("authenticate")] - public IActionResult Authenticate([FromBody]AuthenticateModel model) - { - var user = _userService.Authenticate(model.Username, model.Password); - - if (user == null) - return BadRequest(new { message = "Username or password is incorrect" }); - - var tokenHandler = new JwtSecurityTokenHandler(); - var key = Encoding.ASCII.GetBytes(_appSettings.Secret); - var tokenDescriptor = new SecurityTokenDescriptor - { - Subject = new ClaimsIdentity(new Claim[] - { - new Claim(ClaimTypes.Name, user.Id.ToString()) - }), - Expires = DateTime.UtcNow.AddDays(7), - SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) - }; - var token = tokenHandler.CreateToken(tokenDescriptor); - var tokenString = tokenHandler.WriteToken(token); - - // return basic user info and authentication token - return Ok(new - { - Id = user.Id, - Username = user.Username, - FirstName = user.FirstName, - LastName = user.LastName, - Initials = user.Initials, - Token = tokenString - }); - } - - [AllowAnonymous] - [HttpPost("register")] - public IActionResult Register([FromBody]RegisterModel model) - { - // map model to entity - var user = _mapper.Map(model); - - try - { - // create user - _userService.Create(user, model.Password); - return Ok(); - } - catch (AppException ex) - { - // return error message if there was an exception - return BadRequest(new { message = ex.Message }); - } - } - - [HttpGet] - public IActionResult GetAll() - { - var users = _userService.GetAll(); - var model = _mapper.Map>(users); - return Ok(model); - } - - [HttpGet("{id}")] - public IActionResult GetById(int id) - { - var user = _userService.GetById(id); - var model = _mapper.Map(user); - return Ok(model); - } - - [HttpPut("{id}")] - public IActionResult Update(int id, [FromBody]UpdateModel model) - { - // map model to entity and set id - var user = _mapper.Map(model); - user.Id = id; - - try - { - // update user - _userService.Update(user, model.Password); - return Ok(); - } - catch (AppException ex) - { - // return error message if there was an exception - return BadRequest(new { message = ex.Message }); - } - } - - [HttpDelete("{id}")] - public IActionResult Delete(int id) - { - _userService.Delete(id); - return Ok(); - } - } -} diff --git a/Sledgemapper.Api/Core/Entities/BaseEntity.cs b/Sledgemapper.Api/Core/Entities/BaseEntity.cs new file mode 100644 index 0000000..5196c35 --- /dev/null +++ b/Sledgemapper.Api/Core/Entities/BaseEntity.cs @@ -0,0 +1,7 @@ +using System.ComponentModel.DataAnnotations; + +public abstract class BaseEntity +{ + [Key] + public int Id { get; set; } +} \ No newline at end of file diff --git a/Sledgemapper.Api/Core/Entities/Campaign.cs b/Sledgemapper.Api/Core/Entities/Campaign.cs new file mode 100644 index 0000000..04a18de --- /dev/null +++ b/Sledgemapper.Api/Core/Entities/Campaign.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using Microsoft.EntityFrameworkCore; +using Sledgemapper.Api.Models; + +namespace Sledgemapper.Api.Core.Entities +{ + [Index(nameof(CampaignName), nameof(OwnerId), IsUnique = true)] + public class Campaign + { + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public Guid CampaignId { get; set; } + + public string CampaignName { get; set; } + + public string OwnerId { get; set; } + + public User Owner { get; set; } + + public ICollection InvitedUsers { get; set; } + + public ICollection Maps { get; set; } + } +} diff --git a/Sledgemapper.Api/Core/Entities/Map.cs b/Sledgemapper.Api/Core/Entities/Map.cs new file mode 100644 index 0000000..b46a373 --- /dev/null +++ b/Sledgemapper.Api/Core/Entities/Map.cs @@ -0,0 +1,17 @@ +using System.ComponentModel.DataAnnotations; + +namespace Sledgemapper.Api.Core.Entities +{ + public class Map + { + [Key] + public int MapId { get; set; } + + [Required] + public string MapName { get; set; } + + [Required] + public int CampaignId { get; set; } + + } +} diff --git a/Sledgemapper.Api/Models/MapLog.cs b/Sledgemapper.Api/Core/Entities/MapLog.cs similarity index 78% rename from Sledgemapper.Api/Models/MapLog.cs rename to Sledgemapper.Api/Core/Entities/MapLog.cs index d519df8..4d004f6 100644 --- a/Sledgemapper.Api/Models/MapLog.cs +++ b/Sledgemapper.Api/Core/Entities/MapLog.cs @@ -1,6 +1,7 @@ +using System; using System.ComponentModel.DataAnnotations; -namespace Sledgemapper.Api.Models +namespace Sledgemapper.Api.Core.Entities { public class MapLog @@ -9,10 +10,10 @@ namespace Sledgemapper.Api.Models public int MapLogId { get; set; } [Required] - public int UserId{get;set;} + public string UserId { get; set; } [Required] - public int SessionId { get; set; } + public Guid SessionId { get; set; } [Required] [MaxLength(1)] diff --git a/Sledgemapper.Api/Core/Entities/Session.cs b/Sledgemapper.Api/Core/Entities/Session.cs new file mode 100644 index 0000000..52029db --- /dev/null +++ b/Sledgemapper.Api/Core/Entities/Session.cs @@ -0,0 +1,24 @@ +using Microsoft.EntityFrameworkCore; +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Sledgemapper.Api.Core.Entities +{ + [Index(nameof(CampaignId), nameof(SessionName), IsUnique = true)] + public class Session + { + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + [Key] + public Guid SessionId { get; set; } + + [Required] + public Guid CampaignId { get; set; } + + [Required] + public string SessionName { get; set; } + + [Required] + public string OwnerUserId { get; set; } + } +} diff --git a/Sledgemapper.Api/Models/SessionUser.cs b/Sledgemapper.Api/Core/Entities/SessionUser.cs similarity index 57% rename from Sledgemapper.Api/Models/SessionUser.cs rename to Sledgemapper.Api/Core/Entities/SessionUser.cs index 86ba520..b2136c0 100644 --- a/Sledgemapper.Api/Models/SessionUser.cs +++ b/Sledgemapper.Api/Core/Entities/SessionUser.cs @@ -1,6 +1,7 @@ +using System; using System.ComponentModel.DataAnnotations; -namespace Sledgemapper.Api.Models +namespace Sledgemapper.Api.Core.Entities { public class SessionUser { @@ -8,9 +9,9 @@ namespace Sledgemapper.Api.Models public int SessionUserId { get; set; } [Required] - public int SessionId { get; set; } + public Guid SessionId { get; set; } [Required] - public int UserId { get; set; } + public Guid UserId { get; set; } } } diff --git a/Sledgemapper.Api/Models/Snapshot.cs b/Sledgemapper.Api/Core/Entities/Snapshot.cs similarity index 74% rename from Sledgemapper.Api/Models/Snapshot.cs rename to Sledgemapper.Api/Core/Entities/Snapshot.cs index 31b5e55..2a577e2 100644 --- a/Sledgemapper.Api/Models/Snapshot.cs +++ b/Sledgemapper.Api/Core/Entities/Snapshot.cs @@ -1,6 +1,7 @@ +using System; using System.ComponentModel.DataAnnotations; -namespace Sledgemapper.Api.Models +namespace Sledgemapper.Api.Core.Entities { public class Snapshot @@ -9,8 +10,7 @@ namespace Sledgemapper.Api.Models public int SnapshotId { get; set; } [Required] - public int SessionId { get; set; } - + public Guid SessionId { get; set; } [Required] public string Object { get; set; } diff --git a/Sledgemapper.Api/Core/Entities/User.cs b/Sledgemapper.Api/Core/Entities/User.cs new file mode 100644 index 0000000..bc29784 --- /dev/null +++ b/Sledgemapper.Api/Core/Entities/User.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using Microsoft.AspNetCore.Identity; + +namespace Sledgemapper.Api.Core.Entities +{ + public class User : IdentityUser + { + // public int Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } + // public string Email { get; set; } + // public string Username { get; set; } + public string Initials { get; set; } + // public byte[] PasswordHash { get; set; } + public byte[] PasswordSalt { get; set; } + public ICollection Campaigns { get; set; } + } +} \ No newline at end of file diff --git a/Sledgemapper.Api/Models/UserConnection.cs b/Sledgemapper.Api/Core/Entities/UserConnection.cs similarity index 57% rename from Sledgemapper.Api/Models/UserConnection.cs rename to Sledgemapper.Api/Core/Entities/UserConnection.cs index ea32a9c..17e34a3 100644 --- a/Sledgemapper.Api/Models/UserConnection.cs +++ b/Sledgemapper.Api/Core/Entities/UserConnection.cs @@ -1,15 +1,16 @@ +using System; using System.ComponentModel.DataAnnotations; -namespace Sledgemapper.Api.Models +namespace Sledgemapper.Api.Core.Entities { public class UserConnection { [Key] public int UserConnectionId { get; set; } [Required] - public int UserId { get; set; } + public Guid UserId { get; set; } [Required] - public string ConnectionId{get;set;} + public string ConnectionId { get; set; } } } diff --git a/Sledgemapper.Api/Data/MyDbContext.cs b/Sledgemapper.Api/Data/MyDbContext.cs deleted file mode 100644 index aca62cd..0000000 --- a/Sledgemapper.Api/Data/MyDbContext.cs +++ /dev/null @@ -1,81 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Sledgemapper.Api.Models; -namespace Sledgemapper.Api.Data -{ - public static class DbInitializer - { - public static void Initialize(MyDbContext context) - { - context.Database.EnsureCreated(); - } - } - - public class MyDbContext : DbContext - { - public DbSet MapLogs { get; set; } - public DbSet Sessions { get; set; } - public DbSet UserConnections { get; set; } - public DbSet SessionUsers { get; set; } - public DbSet Snapshots { get; set; } - - public MyDbContext(DbContextOptions options) : base(options) - { - - } - - // protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - // { - // // optionsBuilder. - // // options.MigrationsAssembly(Assembly.GetExecutingAssembly().FullName); - // // optionsBuilder.UseSqlite("Filename=SledgemapperDatabase.db", options => - // // { - // // options.MigrationsAssembly(Assembly.GetExecutingAssembly().FullName); - // // }); - // optionsBuilder.UseSqlite("Filename=MyDatabase.db").UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking); - - // base.OnConfiguring(optionsBuilder); - // } - - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - // Map table names - modelBuilder.Entity().ToTable("MapLog", "dbo"); - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.MapLogId); - }); - - modelBuilder.Entity().ToTable("Session", "dbo"); - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.SessionId); - entity.HasIndex(e => e.SessionName).IsUnique(); - }); - - - modelBuilder.Entity().ToTable("UserConnection", "dbo"); - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.UserConnectionId); - entity.HasIndex(e => e.UserId); - - }); - - modelBuilder.Entity().ToTable("SessionUser", "dbo"); - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.SessionUserId); - entity.HasIndex(e => e.SessionId); - - }); - - modelBuilder.Entity().ToTable("Snapshot", "dbo"); - modelBuilder.Entity(entity => - { - entity.HasKey(e => e.SnapshotId); - }); - - base.OnModelCreating(modelBuilder); - } - } -} \ No newline at end of file diff --git a/Sledgemapper.Api/Entities/User.cs b/Sledgemapper.Api/Entities/User.cs deleted file mode 100644 index 00eb6d7..0000000 --- a/Sledgemapper.Api/Entities/User.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Sledgemapper.Entities -{ - public class User - { - public int Id { get; set; } - public string FirstName { get; set; } - public string LastName { get; set; } - public string Username { get; set; } - public string Initials { get; set; } - public byte[] PasswordHash { get; set; } - public byte[] PasswordSalt { get; set; } - } -} \ No newline at end of file diff --git a/Sledgemapper.Api/Handlers/BaseCommandHandler.cs b/Sledgemapper.Api/Handlers/BaseCommandHandler.cs new file mode 100644 index 0000000..f9a8dea --- /dev/null +++ b/Sledgemapper.Api/Handlers/BaseCommandHandler.cs @@ -0,0 +1,76 @@ +using MediatR; +using Sledgemapper.Api.Commands; +using Sledgemapper.Api.Infrastructure.Data; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using System; +using Microsoft.EntityFrameworkCore; +using Sledgemapper.Api.Models; +using Sledgemapper.Api.Core.Entities; + +namespace Sledgemapper.Api.Handlers +{ + public abstract class BaseCommandHandler : IRequestHandler where TRequest : BaseCommand + { + protected SledgemapperDbContext DbContext { get; } + + protected IMediator Mediator { get; } + + + public abstract Task Handle(TRequest request, CancellationToken cancellationToken); + + protected BaseCommandHandler(IMediator mediator, SledgemapperDbContext dbContext) + { + DbContext = dbContext; + Mediator = mediator; + } + + protected async Task CheckAuthorization(TRequest command) + { + var user = await DbContext.Users.FindAsync(command.UserId); + DbContext.Attach(user); + + + var campaign = await GetCampaignForUser(command); + + var maps = campaign.Maps.Any(s => s.SessionId == command.SessionId); + + if (!maps) + { + throw new Exception("Unauthorized"); + } + } + + protected async Task GetCampaignForUser(TRequest command) + { + var user = await DbContext.Users.FindAsync(command.UserId); + DbContext.Attach(user); + var campaign = await DbContext + .Campaigns + .Where(campaign => campaign.CampaignId == command.Campaign) + .Include(c => c.InvitedUsers) + .Include(c => c.Maps) + .Include(c => c.Owner) + .Where(campaign => campaign.OwnerId == command.UserId || campaign.InvitedUsers.Contains(user)).FirstAsync(); + return campaign; + } + + protected async Task SaveLog(TRequest command, string operation, string type, string data, CancellationToken cancellationToken) + { + var session = DbContext.Sessions.First(m => m.SessionId == command.SessionId); + DbContext.MapLogs.Add(new MapLog + { + Operation = operation, + SessionId = session.SessionId, + Type = type, + Timestamp = command.Timestamp, + Object = data, + UserId = command.UserId, + }); + await DbContext.SaveChangesAsync(cancellationToken); + return session; + } + + } +} diff --git a/Sledgemapper.Api/Handlers/DeleteNoteCommandHandler.cs b/Sledgemapper.Api/Handlers/DeleteNoteCommandHandler.cs index dc8223b..e2d55c3 100644 --- a/Sledgemapper.Api/Handlers/DeleteNoteCommandHandler.cs +++ b/Sledgemapper.Api/Handlers/DeleteNoteCommandHandler.cs @@ -1,42 +1,25 @@ using MediatR; -using Sledgemapper.Api.Data; +using Sledgemapper.Api.Infrastructure.Data; using Sledgemapper.Api.Commands; using Sledgemapper.Api.Notifications; -using Sledgemapper.Shared.Entities; -using System.Linq; using System.Text.Json; using System.Threading; using System.Threading.Tasks; namespace Sledgemapper.Api.Handlers { - - public class DeleteNoteCommandHandler : IRequestHandler + public class DeleteNoteCommandHandler : BaseCommandHandler { - private readonly MyDbContext _dbcontext; - - private readonly IMediator _mediator; - - public DeleteNoteCommandHandler(IMediator mediator, MyDbContext dbcontext) { _dbcontext = dbcontext; _mediator = mediator; } - - - public async Task Handle(DeleteNoteCommand notification, CancellationToken cancellationToken) + public DeleteNoteCommandHandler(IMediator mediator, SledgemapperDbContext dbcontext) : base(mediator, dbcontext) { - var jsonString = JsonSerializer.Serialize(notification.Note); - var session = _dbcontext.Sessions.First(m => m.SessionName == notification.SessionName); - - _dbcontext.MapLogs.Add(new Sledgemapper.Api.Models.MapLog - { - Operation = "D", - SessionId = session.SessionId, - Type = "N", - Timestamp = notification.Timestamp, - Object = jsonString, - UserId = notification.UserId - }); - await _dbcontext.SaveChangesAsync(); - await _mediator.Publish(new DeleteNoteNotification(session, notification.Note, notification.UserId)); + } + public override async Task Handle(DeleteNoteCommand command, CancellationToken cancellationToken) + { + await CheckAuthorization(command); + var jsonString = JsonSerializer.Serialize(command.Note); + var session = await SaveLog(command, "D", "N", jsonString, cancellationToken); + await Mediator.Publish(new DeleteNoteNotification(session, command.Note, command.UserId), cancellationToken); return true; } } diff --git a/Sledgemapper.Api/Handlers/DeleteOverlayCommandHandler.cs b/Sledgemapper.Api/Handlers/DeleteOverlayCommandHandler.cs index 5069970..a6b2956 100644 --- a/Sledgemapper.Api/Handlers/DeleteOverlayCommandHandler.cs +++ b/Sledgemapper.Api/Handlers/DeleteOverlayCommandHandler.cs @@ -1,40 +1,25 @@ using MediatR; using Sledgemapper.Api.Commands; -using Sledgemapper.Api.Data; -using Sledgemapper.Shared.Entities; +using Sledgemapper.Api.Infrastructure.Data; using Sledgemapper.Api.Notifications; -using System.Linq; using System.Text.Json; using System.Threading; using System.Threading.Tasks; namespace Sledgemapper.Api.Handlers { - public class DeleteOverlayCommandHandler : IRequestHandler + public class DeleteOverlayCommandHandler : BaseCommandHandler { - private readonly MyDbContext _dbcontext; - - private readonly IMediator _mediator; - - public DeleteOverlayCommandHandler(IMediator mediator, MyDbContext dbcontext) { _dbcontext = dbcontext; _mediator = mediator; } - - public async Task Handle(DeleteOverlayCommand notification, CancellationToken cancellationToken) + public DeleteOverlayCommandHandler(IMediator mediator, SledgemapperDbContext dbcontext) : base(mediator, dbcontext) { - var jsonString = JsonSerializer.Serialize(notification.Overlay); - var session = _dbcontext.Sessions.First(m=>m.SessionName== notification.SessionName); + } - _dbcontext.MapLogs.Add(new Sledgemapper.Api.Models.MapLog - { - Operation = "D", - SessionId = session.SessionId, - Type = "O", - Timestamp = notification.Timestamp, - Object = jsonString, - UserId=notification.UserId - }); - - await _dbcontext.SaveChangesAsync(); - await _mediator.Publish(new DeleteOverlayNotification(session, notification.Overlay, notification.UserId)); + public override async Task Handle(DeleteOverlayCommand command, CancellationToken cancellationToken) + { + await CheckAuthorization(command); + var jsonString = JsonSerializer.Serialize(command.Overlay); + var session = await SaveLog(command, "D", "O", jsonString, cancellationToken); + await Mediator.Publish(new DeleteOverlayNotification(session, command.Overlay, command.UserId), cancellationToken); return true; } } diff --git a/Sledgemapper.Api/Handlers/DeleteTileCommandHandler.cs b/Sledgemapper.Api/Handlers/DeleteTileCommandHandler.cs index 40e9858..5c1cd1d 100644 --- a/Sledgemapper.Api/Handlers/DeleteTileCommandHandler.cs +++ b/Sledgemapper.Api/Handlers/DeleteTileCommandHandler.cs @@ -1,39 +1,25 @@ using MediatR; using Sledgemapper.Api.Commands; using Sledgemapper.Api.Notifications; -using Sledgemapper.Api.Data; -using Sledgemapper.Shared.Entities; -using System.Linq; +using Sledgemapper.Api.Infrastructure.Data; using System.Text.Json; using System.Threading; using System.Threading.Tasks; namespace Sledgemapper.Api.Handlers { - public class DeleteTileCommandHandler : IRequestHandler + public class DeleteTileCommandHandler : BaseCommandHandler { - private readonly MyDbContext _dbcontext; - - private readonly IMediator _mediator; - - public DeleteTileCommandHandler(IMediator mediator, MyDbContext dbcontext) { _dbcontext = dbcontext; _mediator = mediator; } - - public async Task Handle(DeleteTileCommand notification, CancellationToken cancellationToken) + public DeleteTileCommandHandler(IMediator mediator, SledgemapperDbContext dbcontext) : base(mediator, dbcontext) { - var jsonString = JsonSerializer.Serialize(notification.Tile); - var session = _dbcontext.Sessions.First(m=>m.SessionName== notification.SessionName); + } - _dbcontext.MapLogs.Add(new Sledgemapper.Api.Models.MapLog - { - Operation = "D", - SessionId = session.SessionId, - Type = "T", - Timestamp = notification.Timestamp, - Object = jsonString, - UserId = notification.UserId - }); - await _dbcontext.SaveChangesAsync(); - await _mediator.Publish(new DeleteTileNotification(session, notification.Tile, notification.UserId)); + public override async Task Handle(DeleteTileCommand command, CancellationToken cancellationToken) + { + await CheckAuthorization(command); + var jsonString = JsonSerializer.Serialize(command.Tile); + var session = await SaveLog(command, "D", "T", jsonString, cancellationToken); + await Mediator.Publish(new DeleteTileNotification(session, command.Tile, command.UserId), cancellationToken); return true; } } diff --git a/Sledgemapper.Api/Handlers/DeleteWallCommandHandler.cs b/Sledgemapper.Api/Handlers/DeleteWallCommandHandler.cs index 5fdb16a..aeb0f30 100644 --- a/Sledgemapper.Api/Handlers/DeleteWallCommandHandler.cs +++ b/Sledgemapper.Api/Handlers/DeleteWallCommandHandler.cs @@ -1,42 +1,25 @@ using MediatR; -using Sledgemapper.Api.Data; +using Sledgemapper.Api.Infrastructure.Data; using Sledgemapper.Api.Commands; using Sledgemapper.Api.Notifications; -using Sledgemapper.Shared.Entities; -using System.Linq; using System.Text.Json; using System.Threading; using System.Threading.Tasks; namespace Sledgemapper.Api.Handlers { - - public class DeleteWallCommandHandler : IRequestHandler + public class DeleteWallCommandHandler : BaseCommandHandler { - private readonly MyDbContext _dbcontext; - - private readonly IMediator _mediator; - - public DeleteWallCommandHandler(IMediator mediator, MyDbContext dbcontext) { _dbcontext = dbcontext; _mediator = mediator; } - - - public async Task Handle(DeleteWallCommand notification, CancellationToken cancellationToken) + public DeleteWallCommandHandler(IMediator mediator, SledgemapperDbContext dbcontext) : base(mediator, dbcontext) { - var jsonString = JsonSerializer.Serialize(notification.Wall); - var session = _dbcontext.Sessions.First(m => m.SessionName == notification.SessionName); - - _dbcontext.MapLogs.Add(new Sledgemapper.Api.Models.MapLog - { - Operation = "D", - SessionId = session.SessionId, - Type = "W", - Timestamp = notification.Timestamp, - Object = jsonString, - UserId = notification.UserId - }); - await _dbcontext.SaveChangesAsync(); - await _mediator.Publish(new DeleteWallNotification(session, notification.Wall, notification.UserId)); + } + public override async Task Handle(DeleteWallCommand command, CancellationToken cancellationToken) + { + await CheckAuthorization(command); + var jsonString = JsonSerializer.Serialize(command.Wall); + var session = await SaveLog(command, "D", "W", jsonString, cancellationToken); + await Mediator.Publish(new DeleteWallNotification(session, command.Wall, command.UserId), cancellationToken); return true; } } diff --git a/Sledgemapper.Api/Handlers/GetCampaignMapsCommandHandler.cs b/Sledgemapper.Api/Handlers/GetCampaignMapsCommandHandler.cs new file mode 100644 index 0000000..289b8e1 --- /dev/null +++ b/Sledgemapper.Api/Handlers/GetCampaignMapsCommandHandler.cs @@ -0,0 +1,56 @@ +using MediatR; +using Microsoft.EntityFrameworkCore; +using Sledgemapper.Api.Commands; +using Sledgemapper.Api.Infrastructure.Data; +using Sledgemapper.Shared.Entities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace Sledgemapper.Api.Handlers +{ + public class GetCampaignMapsCommandHandler : IRequestHandler> + { + private readonly IMediator _mediator; + private readonly SledgemapperDbContext _dbcontext; + + public GetCampaignMapsCommandHandler(IMediator mediator, SledgemapperDbContext dbcontext) + { + _mediator = mediator; + _dbcontext = dbcontext; + } + + public async Task> Handle(GetCampaignMapsCommand command, CancellationToken cancellationToken) + { + try + { + var user = await _dbcontext.Users.FindAsync(command.UserId); + _dbcontext.Attach(user); + + + + var campaign = await _dbcontext + .Campaigns + .Where(campaign => campaign.CampaignId == command.CampaignId) + .Include(c => c.InvitedUsers) + .Include(c => c.Maps) + .Include(c => c.Owner) + .Where(campaign => campaign.OwnerId == command.UserId || campaign.InvitedUsers.Contains(user)).FirstAsync(); + + + + + //var campaign = await _dbcontext.Campaigns.Where(campaign => campaign.CampaignId == command.CampaignId && campaign.OwnerId == command.UserId).Include(campaign => campaign.Maps).FirstAsync(); + + var maps = campaign.Maps.Select(session => new Session { SessionName = session.SessionName, SessionId = session.SessionId }).ToList(); + return maps; + } + catch (Exception ex) + { + } + return null; + } + } +} \ No newline at end of file diff --git a/Sledgemapper.Api/Handlers/GetCampaignPlayersCommandHandler.cs b/Sledgemapper.Api/Handlers/GetCampaignPlayersCommandHandler.cs new file mode 100644 index 0000000..e915643 --- /dev/null +++ b/Sledgemapper.Api/Handlers/GetCampaignPlayersCommandHandler.cs @@ -0,0 +1,54 @@ +using MediatR; +using Microsoft.EntityFrameworkCore; +using Sledgemapper.Api.Commands; +using Sledgemapper.Api.Infrastructure.Data; +using Sledgemapper.Shared.Entities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace Sledgemapper.Api.Handlers +{ + public class GetCampaignPlayersCommandHandler : IRequestHandler> + { + private readonly IMediator _mediator; + private readonly SledgemapperDbContext _dbcontext; + + public GetCampaignPlayersCommandHandler(IMediator mediator, SledgemapperDbContext dbcontext) + { + _mediator = mediator; + _dbcontext = dbcontext; + } + + public async Task> Handle(GetCampaignPlayersCommand command, CancellationToken cancellationToken) + { + try + { + var user = await _dbcontext.Users.FindAsync(command.UserId); + _dbcontext.Attach(user); + + + var campaign = await _dbcontext + .Campaigns + .Where(campaign => campaign.CampaignId == command.CampaignId) + .Include(c => c.InvitedUsers) + + .Include(c => c.Owner) + .Where(campaign => campaign.OwnerId == command.UserId || campaign.InvitedUsers.Contains(user)).FirstAsync(); + + + + //var campaign = await _dbcontext.Campaigns.Where(campaign => campaign.CampaignId == command.CampaignId && campaign.OwnerId == command.UserId).Include(campaign => campaign.InvitedUsers).FirstAsync(); + + var players = campaign.InvitedUsers.Select(user => new Player { Initials = user.Initials, UserName = user.UserName , UserId = new Guid(user.Id)}).ToList(); + return players; + } + catch (Exception ex) + { + } + return null; + } + } +} \ No newline at end of file diff --git a/Sledgemapper.Api/Handlers/GetCampaignsCommandHandler.cs b/Sledgemapper.Api/Handlers/GetCampaignsCommandHandler.cs new file mode 100644 index 0000000..666f17f --- /dev/null +++ b/Sledgemapper.Api/Handlers/GetCampaignsCommandHandler.cs @@ -0,0 +1,45 @@ +using MediatR; +using Microsoft.EntityFrameworkCore; +using Sledgemapper.Api.Commands; +using Sledgemapper.Api.Infrastructure.Data; +using Sledgemapper.Shared.Entities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace Sledgemapper.Api.Handlers +{ + public class GetCampaignsCommandHandler : IRequestHandler> + { + private readonly IMediator _mediator; + private readonly SledgemapperDbContext _dbcontext; + + public GetCampaignsCommandHandler(IMediator mediator, SledgemapperDbContext dbcontext) + { + _mediator = mediator; + _dbcontext = dbcontext; + } + + public async Task> Handle(GetCampaignsCommand command, CancellationToken cancellationToken) + { + try + { + var user = await _dbcontext.Users.FindAsync(command.UserId); + _dbcontext.Attach(user); + var campaigns = await _dbcontext.Campaigns + .Include(c => c.InvitedUsers) + .Include(c => c.Owner) + .Where(campaign => campaign.OwnerId == command.UserId || campaign.InvitedUsers.Contains(user)).ToListAsync(); + + return campaigns.Select(c => new Campaign { Id = c.CampaignId, Name = c.CampaignName }).ToList(); + + } + catch (Exception ex) + { + } + return new List(); + } + } +} \ No newline at end of file diff --git a/Sledgemapper.Api/Handlers/GetMapSnapshotCommandHandler.cs b/Sledgemapper.Api/Handlers/GetMapSnapshotCommandHandler.cs index 6b542c1..14ad035 100644 --- a/Sledgemapper.Api/Handlers/GetMapSnapshotCommandHandler.cs +++ b/Sledgemapper.Api/Handlers/GetMapSnapshotCommandHandler.cs @@ -1,36 +1,37 @@ using MediatR; -using Sledgemapper.Api.Data; +using Sledgemapper.Api.Infrastructure.Data; using Sledgemapper.Shared.Entities; using System.Text.Json; using System.Threading; using System.Threading.Tasks; using System.Linq; -using Sledgemapper.Api.Models; +using Sledgemapper.Api.Commands; +using Sledgemapper.Api.Core.Entities; +using Session = Sledgemapper.Shared.Entities.Session; -namespace Sledgemapper.Api.Commands +namespace Sledgemapper.Api.Handlers { - public class GetMapSnapshotCommandHandler : IRequestHandler + public class GetMapSnapshotCommandHandler : IRequestHandler { - private readonly MyDbContext _dbcontext; + private readonly SledgemapperDbContext _dbcontext; - public GetMapSnapshotCommandHandler(MyDbContext dbcontext) { _dbcontext = dbcontext; } + public GetMapSnapshotCommandHandler(SledgemapperDbContext dbcontext) { _dbcontext = dbcontext; } - public async Task Handle(GetMapSnapshotCommand notification, CancellationToken cancellationToken) + public async Task Handle(GetMapSnapshotCommand notification, CancellationToken cancellationToken) { - Snapshot snapshot; double timestamp; - Sledgemapper.Shared.Entities.Session mapSession; - var session = _dbcontext.Sessions.First(m => m.SessionName == notification.SessionName); - snapshot = _dbcontext.Snapshots.OrderByDescending(s => s.Timestamp).FirstOrDefault(m => m.SessionId == session.SessionId); + Session mapSession; + var session = _dbcontext.Sessions.First(m => m.SessionId == notification.MapId); + var snapshot = _dbcontext.Snapshots.OrderByDescending(s => s.Timestamp).FirstOrDefault(m => m.SessionId == session.SessionId); if (snapshot is null) { timestamp = 0; - mapSession = new Shared.Entities.Session(); + mapSession = new Session(); } else { - mapSession = JsonSerializer.Deserialize(snapshot.Object); + mapSession = JsonSerializer.Deserialize(snapshot.Object); timestamp = snapshot.Timestamp; } @@ -57,7 +58,7 @@ namespace Sledgemapper.Api.Commands var note = JsonSerializer.Deserialize(mapUpdate.Object); mapSession.NewNote(note); break; - case "L": + case "L": var line = JsonSerializer.Deserialize(mapUpdate.Object); mapSession.NewLine(line); break; @@ -65,10 +66,6 @@ namespace Sledgemapper.Api.Commands var room = JsonSerializer.Deserialize(mapUpdate.Object); mapSession.NewRoom(room); break; - - - - } } @@ -101,10 +98,10 @@ namespace Sledgemapper.Api.Commands { SessionId = session.SessionId, Timestamp = mapUpdates.Max(mapSession => mapSession.Timestamp), - Object = JsonSerializer.Serialize(mapSession) + Object = JsonSerializer.Serialize(mapSession) }; - await _dbcontext.Snapshots.AddAsync(newSnapshot); - await _dbcontext.SaveChangesAsync(); + await _dbcontext.Snapshots.AddAsync(newSnapshot, cancellationToken); + await _dbcontext.SaveChangesAsync(cancellationToken); } return mapSession; } diff --git a/Sledgemapper.Api/Handlers/InvitePlayerToCampaignCommandHandler.cs b/Sledgemapper.Api/Handlers/InvitePlayerToCampaignCommandHandler.cs new file mode 100644 index 0000000..aefdac0 --- /dev/null +++ b/Sledgemapper.Api/Handlers/InvitePlayerToCampaignCommandHandler.cs @@ -0,0 +1,54 @@ +using System; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using MediatR; +using Microsoft.EntityFrameworkCore; +using Sledgemapper.Api.Commands; +using Sledgemapper.Api.Infrastructure.Data; + +namespace Sledgemapper.Api.Handlers +{ + public class InvitePlayerToCampaignCommandHandler : IRequestHandler + { + private readonly SledgemapperDbContext _dbContext; + private readonly IMediator _mediator; + + public InvitePlayerToCampaignCommandHandler(IMediator mediator, SledgemapperDbContext dbContext) + { + _mediator = mediator; + _dbContext = dbContext; + } + + public async Task Handle(InvitePlayerToCampaignCommand command, CancellationToken cancellationToken) + { + try + { + var user = await _dbContext.Users.FindAsync(command.UserId); + + var campaign = await _dbContext + .Campaigns + .Where(campaign => campaign.CampaignId == command.CampaignId) + .Include(c => c.InvitedUsers) + .Where(campaign => campaign.OwnerId == command.UserId || campaign.InvitedUsers.Contains(user)) + .FirstAsync(cancellationToken); + + + var invitedUser = + await _dbContext.Users.FirstOrDefaultAsync(iUser => iUser.Email == command.Email, + cancellationToken); + _dbContext.Attach(invitedUser); + _dbContext.Attach(campaign); + campaign.InvitedUsers.Add(invitedUser); + + await _dbContext.SaveChangesAsync(cancellationToken); + return true; + } + catch (Exception ex) + { + } + + return false; + } + } +} \ No newline at end of file diff --git a/Sledgemapper.Api/Handlers/NewCampaignCommandHandler.cs b/Sledgemapper.Api/Handlers/NewCampaignCommandHandler.cs new file mode 100644 index 0000000..f6b505e --- /dev/null +++ b/Sledgemapper.Api/Handlers/NewCampaignCommandHandler.cs @@ -0,0 +1,48 @@ +using MediatR; +using Sledgemapper.Api.Commands; +using Sledgemapper.Api.Infrastructure.Data; +using System; +using System.Threading; +using System.Threading.Tasks; +using Sledgemapper.Api.Core.Entities; + +namespace Sledgemapper.Api.Handlers +{ + public class NewCampaignCommandHandler : IRequestHandler + { + private readonly IMediator _mediator; + private readonly SledgemapperDbContext _dbcontext; + + public NewCampaignCommandHandler(IMediator mediator, SledgemapperDbContext dbcontext) + { + _mediator = mediator; + _dbcontext = dbcontext; + } + + public async Task Handle(NewCampaignCommand notification, CancellationToken cancellationToken) + { + try + { + var user = await _dbcontext.Users.FindAsync(new object[] { notification.UserId }, cancellationToken); + _dbcontext.Attach(user); + var campaign = new Core.Entities.Campaign + { + CampaignName = notification.CampaignName, + OwnerId = user.Id, + InvitedUsers = new System.Collections.Generic.List { user } + }; + + _dbcontext.Campaigns.Add(campaign); + + await _dbcontext.SaveChangesAsync(cancellationToken); + return true; + } + catch (Exception ex) + { + + + } + return false; + } + } +} \ No newline at end of file diff --git a/Sledgemapper.Api/Handlers/NewLineCommandHandler.cs b/Sledgemapper.Api/Handlers/NewLineCommandHandler.cs index 4901dae..c499145 100644 --- a/Sledgemapper.Api/Handlers/NewLineCommandHandler.cs +++ b/Sledgemapper.Api/Handlers/NewLineCommandHandler.cs @@ -1,8 +1,6 @@ using MediatR; -using Sledgemapper.Api.Data; -using Sledgemapper.Shared.Entities; +using Sledgemapper.Api.Infrastructure.Data; using Sledgemapper.Api.Commands; -using System.Linq; using System.Text.Json; using System.Threading; using System.Threading.Tasks; @@ -10,29 +8,18 @@ using Sledgemapper.Api.Notifications; namespace Sledgemapper.Api.Handlers { - public class NewLineCommandHandler : IRequestHandler + public class NewLineCommandHandler : BaseCommandHandler { - private readonly MyDbContext _dbcontext; - - private readonly IMediator _mediator; - - public NewLineCommandHandler(IMediator mediator, MyDbContext dbcontext) { _dbcontext = dbcontext; _mediator = mediator; } - - public async Task Handle(NewLineCommand notification, CancellationToken cancellationToken) + public NewLineCommandHandler(IMediator mediator, SledgemapperDbContext dbContext) : base(mediator, dbContext) { - var jsonString = JsonSerializer.Serialize(notification.Line); - var session = _dbcontext.Sessions.First(m => m.SessionName == notification.SessionName); - _dbcontext.MapLogs.Add(new Sledgemapper.Api.Models.MapLog - { - Operation = "N", - SessionId = session.SessionId, - Type = "L", - Timestamp = notification.Timestamp, - Object = jsonString, - UserId = notification.UserId, - }); - await _dbcontext.SaveChangesAsync(); - await _mediator.Publish(new NewLineNotification(session, notification.Line, notification.UserId)); + } + + public override async Task Handle(NewLineCommand command, CancellationToken cancellationToken) + { + await CheckAuthorization(command); + var jsonString = JsonSerializer.Serialize(command.Line); + var session = await SaveLog(command, "N", "L", jsonString, cancellationToken); + await Mediator.Publish(new NewLineNotification(session, command.Line, command.UserId), cancellationToken); return true; } } diff --git a/Sledgemapper.Api/Handlers/NewNoteCommandHandler.cs b/Sledgemapper.Api/Handlers/NewNoteCommandHandler.cs index 5a50e45..8be5287 100644 --- a/Sledgemapper.Api/Handlers/NewNoteCommandHandler.cs +++ b/Sledgemapper.Api/Handlers/NewNoteCommandHandler.cs @@ -1,38 +1,25 @@ using MediatR; -using Sledgemapper.Api.Data; -using Sledgemapper.Shared.Entities; +using Sledgemapper.Api.Infrastructure.Data; using Sledgemapper.Api.Commands; using Sledgemapper.Api.Notifications; -using System.Linq; using System.Text.Json; using System.Threading; using System.Threading.Tasks; namespace Sledgemapper.Api.Handlers { - public class NewNoteCommandHandler : IRequestHandler + public class NewNoteCommandHandler : BaseCommandHandler { - private readonly MyDbContext _dbcontext; - - private readonly IMediator _mediator; - - public NewNoteCommandHandler(IMediator mediator, MyDbContext dbcontext) { _dbcontext = dbcontext; _mediator = mediator; } - - public async Task Handle(NewNoteCommand notification, CancellationToken cancellationToken) + public NewNoteCommandHandler(IMediator mediator, SledgemapperDbContext dbcontext) : base(mediator, dbcontext) { - var jsonString = JsonSerializer.Serialize(notification.Note); - var session = _dbcontext.Sessions.First(m => m.SessionName == notification.SessionName); - _dbcontext.MapLogs.Add(new Sledgemapper.Api.Models.MapLog - { - Operation = "N", - SessionId = session.SessionId, - Type = "N", - Timestamp = notification.Timestamp, - Object = jsonString, - UserId = notification.UserId, - }); - await _dbcontext.SaveChangesAsync(); - await _mediator.Publish(new NewNoteNotification(session, notification.Note, notification.UserId)); + } + + public override async Task Handle(NewNoteCommand command, CancellationToken cancellationToken) + { + await CheckAuthorization(command); + var jsonString = JsonSerializer.Serialize(command.Note); + var session = await SaveLog(command, "N", "N", jsonString, cancellationToken); + await Mediator.Publish(new NewNoteNotification(session, command.Note, command.UserId), cancellationToken); return true; } } diff --git a/Sledgemapper.Api/Handlers/NewOverlayCommandHandler.cs b/Sledgemapper.Api/Handlers/NewOverlayCommandHandler.cs index 817a37f..68a6793 100644 --- a/Sledgemapper.Api/Handlers/NewOverlayCommandHandler.cs +++ b/Sledgemapper.Api/Handlers/NewOverlayCommandHandler.cs @@ -1,38 +1,26 @@ using MediatR; using Sledgemapper.Api.Commands; +using Sledgemapper.Api.Infrastructure.Data; using Sledgemapper.Api.Notifications; -using Sledgemapper.Api.Data; -using Sledgemapper.Shared.Entities; -using System.Linq; using System.Text.Json; using System.Threading; using System.Threading.Tasks; namespace Sledgemapper.Api.Handlers { - public class NewOverlayCommandHandler : IRequestHandler + + public class NewOverlayCommandHandler : BaseCommandHandler { - private readonly MyDbContext _dbcontext; - - private readonly IMediator _mediator; - - public NewOverlayCommandHandler(IMediator mediator, MyDbContext dbcontext) { _dbcontext = dbcontext; _mediator = mediator; } - - public async Task Handle(NewOverlayCommand notification, CancellationToken cancellationToken) + public NewOverlayCommandHandler(IMediator mediator, SledgemapperDbContext dbcontext) : base(mediator, dbcontext) { - var jsonString = JsonSerializer.Serialize(notification.Overlay); - var session = _dbcontext.Sessions.First(m => m.SessionName == notification.SessionName); - _dbcontext.MapLogs.Add(new Sledgemapper.Api.Models.MapLog - { - Operation = "N", - SessionId = session.SessionId, - Type = "O", - Timestamp = notification.Timestamp, - Object = jsonString, - UserId = notification.UserId, - }); - await _dbcontext.SaveChangesAsync(); - await _mediator.Publish(new NewOverlayNotification(session, notification.Overlay, notification.UserId)); + } + + public override async Task Handle(NewOverlayCommand command, CancellationToken cancellationToken) + { + await CheckAuthorization(command); + var jsonString = JsonSerializer.Serialize(command.Overlay); + var session = await SaveLog(command, "N", "O", jsonString, cancellationToken); + await Mediator.Publish(new NewOverlayNotification(session, command.Overlay, command.UserId), cancellationToken); return true; } } diff --git a/Sledgemapper.Api/Handlers/NewRoomCommandHandler.cs b/Sledgemapper.Api/Handlers/NewRoomCommandHandler.cs index 73561a1..f5093ba 100644 --- a/Sledgemapper.Api/Handlers/NewRoomCommandHandler.cs +++ b/Sledgemapper.Api/Handlers/NewRoomCommandHandler.cs @@ -1,8 +1,6 @@ using MediatR; -using Sledgemapper.Api.Data; -using Sledgemapper.Shared.Entities; +using Sledgemapper.Api.Infrastructure.Data; using Sledgemapper.Api.Commands; -using System.Linq; using System.Text.Json; using System.Threading; using System.Threading.Tasks; @@ -10,29 +8,17 @@ using Sledgemapper.Api.Notifications; namespace Sledgemapper.Api.Handlers { - public class NewRoomCommandHandler : IRequestHandler + public class NewRoomCommandHandler : BaseCommandHandler { - private readonly MyDbContext _dbcontext; + public NewRoomCommandHandler(IMediator mediator, SledgemapperDbContext dbcontext) : base(mediator, dbcontext) + { } - private readonly IMediator _mediator; - - public NewRoomCommandHandler(IMediator mediator, MyDbContext dbcontext) { _dbcontext = dbcontext; _mediator = mediator; } - - public async Task Handle(NewRoomCommand notification, CancellationToken cancellationToken) + public override async Task Handle(NewRoomCommand command, CancellationToken cancellationToken) { - var jsonString = JsonSerializer.Serialize(notification.Room); - var session = _dbcontext.Sessions.First(m => m.SessionName == notification.SessionName); - _dbcontext.MapLogs.Add(new Sledgemapper.Api.Models.MapLog - { - Operation = "N", - SessionId = session.SessionId, - Type = "R", - Timestamp = notification.Timestamp, - Object = jsonString, - UserId = notification.UserId, - }); - await _dbcontext.SaveChangesAsync(); - await _mediator.Publish(new NewRoomNotification(session, notification.Room, notification.UserId)); + await CheckAuthorization(command); + var jsonString = JsonSerializer.Serialize(command.Room); + var session = await SaveLog(command, "N", "R", jsonString, cancellationToken); + await Mediator.Publish(new NewRoomNotification(session, command.Room, command.UserId), cancellationToken); return true; } } diff --git a/Sledgemapper.Api/Handlers/NewSnapshotCommandHandler.cs b/Sledgemapper.Api/Handlers/NewSnapshotCommandHandler.cs index e6d88e0..941fbb6 100644 --- a/Sledgemapper.Api/Handlers/NewSnapshotCommandHandler.cs +++ b/Sledgemapper.Api/Handlers/NewSnapshotCommandHandler.cs @@ -1,34 +1,37 @@ using MediatR; -using Sledgemapper.Api.Data; +using Sledgemapper.Api.Infrastructure.Data; using System.Text.Json; using System.Threading; using System.Threading.Tasks; using System.Linq; +using Sledgemapper.Api.Commands; +using Sledgemapper.Api.Core.Entities; -namespace Sledgemapper.Api.Commands +namespace Sledgemapper.Api.Handlers { public class NewSnapshotCommandHandler : IRequestHandler { - private readonly MyDbContext _dbcontext; + private readonly SledgemapperDbContext _dbcontext; private readonly IMediator _mediator; - public NewSnapshotCommandHandler(IMediator mediator, MyDbContext dbcontext) { _dbcontext = dbcontext; _mediator = mediator; } + public NewSnapshotCommandHandler(IMediator mediator, SledgemapperDbContext dbcontext) { _dbcontext = dbcontext; _mediator = mediator; } public async Task Handle(NewSnapshotCommand notification, CancellationToken cancellationToken) { - + var session = _dbcontext.Sessions.First(m => m.SessionName == notification.SessionName); - var newSnapshot = new Sledgemapper.Api.Models.Snapshot{ - SessionId=session.SessionId, - Timestamp=notification.Timestamp, - Object = JsonSerializer.Serialize(notification.Session) + var newSnapshot = new Snapshot + { + SessionId = session.SessionId, + Timestamp = notification.Timestamp, + Object = JsonSerializer.Serialize(notification.Session) + + }; + await _dbcontext.Snapshots.AddAsync(newSnapshot, cancellationToken); + await _dbcontext.SaveChangesAsync(cancellationToken); -}; -await _dbcontext.Snapshots.AddAsync(newSnapshot); - await _dbcontext.SaveChangesAsync(); - return true; } diff --git a/Sledgemapper.Api/Handlers/NewTileCommandHandler.cs b/Sledgemapper.Api/Handlers/NewTileCommandHandler.cs index 6b0a55c..5db3d32 100644 --- a/Sledgemapper.Api/Handlers/NewTileCommandHandler.cs +++ b/Sledgemapper.Api/Handlers/NewTileCommandHandler.cs @@ -1,38 +1,25 @@ using MediatR; -using Sledgemapper.Api.Data; - +using Sledgemapper.Api.Infrastructure.Data; using System.Text.Json; using System.Threading; using System.Threading.Tasks; using Sledgemapper.Api.Notifications; -using System.Linq; -using Sledgemapper.Shared.Entities; +using Sledgemapper.Api.Commands; -namespace Sledgemapper.Api.Commands +namespace Sledgemapper.Api.Handlers { - public class NewTileCommandHandler : IRequestHandler + public class NewTileCommandHandler : BaseCommandHandler { - private readonly MyDbContext _dbcontext; - private readonly IMediator _mediator; - - public NewTileCommandHandler(IMediator mediator, MyDbContext dbcontext) { _dbcontext = dbcontext; _mediator = mediator; } - - public async Task Handle(NewTileCommand notification, CancellationToken cancellationToken) + public NewTileCommandHandler(IMediator mediator, SledgemapperDbContext dbContext) : base(mediator, dbContext) { - var jsonString = JsonSerializer.Serialize(notification.Tile); - var session = _dbcontext.Sessions.First(m => m.SessionName == notification.SessionName); + } - _dbcontext.MapLogs.Add(new Sledgemapper.Api.Models.MapLog - { - Operation = "N", - SessionId = session.SessionId, - Type = "T", - Timestamp = notification.Timestamp, - Object = jsonString, - UserId = notification.UserId - }); - await _dbcontext.SaveChangesAsync(); - await _mediator.Publish(new NewTileNotification(session, notification.Tile, notification.UserId)); + public override async Task Handle(NewTileCommand command, CancellationToken cancellationToken) + { + await CheckAuthorization(command); + var jsonString = JsonSerializer.Serialize(command.Tile); + var session = await SaveLog(command, "N", "T", jsonString, cancellationToken); + await Mediator.Publish(new NewTileNotification(session, command.Tile, command.UserId), cancellationToken); return true; } } diff --git a/Sledgemapper.Api/Handlers/NewWallCommandHandler.cs b/Sledgemapper.Api/Handlers/NewWallCommandHandler.cs index af69b69..c2c480d 100644 --- a/Sledgemapper.Api/Handlers/NewWallCommandHandler.cs +++ b/Sledgemapper.Api/Handlers/NewWallCommandHandler.cs @@ -1,38 +1,25 @@ using MediatR; -using Sledgemapper.Api.Data; -using Sledgemapper.Shared.Entities; +using Sledgemapper.Api.Infrastructure.Data; using Sledgemapper.Api.Commands; using Sledgemapper.Api.Notifications; -using System.Linq; using System.Text.Json; using System.Threading; using System.Threading.Tasks; namespace Sledgemapper.Api.Handlers { - public class NewWallCommandHandler : IRequestHandler + public class NewWallCommandHandler : BaseCommandHandler { - private readonly MyDbContext _dbcontext; - - private readonly IMediator _mediator; - - public NewWallCommandHandler(IMediator mediator, MyDbContext dbcontext) { _dbcontext = dbcontext; _mediator = mediator; } - - public async Task Handle(NewWallCommand notification, CancellationToken cancellationToken) + public NewWallCommandHandler(IMediator mediator, SledgemapperDbContext dbContext) : base(mediator, dbContext) { - var jsonString = JsonSerializer.Serialize(notification.Wall); - var session = _dbcontext.Sessions.First(m => m.SessionName == notification.SessionName); - _dbcontext.MapLogs.Add(new Sledgemapper.Api.Models.MapLog - { - Operation = "N", - SessionId = session.SessionId, - Type = "W", - Timestamp = notification.Timestamp, - Object = jsonString, - UserId = notification.UserId, - }); - await _dbcontext.SaveChangesAsync(); - await _mediator.Publish(new NewWallNotification(session, notification.Wall, notification.UserId)); + } + + public override async Task Handle(NewWallCommand command, CancellationToken cancellationToken) + { + await CheckAuthorization(command); + var jsonString = JsonSerializer.Serialize(command.Wall); + var session = await SaveLog(command, "N", "W", jsonString, cancellationToken); + await Mediator.Publish(new NewWallNotification(session, command.Wall, command.UserId), cancellationToken); return true; } } diff --git a/Sledgemapper.Api/Handlers/PingCommandHandler.cs b/Sledgemapper.Api/Handlers/PingCommandHandler.cs deleted file mode 100644 index efc9325..0000000 --- a/Sledgemapper.Api/Handlers/PingCommandHandler.cs +++ /dev/null @@ -1,28 +0,0 @@ -// using MediatR; -// using Sledgemapper.Api.Data; -// using System.Threading; -// using System.Threading.Tasks; -// using Sledgemapper.Api.Notifications; -// using System.Linq; - -// namespace Sledgemapper.Api.Commands -// { -// public class PingCommandHandler : IRequestHandler -// { -// private readonly MyDbContext _dbcontext; -// private readonly IMediator _mediator; - -// public PingCommandHandler(IMediator mediator, MyDbContext dbcontext) { _dbcontext = dbcontext; _mediator = mediator; } - -// public async Task Handle(PingCommand notification, CancellationToken cancellationToken) -// { -// var session = _dbcontext.Sessions.First(m => m.SessionName == notification.SessionName); - - -// await _mediator.Publish(new PingNotification(session, notification.Location, notification.UserId)); -// return true; -// } - - -// } -// } diff --git a/Sledgemapper.Api/Handlers/SendDeleteNoteMessage.cs b/Sledgemapper.Api/Handlers/SendDeleteNoteMessage.cs index 1f6a112..1c66299 100644 --- a/Sledgemapper.Api/Handlers/SendDeleteNoteMessage.cs +++ b/Sledgemapper.Api/Handlers/SendDeleteNoteMessage.cs @@ -1,6 +1,6 @@ using MediatR; using Microsoft.AspNetCore.SignalR; -using Sledgemapper.Clients; +using Sledgemapper.Shared.Clients; using System.Threading; using System.Threading.Tasks; using Sledgemapper.Api.Hubs; @@ -16,7 +16,7 @@ namespace Sledgemapper.Api.Handlers public async Task Handle(DeleteNoteNotification notification, CancellationToken cancellationToken) { - await _hub.Clients.Groups(notification.Session.SessionName).DeleteNote(notification.Note); + await _hub.Clients.Groups(notification.Session.SessionId.ToString()).DeleteNote(notification.Note); } } } diff --git a/Sledgemapper.Api/Handlers/SendDeleteOverlayMessage.cs b/Sledgemapper.Api/Handlers/SendDeleteOverlayMessage.cs index cb0b922..35b07aa 100644 --- a/Sledgemapper.Api/Handlers/SendDeleteOverlayMessage.cs +++ b/Sledgemapper.Api/Handlers/SendDeleteOverlayMessage.cs @@ -2,9 +2,9 @@ using MediatR; using Microsoft.AspNetCore.SignalR; using Sledgemapper.Api.Hubs; using Sledgemapper.Api.Notifications; -using Sledgemapper.Clients; using System.Threading; using System.Threading.Tasks; +using Sledgemapper.Shared.Clients; namespace Sledgemapper.Api.Handlers { @@ -16,7 +16,7 @@ namespace Sledgemapper.Api.Handlers public async Task Handle(DeleteOverlayNotification notification, CancellationToken cancellationToken) { - await _hub.Clients.Groups(notification.Session.SessionName).DeleteOverlay(notification.Overlay); + await _hub.Clients.Groups(notification.Session.SessionId.ToString()).DeleteOverlay(notification.Overlay); } } } diff --git a/Sledgemapper.Api/Handlers/SendDeleteTileMessage.cs b/Sledgemapper.Api/Handlers/SendDeleteTileMessage.cs index 75c0c03..78f07ee 100644 --- a/Sledgemapper.Api/Handlers/SendDeleteTileMessage.cs +++ b/Sledgemapper.Api/Handlers/SendDeleteTileMessage.cs @@ -2,9 +2,9 @@ using MediatR; using Microsoft.AspNetCore.SignalR; using Sledgemapper.Api.Hubs; using Sledgemapper.Api.Notifications; -using Sledgemapper.Clients; using System.Threading; using System.Threading.Tasks; +using Sledgemapper.Shared.Clients; namespace Sledgemapper.Api.Handlers { @@ -16,7 +16,7 @@ namespace Sledgemapper.Api.Handlers public async Task Handle(DeleteTileNotification notification, CancellationToken cancellationToken) { - await _hub.Clients.Groups(notification.Session.SessionName).DeleteTile(notification.Tile); + await _hub.Clients.Groups(notification.Session.SessionId.ToString()).DeleteTile(notification.Tile); } } } diff --git a/Sledgemapper.Api/Handlers/SendDeleteWallMessage.cs b/Sledgemapper.Api/Handlers/SendDeleteWallMessage.cs index e853012..99f4e2a 100644 --- a/Sledgemapper.Api/Handlers/SendDeleteWallMessage.cs +++ b/Sledgemapper.Api/Handlers/SendDeleteWallMessage.cs @@ -1,10 +1,10 @@ using MediatR; using Microsoft.AspNetCore.SignalR; using Sledgemapper.Api.Notifications; -using Sledgemapper.Clients; using System.Threading; using System.Threading.Tasks; using Sledgemapper.Api.Hubs; +using Sledgemapper.Shared.Clients; namespace Sledgemapper.Api.Handlers { @@ -16,7 +16,7 @@ namespace Sledgemapper.Api.Handlers public async Task Handle(DeleteWallNotification notification, CancellationToken cancellationToken) { - await _hub.Clients.Groups(notification.Session.SessionName).DeleteWall(notification.Wall); + await _hub.Clients.Groups(notification.Session.SessionId.ToString()).DeleteWall(notification.Wall); } } } diff --git a/Sledgemapper.Api/Handlers/SendNewLineMessage.cs b/Sledgemapper.Api/Handlers/SendNewLineMessage.cs index e0e9c86..1447351 100644 --- a/Sledgemapper.Api/Handlers/SendNewLineMessage.cs +++ b/Sledgemapper.Api/Handlers/SendNewLineMessage.cs @@ -1,10 +1,10 @@ using MediatR; using Microsoft.AspNetCore.SignalR; using Sledgemapper.Api.Notifications; -using Sledgemapper.Clients; using System.Threading; using System.Threading.Tasks; using Sledgemapper.Api.Hubs; +using Sledgemapper.Shared.Clients; namespace Sledgemapper.Api.Handlers { @@ -16,7 +16,7 @@ namespace Sledgemapper.Api.Handlers public async Task Handle(NewLineNotification notification, CancellationToken cancellationToken) { - await _hub.Clients.Groups(notification.Session.SessionName).NewLine(notification.Line); + await _hub.Clients.Groups(notification.Session.SessionId.ToString()).NewLine(notification.Line); } } } diff --git a/Sledgemapper.Api/Handlers/SendNewNoteMessage.cs b/Sledgemapper.Api/Handlers/SendNewNoteMessage.cs index 37e9f5a..88eafe6 100644 --- a/Sledgemapper.Api/Handlers/SendNewNoteMessage.cs +++ b/Sledgemapper.Api/Handlers/SendNewNoteMessage.cs @@ -1,10 +1,10 @@ using MediatR; using Microsoft.AspNetCore.SignalR; using Sledgemapper.Api.Notifications; -using Sledgemapper.Clients; using System.Threading; using System.Threading.Tasks; using Sledgemapper.Api.Hubs; +using Sledgemapper.Shared.Clients; namespace Sledgemapper.Api.Handlers { @@ -16,7 +16,7 @@ namespace Sledgemapper.Api.Handlers public async Task Handle(NewNoteNotification notification, CancellationToken cancellationToken) { - await _hub.Clients.Groups(notification.Session.SessionName).NewNote(notification.Note); + await _hub.Clients.Groups(notification.Session.SessionId.ToString()).NewNote(notification.Note); } } } diff --git a/Sledgemapper.Api/Handlers/SendNewOverlayMessage.cs b/Sledgemapper.Api/Handlers/SendNewOverlayMessage.cs index 6cfe0ef..782742e 100644 --- a/Sledgemapper.Api/Handlers/SendNewOverlayMessage.cs +++ b/Sledgemapper.Api/Handlers/SendNewOverlayMessage.cs @@ -2,9 +2,9 @@ using MediatR; using Microsoft.AspNetCore.SignalR; using Sledgemapper.Api.Hubs; using Sledgemapper.Api.Notifications; -using Sledgemapper.Clients; using System.Threading; using System.Threading.Tasks; +using Sledgemapper.Shared.Clients; namespace Sledgemapper.Api.Handlers { @@ -16,7 +16,7 @@ namespace Sledgemapper.Api.Handlers public async Task Handle(NewOverlayNotification notification, CancellationToken cancellationToken) { - await _hub.Clients.Groups(notification.Session.SessionName).NewOverlay(notification.Overlay); + await _hub.Clients.Groups(notification.Session.SessionId.ToString()).NewOverlay(notification.Overlay); } } } diff --git a/Sledgemapper.Api/Handlers/SendNewRoomMessage.cs b/Sledgemapper.Api/Handlers/SendNewRoomMessage.cs index adbf4ec..e8dcd7e 100644 --- a/Sledgemapper.Api/Handlers/SendNewRoomMessage.cs +++ b/Sledgemapper.Api/Handlers/SendNewRoomMessage.cs @@ -1,10 +1,10 @@ using MediatR; using Microsoft.AspNetCore.SignalR; using Sledgemapper.Api.Notifications; -using Sledgemapper.Clients; using System.Threading; using System.Threading.Tasks; using Sledgemapper.Api.Hubs; +using Sledgemapper.Shared.Clients; namespace Sledgemapper.Api.Handlers { @@ -16,7 +16,7 @@ namespace Sledgemapper.Api.Handlers public async Task Handle(NewRoomNotification notification, CancellationToken cancellationToken) { - await _hub.Clients.Groups(notification.Session.SessionName).NewRoom(notification.Room); + await _hub.Clients.Groups(notification.Session.SessionId.ToString()).NewRoom(notification.Room); } } } diff --git a/Sledgemapper.Api/Handlers/SendNewTileMessage.cs b/Sledgemapper.Api/Handlers/SendNewTileMessage.cs index 7fa2541..268bc99 100644 --- a/Sledgemapper.Api/Handlers/SendNewTileMessage.cs +++ b/Sledgemapper.Api/Handlers/SendNewTileMessage.cs @@ -1,10 +1,10 @@ using MediatR; using Microsoft.AspNetCore.SignalR; using Sledgemapper.Api.Notifications; -using Sledgemapper.Clients; using System.Threading; using System.Threading.Tasks; using Sledgemapper.Api.Hubs; +using Sledgemapper.Shared.Clients; namespace Sledgemapper.Api.Handlers { @@ -17,7 +17,7 @@ namespace Sledgemapper.Api.Handlers public async Task Handle(NewTileNotification notification, CancellationToken cancellationToken) { - await _hub.Clients.Groups(notification.Session.SessionName).NewTile(notification.Tile); + await _hub.Clients.Groups(notification.Session.SessionId.ToString()).NewTile(notification.Tile); } } } diff --git a/Sledgemapper.Api/Handlers/SendNewWallMessage.cs b/Sledgemapper.Api/Handlers/SendNewWallMessage.cs index 34d5567..0ed117a 100644 --- a/Sledgemapper.Api/Handlers/SendNewWallMessage.cs +++ b/Sledgemapper.Api/Handlers/SendNewWallMessage.cs @@ -1,10 +1,10 @@ using MediatR; using Microsoft.AspNetCore.SignalR; using Sledgemapper.Api.Notifications; -using Sledgemapper.Clients; using System.Threading; using System.Threading.Tasks; using Sledgemapper.Api.Hubs; +using Sledgemapper.Shared.Clients; namespace Sledgemapper.Api.Handlers { @@ -16,7 +16,7 @@ namespace Sledgemapper.Api.Handlers public async Task Handle(NewWallNotification notification, CancellationToken cancellationToken) { - await _hub.Clients.Groups(notification.Session.SessionName).NewWall(notification.Wall); + await _hub.Clients.Groups(notification.Session.SessionId.ToString()).NewWall(notification.Wall); } } } diff --git a/Sledgemapper.Api/Handlers/SendPingMessage.cs b/Sledgemapper.Api/Handlers/SendPingMessage.cs deleted file mode 100644 index 9b7f0d9..0000000 --- a/Sledgemapper.Api/Handlers/SendPingMessage.cs +++ /dev/null @@ -1,23 +0,0 @@ -// using MediatR; -// using Microsoft.AspNetCore.SignalR; -// using Sledgemapper.Api.Notifications; -// using Sledgemapper.Clients; -// using System.Threading; -// using System.Threading.Tasks; -// using Sledgemapper.Api.Hubs; - -// namespace Sledgemapper.Api.Handlers -// { -// public class SendPingMessage : INotificationHandler -// { -// private readonly IHubContext _hub; - -// public SendPingMessage(IHubContext hub) => _hub = hub; - -// public async Task Handle(PingNotification notification, CancellationToken cancellationToken) -// { - -// await _hub.Clients.Groups(notification.Session.SessionName).Ping(notification.Location, notification.UserId); -// } -// } -// } diff --git a/Sledgemapper.Api/Handlers/StartNewSessionHandler.cs b/Sledgemapper.Api/Handlers/StartNewSessionHandler.cs index 211b019..a9d687e 100644 --- a/Sledgemapper.Api/Handlers/StartNewSessionHandler.cs +++ b/Sledgemapper.Api/Handlers/StartNewSessionHandler.cs @@ -1,32 +1,37 @@ using MediatR; using Sledgemapper.Api.Commands; -using Sledgemapper.Api.Data; +using Sledgemapper.Api.Infrastructure.Data; using Sledgemapper.Api.Models; +using System; using System.Threading; using System.Threading.Tasks; +using Sledgemapper.Api.Core.Entities; namespace Sledgemapper.Api.Handlers { - public class StartNewSessionHandler : IRequestHandler + public class StartNewSessionHandler : BaseCommandHandler { - private readonly IMediator _mediator; - private readonly MyDbContext _dbcontext; + - public StartNewSessionHandler(IMediator mediator, MyDbContext dbcontext) + public StartNewSessionHandler(IMediator mediator, SledgemapperDbContext dbcontext):base(mediator, dbcontext) { - _mediator = mediator; - _dbcontext = dbcontext; + } - public async Task Handle(NewSessionCommand notification, CancellationToken cancellationToken) + public override async Task Handle(NewSessionCommand command, CancellationToken cancellationToken) { - _dbcontext.Sessions.Add(new Session + var campaign = await GetCampaignForUser(command); + + var session = new Session { - SessionName = notification.SessionName, - OwnerUserId = notification.UserId - }); - await _dbcontext.SaveChangesAsync(); - return true; + SessionName = command.SessionName, + OwnerUserId = command.UserId, + CampaignId = campaign.CampaignId + + }; + DbContext.Sessions.Add(session); + await DbContext.SaveChangesAsync(cancellationToken); + return session.SessionId; } } } diff --git a/Sledgemapper.Api/Helpers/AppException.cs b/Sledgemapper.Api/Helpers/AppException.cs index c9601e5..957826f 100644 --- a/Sledgemapper.Api/Helpers/AppException.cs +++ b/Sledgemapper.Api/Helpers/AppException.cs @@ -1,17 +1,17 @@ using System; using System.Globalization; -namespace Sledgemapper.Helpers +namespace Sledgemapper.Api.Helpers { // Custom exception class for throwing application specific exceptions (e.g. for validation) // that can be caught and handled within the application public class AppException : Exception { - public AppException() : base() {} + public AppException() : base() { } public AppException(string message) : base(message) { } - public AppException(string message, params object[] args) + public AppException(string message, params object[] args) : base(string.Format(CultureInfo.CurrentCulture, message, args)) { } diff --git a/Sledgemapper.Api/Helpers/AppSettings.cs b/Sledgemapper.Api/Helpers/AppSettings.cs deleted file mode 100644 index bcf36f3..0000000 --- a/Sledgemapper.Api/Helpers/AppSettings.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Sledgemapper.Helpers -{ - public class AppSettings - { - public string Secret { get; set; } - } -} \ No newline at end of file diff --git a/Sledgemapper.Api/Helpers/AutoMapperProfile.cs b/Sledgemapper.Api/Helpers/AutoMapperProfile.cs index fe86397..1fc8edb 100644 --- a/Sledgemapper.Api/Helpers/AutoMapperProfile.cs +++ b/Sledgemapper.Api/Helpers/AutoMapperProfile.cs @@ -1,16 +1,14 @@ using AutoMapper; -using Sledgemapper.Entities; -using Sledgemapper.Models.Users; +using Sledgemapper.Api.Core.Entities; +using Sledgemapper.Api.Models; -namespace Sledgemapper.Helpers +namespace Sledgemapper.Api.Helpers { public class AutoMapperProfile : Profile { public AutoMapperProfile() { - CreateMap(); CreateMap(); - CreateMap(); } } } \ No newline at end of file diff --git a/Sledgemapper.Api/Helpers/DataContext.cs b/Sledgemapper.Api/Helpers/DataContext.cs deleted file mode 100644 index 905b1b2..0000000 --- a/Sledgemapper.Api/Helpers/DataContext.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; -using Sledgemapper.Entities; - -namespace Sledgemapper.Helpers -{ - public class DataContext : DbContext - { - protected readonly IConfiguration Configuration; - - public DataContext(IConfiguration configuration) - { - Configuration = configuration; - } - - protected override void OnConfiguring(DbContextOptionsBuilder options) - { - // connect to sql server database - options.UseSqlServer(Configuration.GetConnectionString("WebApiDatabase")); - } - - public DbSet Users { get; set; } - } -} \ No newline at end of file diff --git a/Sledgemapper.Api/Helpers/SqliteDataContext.cs b/Sledgemapper.Api/Helpers/SqliteDataContext.cs deleted file mode 100644 index 5b799b9..0000000 --- a/Sledgemapper.Api/Helpers/SqliteDataContext.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; - -namespace Sledgemapper.Helpers -{ - public class SqliteDataContext : DataContext - { - public SqliteDataContext(IConfiguration configuration) : base(configuration) { } - - protected override void OnConfiguring(DbContextOptionsBuilder options) - { - // connect to sqlite database - options.UseSqlite(Configuration.GetConnectionString("WebApiDatabase")); - } - } -} \ No newline at end of file diff --git a/Sledgemapper.Api/Hubs/SledgemapperHub.cs b/Sledgemapper.Api/Hubs/SledgemapperHub.cs index 235af86..9484d99 100644 --- a/Sledgemapper.Api/Hubs/SledgemapperHub.cs +++ b/Sledgemapper.Api/Hubs/SledgemapperHub.cs @@ -4,26 +4,24 @@ using System.Linq; using System.Threading.Tasks; using System.Collections.Concurrent; using Sledgemapper.Shared.Entities; -using Sledgemapper.Clients; using System; -using Sledgemapper.Api.Data; +using Sledgemapper.Api.Infrastructure.Data; using Microsoft.AspNetCore.Authorization; +using Sledgemapper.Api.Core.Entities; using Sledgemapper.Api.Models; -using Sledgemapper.Helpers; +using Sledgemapper.Shared.Clients; namespace Sledgemapper.Api.Hubs { [Authorize] public class SledgemapperHub : Hub { - private static readonly ConcurrentDictionary UserColors = new(); - private readonly MyDbContext _dbContext; - private readonly DataContext _datacontext; + private static readonly ConcurrentDictionary UserColors = new(); + private readonly SledgemapperDbContext _dbContext; - public SledgemapperHub(MyDbContext dbContext, DataContext datacontext) + public SledgemapperHub(SledgemapperDbContext dbContext/*, DataContext datacontext*/) { _dbContext = dbContext; - _datacontext = datacontext; } // other colors @@ -61,9 +59,9 @@ namespace Sledgemapper.Api.Hubs await Clients.Group(sessionName).NewWall(tile); } - public async Task NewOverlay(string sessionName, Overlay tile) + public async Task NewOverlay(Guid mapId, Overlay tile) { - await Clients.Group(sessionName).NewOverlay(tile); + await Clients.Group(mapId.ToString()).NewOverlay(tile); } public async Task NewNote(string sessionName, Note note) @@ -88,61 +86,68 @@ namespace Sledgemapper.Api.Hubs public async Task Ping(string sessionName, Tile location) { - var userId = int.Parse(Context.User.Identity.Name); - var user = _datacontext.Users.First(u => u.Id == userId); + var userId = new Guid(Context.User.Claims.FirstOrDefault(m => m.Type == "Id").Value); + + var user = _dbContext.Users.First(u => u.Id == userId.ToString()); var player = new Player { UserId = userId, Initials = user.Initials, Position = new Tile { X = 0, Y = 0 }, Color = UserColors[userId] }; - await Clients.Group(sessionName).Ping(new Ping{X=location.X, Y=location.Y, Player=player}); + await Clients.Group(sessionName).Ping(new Ping { X = location.X, Y = location.Y, Player = player }); } - public async Task JoinSession(string sessionName) + public async Task JoinSession(Guid mapId) { - var session = _dbContext.Sessions.FirstOrDefault(s => s.SessionName == sessionName); - var userId = int.Parse(Context.User.Identity.Name); + var session = _dbContext.Sessions.FirstOrDefault(s => s.SessionId == mapId); + + var userId = new Guid(Context.User.Claims.FirstOrDefault(m => m.Type == "Id").Value); if (session != null) { var userSession = new SessionUser { SessionId = session.SessionId, UserId = userId }; _dbContext.SessionUsers.Add(userSession); await _dbContext.SaveChangesAsync(); - await Groups.AddToGroupAsync(Context.ConnectionId, session.SessionName); - var user = _datacontext.Users.First(u => u.Id == userId); + await Groups.AddToGroupAsync(Context.ConnectionId, session.SessionId.ToString()); + var user = _dbContext.Users.First(u => u.Id == userId.ToString()); var player = new Player { UserId = userId, Initials = user.Initials, Position = new Tile { X = 0, Y = 0 }, Color = UserColors[userId] }; - await Clients.Group(session.SessionName).NewPlayer(player); - await Clients.Group(session.SessionName).RefreshPlayers(); + await Clients.Group(session.SessionId.ToString()).NewPlayer(player); + await Clients.Group(session.SessionId.ToString()).RefreshPlayers(); - var newSession = new Sledgemapper.Shared.Entities.Session - { - SessionName = session.SessionName, - SessionId = session.SessionId - }; - return newSession; + + return true; } else { - return null; + return false; } } - public async Task UpdatePosition(string sessionName, int sessionId, Tile tile) + //public async Task UpdatePosition(string sessionName, int sessionId, Tile tile) + //{ + // //var userId = int.Parse(Context.User.Identity.Name); + // //var SessionUsers = _dbContext.SessionUsers.Where(m => m.SessionId == sessionId).OrderBy(m => m.UserId).ToList(); + // //var user = _dbContext.Users.First(u => u.Id == Context.User.Identity.Name); + // //var player = new Player { UserId = userId, Initials = user.Initials, Position = tile, Color = UserColors[userId] }; + // //await Clients.Group(sessionName).PlayerUpdate(player); + //} + + public async Task UpdatePosition(string sessionName, Guid sessionId, Tile tile) { - var userId = int.Parse(Context.User.Identity.Name); - var SessionUsers = _dbContext.SessionUsers.Where(m => m.SessionId == sessionId).OrderBy(m => m.UserId).ToList(); - var user = _datacontext.Users.First(u => u.Id == userId); + var userId = new Guid(Context.User.Claims.FirstOrDefault(m => m.Type == "Id").Value); + var sessionUsers = _dbContext.SessionUsers.Where(m => m.SessionId == sessionId).OrderBy(m => m.UserId).ToList(); + var user = _dbContext.Users.First(u => u.Id == userId.ToString()); var player = new Player { UserId = userId, Initials = user.Initials, Position = tile, Color = UserColors[userId] }; - await Clients.Group(sessionName).PlayerUpdate(player); + await Clients.Group(sessionId.ToString()).PlayerUpdate(player); } public override async Task OnConnectedAsync() { - var userId = int.Parse(Context.User.Identity.Name); + var userId = new Guid(Context.User.Claims.FirstOrDefault(m => m.Type == "Id").Value); var userConnection = new UserConnection { ConnectionId = Context.ConnectionId, UserId = userId }; _dbContext.UserConnections.Add(userConnection); await _dbContext.SaveChangesAsync(); - var availableColor = Colors.Where(m => !UserColors.Values.Contains(m)).First(); + var availableColor = Colors.First(m => !UserColors.Values.Contains(m)); UserColors.AddOrUpdate(userId, availableColor, (key, oldValue) => availableColor); await base.OnConnectedAsync(); } @@ -150,26 +155,37 @@ namespace Sledgemapper.Api.Hubs public override async Task OnDisconnectedAsync(Exception exception) { var userConnection = _dbContext.UserConnections.FirstOrDefault(m => m.ConnectionId == Context.ConnectionId); - var userId = userConnection.UserId; if (userConnection != null) { + var userId = userConnection.UserId; + _dbContext.UserConnections.Remove(userConnection); - } - var userSessions = _dbContext.SessionUsers.Where(m => m.UserId == userId).ToList(); - { - foreach (var userSession in userSessions) + var userSessions = _dbContext.SessionUsers.Where(m => m.UserId == userId).ToList(); { - var session = _dbContext.Sessions.FirstOrDefault(m => m.SessionId == userSession.SessionId); + foreach (var userSession in userSessions) + { + var session = _dbContext.Sessions.FirstOrDefault(m => m.SessionId == userSession.SessionId); + if (session != null) + { - await Clients.Group(session.SessionName).RemovePlayer(new Player { UserId = userId }); //send remove player - _dbContext.SessionUsers.Remove(userSession); + try + { + await Clients.GroupExcept(session.SessionId.ToString(), new List { Context.ConnectionId }).RemovePlayer(new Player { UserId = userId }); //send remove player + } + catch (Exception e) + { + Console.WriteLine(e); + } + _dbContext.SessionUsers.Remove(userSession); + } + + } } + await _dbContext.SaveChangesAsync(); + + await base.OnDisconnectedAsync(exception); } - await _dbContext.SaveChangesAsync(); - - await base.OnDisconnectedAsync(exception); - } } } \ No newline at end of file diff --git a/Sledgemapper.Api/Infrastructure/Data/SledgemapperDbContext.cs b/Sledgemapper.Api/Infrastructure/Data/SledgemapperDbContext.cs new file mode 100644 index 0000000..195b192 --- /dev/null +++ b/Sledgemapper.Api/Infrastructure/Data/SledgemapperDbContext.cs @@ -0,0 +1,94 @@ +using Microsoft.AspNetCore.Identity.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; +using Sledgemapper.Api.Core.Entities; + +namespace Sledgemapper.Api.Infrastructure.Data +{ + // public static class DbInitializer + // { + // public static void Initialize(SledgemapperDbContext context) + // { + // context.Database.EnsureCreated(); + // } + // } + + public class SledgemapperDbContext : IdentityDbContext + { + public DbSet Campaigns { get; set; } + public DbSet MapLogs { get; set; } + public DbSet Maps { get; set; } + public DbSet Sessions { get; set; } + public DbSet SessionUsers { get; set; } + public DbSet Snapshots { get; set; } + public DbSet Users { get; set; } + public DbSet UserConnections { get; set; } + + public SledgemapperDbContext(DbContextOptions options) : base(options) + { + + } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + // optionsBuilder. + // options.MigrationsAssembly(Assembly.GetExecutingAssembly().FullName); + // optionsBuilder.UseSqlite("Filename=SledgemapperDatabase.db", options => + // { + // options.MigrationsAssembly(Assembly.GetExecutingAssembly().FullName); + // }); + + optionsBuilder.UseSqlite("Filename=db/sledgemapper.db").UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking); + + base.OnConfiguring(optionsBuilder); + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity().HasOne(e => e.Owner); + + modelBuilder.Entity().HasMany(e => e.InvitedUsers).WithMany(e => e.Campaigns); + + modelBuilder.Entity() //Use your application user class here + .ToTable("Users"); //Set the table name here + + // // Map table names + // modelBuilder.Entity().ToTable("MapLog", "dbo"); + // modelBuilder.Entity(entity => + // { + // entity.HasKey(e => e.MapLogId); + // }); + + // modelBuilder.Entity().ToTable("Session", "dbo"); + // modelBuilder.Entity(entity => + // { + // entity.HasKey(e => e.SessionId); + // entity.HasIndex(e => e.SessionName).IsUnique(); + // }); + + + // modelBuilder.Entity().ToTable("UserConnection", "dbo"); + // modelBuilder.Entity(entity => + // { + // entity.HasKey(e => e.UserConnectionId); + // entity.HasIndex(e => e.UserId); + + // }); + + // modelBuilder.Entity().ToTable("SessionUser", "dbo"); + // modelBuilder.Entity(entity => + // { + // entity.HasKey(e => e.SessionUserId); + // entity.HasIndex(e => e.SessionId); + + // }); + + // modelBuilder.Entity().ToTable("Snapshot", "dbo"); + // modelBuilder.Entity(entity => + // { + // entity.HasKey(e => e.SnapshotId); + // }); + + base.OnModelCreating(modelBuilder); + } + } +} \ No newline at end of file diff --git a/Sledgemapper.Api/JwtConfig.cs b/Sledgemapper.Api/JwtConfig.cs new file mode 100644 index 0000000..7c5c5c4 --- /dev/null +++ b/Sledgemapper.Api/JwtConfig.cs @@ -0,0 +1,7 @@ +namespace Sledgemapper.Api +{ + public class JwtConfig + { + public string Secret { get; set; } + } +} \ No newline at end of file diff --git a/Sledgemapper.Api/Migrations/20210219223114_InitialCreate.Designer.cs b/Sledgemapper.Api/Migrations/20210219223114_InitialCreate.Designer.cs new file mode 100644 index 0000000..fc87031 --- /dev/null +++ b/Sledgemapper.Api/Migrations/20210219223114_InitialCreate.Designer.cs @@ -0,0 +1,258 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Sledgemapper.Api.Infrastructure.Data; + +namespace Sledgemapper.Api.Migrations +{ + [DbContext(typeof(SledgemapperDbContext))] + [Migration("20210219223114_InitialCreate")] + partial class InitialCreate + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "5.0.3"); + + modelBuilder.Entity("CampaignUser", b => + { + b.Property("CampaignsCampaignId") + .HasColumnType("INTEGER"); + + b.Property("InvitedUsersId") + .HasColumnType("INTEGER"); + + b.HasKey("CampaignsCampaignId", "InvitedUsersId"); + + b.HasIndex("InvitedUsersId"); + + b.ToTable("CampaignUser"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.Property("CampaignId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CampaignName") + .HasColumnType("TEXT"); + + b.Property("OwnerId") + .HasColumnType("INTEGER"); + + b.HasKey("CampaignId"); + + b.HasIndex("OwnerId"); + + b.HasIndex("CampaignName", "OwnerId") + .IsUnique(); + + b.ToTable("Campaigns"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Map", b => + { + b.Property("MapId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CampaignId") + .HasColumnType("INTEGER"); + + b.Property("MapName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("MapId"); + + b.HasIndex("CampaignId"); + + b.ToTable("Maps"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.MapLog", b => + { + b.Property("MapLogId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Object") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("Operation") + .IsRequired() + .HasMaxLength(1) + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("Timestamp") + .HasColumnType("REAL"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("MapLogId"); + + b.ToTable("MapLogs"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Session", b => + { + b.Property("SessionId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("OwnerUserId") + .HasColumnType("INTEGER"); + + b.Property("SessionName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("SessionId"); + + b.ToTable("Sessions"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.SessionUser", b => + { + b.Property("SessionUserId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("SessionUserId"); + + b.ToTable("SessionUsers"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Snapshot", b => + { + b.Property("SnapshotId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Object") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("Timestamp") + .HasColumnType("REAL"); + + b.HasKey("SnapshotId"); + + b.ToTable("Snapshots"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.UserConnection", b => + { + b.Property("UserConnectionId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConnectionId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("UserConnectionId"); + + b.ToTable("UserConnections"); + }); + + modelBuilder.Entity("Sledgemapper.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("FirstName") + .HasColumnType("TEXT"); + + b.Property("Initials") + .HasColumnType("TEXT"); + + b.Property("LastName") + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("BLOB"); + + b.Property("PasswordSalt") + .HasColumnType("BLOB"); + + b.Property("Username") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("CampaignUser", b => + { + b.HasOne("Sledgemapper.Api.Core.Entities.Campaign", null) + .WithMany() + .HasForeignKey("CampaignsCampaignId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Sledgemapper.Entities.User", null) + .WithMany() + .HasForeignKey("InvitedUsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.HasOne("Sledgemapper.Entities.User", "Owner") + .WithMany() + .HasForeignKey("OwnerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Owner"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Map", b => + { + b.HasOne("Sledgemapper.Api.Core.Entities.Campaign", null) + .WithMany("Maps") + .HasForeignKey("CampaignId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.Navigation("Maps"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Sledgemapper.Api/Migrations/20210219223114_InitialCreate.cs b/Sledgemapper.Api/Migrations/20210219223114_InitialCreate.cs new file mode 100644 index 0000000..81e0648 --- /dev/null +++ b/Sledgemapper.Api/Migrations/20210219223114_InitialCreate.cs @@ -0,0 +1,218 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Sledgemapper.Api.Migrations +{ + public partial class InitialCreate : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "MapLogs", + columns: table => new + { + MapLogId = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + UserId = table.Column(type: "INTEGER", nullable: false), + SessionId = table.Column(type: "INTEGER", nullable: false), + Operation = table.Column(type: "TEXT", maxLength: 1, nullable: false), + Type = table.Column(type: "TEXT", maxLength: 256, nullable: false), + Object = table.Column(type: "TEXT", maxLength: 256, nullable: false), + Timestamp = table.Column(type: "REAL", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_MapLogs", x => x.MapLogId); + }); + + migrationBuilder.CreateTable( + name: "Sessions", + columns: table => new + { + SessionId = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + SessionName = table.Column(type: "TEXT", nullable: false), + OwnerUserId = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Sessions", x => x.SessionId); + }); + + migrationBuilder.CreateTable( + name: "SessionUsers", + columns: table => new + { + SessionUserId = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + SessionId = table.Column(type: "INTEGER", nullable: false), + UserId = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_SessionUsers", x => x.SessionUserId); + }); + + migrationBuilder.CreateTable( + name: "Snapshots", + columns: table => new + { + SnapshotId = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + SessionId = table.Column(type: "INTEGER", nullable: false), + Object = table.Column(type: "TEXT", nullable: false), + Timestamp = table.Column(type: "REAL", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Snapshots", x => x.SnapshotId); + }); + + migrationBuilder.CreateTable( + name: "UserConnections", + columns: table => new + { + UserConnectionId = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + UserId = table.Column(type: "INTEGER", nullable: false), + ConnectionId = table.Column(type: "TEXT", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_UserConnections", x => x.UserConnectionId); + }); + + migrationBuilder.CreateTable( + name: "Users", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + FirstName = table.Column(type: "TEXT", nullable: true), + LastName = table.Column(type: "TEXT", nullable: true), + Username = table.Column(type: "TEXT", nullable: true), + Initials = table.Column(type: "TEXT", nullable: true), + PasswordHash = table.Column(type: "BLOB", nullable: true), + PasswordSalt = table.Column(type: "BLOB", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Users", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Campaigns", + columns: table => new + { + CampaignId = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + CampaignName = table.Column(type: "TEXT", nullable: true), + OwnerId = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Campaigns", x => x.CampaignId); + table.ForeignKey( + name: "FK_Campaigns_Users_OwnerId", + column: x => x.OwnerId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "CampaignUser", + columns: table => new + { + CampaignsCampaignId = table.Column(type: "INTEGER", nullable: false), + InvitedUsersId = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_CampaignUser", x => new { x.CampaignsCampaignId, x.InvitedUsersId }); + table.ForeignKey( + name: "FK_CampaignUser_Campaigns_CampaignsCampaignId", + column: x => x.CampaignsCampaignId, + principalTable: "Campaigns", + principalColumn: "CampaignId", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_CampaignUser_Users_InvitedUsersId", + column: x => x.InvitedUsersId, + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Maps", + columns: table => new + { + MapId = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + MapName = table.Column(type: "TEXT", nullable: false), + CampaignId = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Maps", x => x.MapId); + table.ForeignKey( + name: "FK_Maps_Campaigns_CampaignId", + column: x => x.CampaignId, + principalTable: "Campaigns", + principalColumn: "CampaignId", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_Campaigns_CampaignName_OwnerId", + table: "Campaigns", + columns: new[] { "CampaignName", "OwnerId" }, + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Campaigns_OwnerId", + table: "Campaigns", + column: "OwnerId"); + + migrationBuilder.CreateIndex( + name: "IX_CampaignUser_InvitedUsersId", + table: "CampaignUser", + column: "InvitedUsersId"); + + migrationBuilder.CreateIndex( + name: "IX_Maps_CampaignId", + table: "Maps", + column: "CampaignId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "CampaignUser"); + + migrationBuilder.DropTable( + name: "MapLogs"); + + migrationBuilder.DropTable( + name: "Maps"); + + migrationBuilder.DropTable( + name: "Sessions"); + + migrationBuilder.DropTable( + name: "SessionUsers"); + + migrationBuilder.DropTable( + name: "Snapshots"); + + migrationBuilder.DropTable( + name: "UserConnections"); + + migrationBuilder.DropTable( + name: "Campaigns"); + + migrationBuilder.DropTable( + name: "Users"); + } + } +} diff --git a/Sledgemapper.Api/Migrations/20210219223251_Adding authentication to our Api.Designer.cs b/Sledgemapper.Api/Migrations/20210219223251_Adding authentication to our Api.Designer.cs new file mode 100644 index 0000000..faeeb8c --- /dev/null +++ b/Sledgemapper.Api/Migrations/20210219223251_Adding authentication to our Api.Designer.cs @@ -0,0 +1,258 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Sledgemapper.Api.Infrastructure.Data; + +namespace Sledgemapper.Api.Migrations +{ + [DbContext(typeof(SledgemapperDbContext))] + [Migration("20210219223251_Adding authentication to our Api")] + partial class AddingauthenticationtoourApi + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "5.0.3"); + + modelBuilder.Entity("CampaignUser", b => + { + b.Property("CampaignsCampaignId") + .HasColumnType("INTEGER"); + + b.Property("InvitedUsersId") + .HasColumnType("INTEGER"); + + b.HasKey("CampaignsCampaignId", "InvitedUsersId"); + + b.HasIndex("InvitedUsersId"); + + b.ToTable("CampaignUser"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.Property("CampaignId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CampaignName") + .HasColumnType("TEXT"); + + b.Property("OwnerId") + .HasColumnType("INTEGER"); + + b.HasKey("CampaignId"); + + b.HasIndex("OwnerId"); + + b.HasIndex("CampaignName", "OwnerId") + .IsUnique(); + + b.ToTable("Campaigns"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Map", b => + { + b.Property("MapId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CampaignId") + .HasColumnType("INTEGER"); + + b.Property("MapName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("MapId"); + + b.HasIndex("CampaignId"); + + b.ToTable("Maps"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.MapLog", b => + { + b.Property("MapLogId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Object") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("Operation") + .IsRequired() + .HasMaxLength(1) + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("Timestamp") + .HasColumnType("REAL"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("MapLogId"); + + b.ToTable("MapLogs"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Session", b => + { + b.Property("SessionId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("OwnerUserId") + .HasColumnType("INTEGER"); + + b.Property("SessionName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("SessionId"); + + b.ToTable("Sessions"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.SessionUser", b => + { + b.Property("SessionUserId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("SessionUserId"); + + b.ToTable("SessionUsers"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Snapshot", b => + { + b.Property("SnapshotId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Object") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("Timestamp") + .HasColumnType("REAL"); + + b.HasKey("SnapshotId"); + + b.ToTable("Snapshots"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.UserConnection", b => + { + b.Property("UserConnectionId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConnectionId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("UserConnectionId"); + + b.ToTable("UserConnections"); + }); + + modelBuilder.Entity("Sledgemapper.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("FirstName") + .HasColumnType("TEXT"); + + b.Property("Initials") + .HasColumnType("TEXT"); + + b.Property("LastName") + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("BLOB"); + + b.Property("PasswordSalt") + .HasColumnType("BLOB"); + + b.Property("Username") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("CampaignUser", b => + { + b.HasOne("Sledgemapper.Api.Core.Entities.Campaign", null) + .WithMany() + .HasForeignKey("CampaignsCampaignId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Sledgemapper.Entities.User", null) + .WithMany() + .HasForeignKey("InvitedUsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.HasOne("Sledgemapper.Entities.User", "Owner") + .WithMany() + .HasForeignKey("OwnerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Owner"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Map", b => + { + b.HasOne("Sledgemapper.Api.Core.Entities.Campaign", null) + .WithMany("Maps") + .HasForeignKey("CampaignId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.Navigation("Maps"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Sledgemapper.Api/Migrations/20210219223251_Adding authentication to our Api.cs b/Sledgemapper.Api/Migrations/20210219223251_Adding authentication to our Api.cs new file mode 100644 index 0000000..79e5c82 --- /dev/null +++ b/Sledgemapper.Api/Migrations/20210219223251_Adding authentication to our Api.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Sledgemapper.Api.Migrations +{ + public partial class AddingauthenticationtoourApi : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/Sledgemapper.Api/Migrations/20210219230948_rename table.Designer.cs b/Sledgemapper.Api/Migrations/20210219230948_rename table.Designer.cs new file mode 100644 index 0000000..d16b294 --- /dev/null +++ b/Sledgemapper.Api/Migrations/20210219230948_rename table.Designer.cs @@ -0,0 +1,505 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Sledgemapper.Api.Infrastructure.Data; + +namespace Sledgemapper.Api.Migrations +{ + [DbContext(typeof(SledgemapperDbContext))] + [Migration("20210219230948_rename table")] + partial class renametable + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "5.0.3"); + + modelBuilder.Entity("CampaignUser", b => + { + b.Property("CampaignsCampaignId") + .HasColumnType("INTEGER"); + + b.Property("InvitedUsersId") + .HasColumnType("TEXT"); + + b.HasKey("CampaignsCampaignId", "InvitedUsersId"); + + b.HasIndex("InvitedUsersId"); + + b.ToTable("CampaignUser"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.Property("CampaignId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CampaignName") + .HasColumnType("TEXT"); + + b.Property("OwnerId") + .HasColumnType("TEXT"); + + b.HasKey("CampaignId"); + + b.HasIndex("OwnerId"); + + b.HasIndex("CampaignName", "OwnerId") + .IsUnique(); + + b.ToTable("Campaigns"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Map", b => + { + b.Property("MapId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CampaignId") + .HasColumnType("INTEGER"); + + b.Property("MapName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("MapId"); + + b.HasIndex("CampaignId"); + + b.ToTable("Maps"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.MapLog", b => + { + b.Property("MapLogId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Object") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("Operation") + .IsRequired() + .HasMaxLength(1) + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("Timestamp") + .HasColumnType("REAL"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("MapLogId"); + + b.ToTable("MapLogs"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Session", b => + { + b.Property("SessionId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("OwnerUserId") + .HasColumnType("INTEGER"); + + b.Property("SessionName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("SessionId"); + + b.ToTable("Sessions"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.SessionUser", b => + { + b.Property("SessionUserId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("SessionUserId"); + + b.ToTable("SessionUsers"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Snapshot", b => + { + b.Property("SnapshotId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Object") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("Timestamp") + .HasColumnType("REAL"); + + b.HasKey("SnapshotId"); + + b.ToTable("Snapshots"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.UserConnection", b => + { + b.Property("UserConnectionId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConnectionId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("UserConnectionId"); + + b.ToTable("UserConnections"); + }); + + modelBuilder.Entity("Sledgemapper.Entities.User", b => + { + b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityUser"); + + b.Property("FirstName") + .HasColumnType("TEXT"); + + b.Property("Initials") + .HasColumnType("TEXT"); + + b.Property("LastName") + .HasColumnType("TEXT"); + + b.Property("PasswordSalt") + .HasColumnType("BLOB"); + + b.Property("Username") + .HasColumnType("TEXT"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("CampaignUser", b => + { + b.HasOne("Sledgemapper.Api.Core.Entities.Campaign", null) + .WithMany() + .HasForeignKey("CampaignsCampaignId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Sledgemapper.Entities.User", null) + .WithMany() + .HasForeignKey("InvitedUsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.HasOne("Sledgemapper.Entities.User", "Owner") + .WithMany() + .HasForeignKey("OwnerId"); + + b.Navigation("Owner"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Map", b => + { + b.HasOne("Sledgemapper.Api.Core.Entities.Campaign", null) + .WithMany("Maps") + .HasForeignKey("CampaignId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Entities.User", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithOne() + .HasForeignKey("Sledgemapper.Entities.User", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.Navigation("Maps"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Sledgemapper.Api/Migrations/20210219230948_rename table.cs b/Sledgemapper.Api/Migrations/20210219230948_rename table.cs new file mode 100644 index 0000000..ac5f815 --- /dev/null +++ b/Sledgemapper.Api/Migrations/20210219230948_rename table.cs @@ -0,0 +1,315 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Sledgemapper.Api.Migrations +{ + public partial class renametable : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Campaigns_Users_OwnerId", + table: "Campaigns"); + + migrationBuilder.DropColumn( + name: "PasswordHash", + table: "Users"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "Users", + type: "TEXT", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER") + .OldAnnotation("Sqlite:Autoincrement", true); + + migrationBuilder.AlterColumn( + name: "InvitedUsersId", + table: "CampaignUser", + type: "TEXT", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AlterColumn( + name: "OwnerId", + table: "Campaigns", + type: "TEXT", + nullable: true, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.CreateTable( + name: "AspNetRoles", + columns: table => new + { + Id = table.Column(type: "TEXT", nullable: false), + Name = table.Column(type: "TEXT", maxLength: 256, nullable: true), + NormalizedName = table.Column(type: "TEXT", maxLength: 256, nullable: true), + ConcurrencyStamp = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoles", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AspNetUsers", + columns: table => new + { + Id = table.Column(type: "TEXT", nullable: false), + UserName = table.Column(type: "TEXT", maxLength: 256, nullable: true), + NormalizedUserName = table.Column(type: "TEXT", maxLength: 256, nullable: true), + Email = table.Column(type: "TEXT", maxLength: 256, nullable: true), + NormalizedEmail = table.Column(type: "TEXT", maxLength: 256, nullable: true), + EmailConfirmed = table.Column(type: "INTEGER", nullable: false), + PasswordHash = table.Column(type: "TEXT", nullable: true), + SecurityStamp = table.Column(type: "TEXT", nullable: true), + ConcurrencyStamp = table.Column(type: "TEXT", nullable: true), + PhoneNumber = table.Column(type: "TEXT", nullable: true), + PhoneNumberConfirmed = table.Column(type: "INTEGER", nullable: false), + TwoFactorEnabled = table.Column(type: "INTEGER", nullable: false), + LockoutEnd = table.Column(type: "TEXT", nullable: true), + LockoutEnabled = table.Column(type: "INTEGER", nullable: false), + AccessFailedCount = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUsers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AspNetRoleClaims", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + RoleId = table.Column(type: "TEXT", nullable: false), + ClaimType = table.Column(type: "TEXT", nullable: true), + ClaimValue = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetRoleClaims_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserClaims", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + UserId = table.Column(type: "TEXT", nullable: false), + ClaimType = table.Column(type: "TEXT", nullable: true), + ClaimValue = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetUserClaims_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserLogins", + columns: table => new + { + LoginProvider = table.Column(type: "TEXT", maxLength: 128, nullable: false), + ProviderKey = table.Column(type: "TEXT", maxLength: 128, nullable: false), + ProviderDisplayName = table.Column(type: "TEXT", nullable: true), + UserId = table.Column(type: "TEXT", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey }); + table.ForeignKey( + name: "FK_AspNetUserLogins_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserRoles", + columns: table => new + { + UserId = table.Column(type: "TEXT", nullable: false), + RoleId = table.Column(type: "TEXT", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId }); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserTokens", + columns: table => new + { + UserId = table.Column(type: "TEXT", nullable: false), + LoginProvider = table.Column(type: "TEXT", maxLength: 128, nullable: false), + Name = table.Column(type: "TEXT", maxLength: 128, nullable: false), + Value = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); + table.ForeignKey( + name: "FK_AspNetUserTokens_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_AspNetRoleClaims_RoleId", + table: "AspNetRoleClaims", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "RoleNameIndex", + table: "AspNetRoles", + column: "NormalizedName", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserClaims_UserId", + table: "AspNetUserClaims", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserLogins_UserId", + table: "AspNetUserLogins", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserRoles_RoleId", + table: "AspNetUserRoles", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "EmailIndex", + table: "AspNetUsers", + column: "NormalizedEmail"); + + migrationBuilder.CreateIndex( + name: "UserNameIndex", + table: "AspNetUsers", + column: "NormalizedUserName", + unique: true); + + migrationBuilder.AddForeignKey( + name: "FK_Campaigns_Users_OwnerId", + table: "Campaigns", + column: "OwnerId", + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + + migrationBuilder.AddForeignKey( + name: "FK_Users_AspNetUsers_Id", + table: "Users", + column: "Id", + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Campaigns_Users_OwnerId", + table: "Campaigns"); + + migrationBuilder.DropForeignKey( + name: "FK_Users_AspNetUsers_Id", + table: "Users"); + + migrationBuilder.DropTable( + name: "AspNetRoleClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserLogins"); + + migrationBuilder.DropTable( + name: "AspNetUserRoles"); + + migrationBuilder.DropTable( + name: "AspNetUserTokens"); + + migrationBuilder.DropTable( + name: "AspNetRoles"); + + migrationBuilder.DropTable( + name: "AspNetUsers"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "Users", + type: "INTEGER", + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT") + .Annotation("Sqlite:Autoincrement", true); + + migrationBuilder.AddColumn( + name: "PasswordHash", + table: "Users", + type: "BLOB", + nullable: true); + + migrationBuilder.AlterColumn( + name: "InvitedUsersId", + table: "CampaignUser", + type: "INTEGER", + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "OwnerId", + table: "Campaigns", + type: "INTEGER", + nullable: false, + defaultValue: 0, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AddForeignKey( + name: "FK_Campaigns_Users_OwnerId", + table: "Campaigns", + column: "OwnerId", + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/Sledgemapper.Api/Migrations/20210528182730_ChangeCompanyId.Designer.cs b/Sledgemapper.Api/Migrations/20210528182730_ChangeCompanyId.Designer.cs new file mode 100644 index 0000000..abbac2c --- /dev/null +++ b/Sledgemapper.Api/Migrations/20210528182730_ChangeCompanyId.Designer.cs @@ -0,0 +1,503 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Sledgemapper.Api.Infrastructure.Data; + +namespace Sledgemapper.Api.Migrations +{ + [DbContext(typeof(SledgemapperDbContext))] + [Migration("20210528182730_ChangeCompanyId")] + partial class ChangeCompanyId + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "5.0.6"); + + modelBuilder.Entity("CampaignUser", b => + { + b.Property("CampaignsCampaignId") + .HasColumnType("TEXT"); + + b.Property("InvitedUsersId") + .HasColumnType("TEXT"); + + b.HasKey("CampaignsCampaignId", "InvitedUsersId"); + + b.HasIndex("InvitedUsersId"); + + b.ToTable("CampaignUser"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.Property("CampaignId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CampaignName") + .HasColumnType("TEXT"); + + b.Property("OwnerId") + .HasColumnType("TEXT"); + + b.HasKey("CampaignId"); + + b.HasIndex("OwnerId"); + + b.HasIndex("CampaignName", "OwnerId") + .IsUnique(); + + b.ToTable("Campaigns"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Map", b => + { + b.Property("MapId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CampaignId") + .HasColumnType("INTEGER"); + + b.Property("CampaignId1") + .HasColumnType("TEXT"); + + b.Property("MapName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("MapId"); + + b.HasIndex("CampaignId1"); + + b.ToTable("Maps"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.MapLog", b => + { + b.Property("MapLogId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Object") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("Operation") + .IsRequired() + .HasMaxLength(1) + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("Timestamp") + .HasColumnType("REAL"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("MapLogId"); + + b.ToTable("MapLogs"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Session", b => + { + b.Property("SessionId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("OwnerUserId") + .HasColumnType("INTEGER"); + + b.Property("SessionName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("SessionId"); + + b.ToTable("Sessions"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.SessionUser", b => + { + b.Property("SessionUserId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("SessionUserId"); + + b.ToTable("SessionUsers"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Snapshot", b => + { + b.Property("SnapshotId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Object") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("Timestamp") + .HasColumnType("REAL"); + + b.HasKey("SnapshotId"); + + b.ToTable("Snapshots"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.UserConnection", b => + { + b.Property("UserConnectionId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConnectionId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("UserConnectionId"); + + b.ToTable("UserConnections"); + }); + + modelBuilder.Entity("Sledgemapper.Entities.User", b => + { + b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityUser"); + + b.Property("FirstName") + .HasColumnType("TEXT"); + + b.Property("Initials") + .HasColumnType("TEXT"); + + b.Property("LastName") + .HasColumnType("TEXT"); + + b.Property("PasswordSalt") + .HasColumnType("BLOB"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("CampaignUser", b => + { + b.HasOne("Sledgemapper.Api.Core.Entities.Campaign", null) + .WithMany() + .HasForeignKey("CampaignsCampaignId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Sledgemapper.Entities.User", null) + .WithMany() + .HasForeignKey("InvitedUsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.HasOne("Sledgemapper.Entities.User", "Owner") + .WithMany() + .HasForeignKey("OwnerId"); + + b.Navigation("Owner"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Map", b => + { + b.HasOne("Sledgemapper.Api.Core.Entities.Campaign", null) + .WithMany("Maps") + .HasForeignKey("CampaignId1"); + }); + + modelBuilder.Entity("Sledgemapper.Entities.User", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithOne() + .HasForeignKey("Sledgemapper.Entities.User", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.Navigation("Maps"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Sledgemapper.Api/Migrations/20210528182730_ChangeCompanyId.cs b/Sledgemapper.Api/Migrations/20210528182730_ChangeCompanyId.cs new file mode 100644 index 0000000..b56d87e --- /dev/null +++ b/Sledgemapper.Api/Migrations/20210528182730_ChangeCompanyId.cs @@ -0,0 +1,110 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Sledgemapper.Api.Migrations +{ + public partial class ChangeCompanyId : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Maps_Campaigns_CampaignId", + table: "Maps"); + + migrationBuilder.DropIndex( + name: "IX_Maps_CampaignId", + table: "Maps"); + + migrationBuilder.DropColumn( + name: "Username", + table: "Users"); + + migrationBuilder.AddColumn( + name: "CampaignId1", + table: "Maps", + type: "TEXT", + nullable: true); + + migrationBuilder.AlterColumn( + name: "CampaignsCampaignId", + table: "CampaignUser", + type: "TEXT", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AlterColumn( + name: "CampaignId", + table: "Campaigns", + type: "TEXT", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER") + .OldAnnotation("Sqlite:Autoincrement", true); + + migrationBuilder.CreateIndex( + name: "IX_Maps_CampaignId1", + table: "Maps", + column: "CampaignId1"); + + migrationBuilder.AddForeignKey( + name: "FK_Maps_Campaigns_CampaignId1", + table: "Maps", + column: "CampaignId1", + principalTable: "Campaigns", + principalColumn: "CampaignId", + onDelete: ReferentialAction.Restrict); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Maps_Campaigns_CampaignId1", + table: "Maps"); + + migrationBuilder.DropIndex( + name: "IX_Maps_CampaignId1", + table: "Maps"); + + migrationBuilder.DropColumn( + name: "CampaignId1", + table: "Maps"); + + migrationBuilder.AddColumn( + name: "Username", + table: "Users", + type: "TEXT", + nullable: true); + + migrationBuilder.AlterColumn( + name: "CampaignsCampaignId", + table: "CampaignUser", + type: "INTEGER", + nullable: false, + oldClrType: typeof(Guid), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "CampaignId", + table: "Campaigns", + type: "INTEGER", + nullable: false, + oldClrType: typeof(Guid), + oldType: "TEXT") + .Annotation("Sqlite:Autoincrement", true); + + migrationBuilder.CreateIndex( + name: "IX_Maps_CampaignId", + table: "Maps", + column: "CampaignId"); + + migrationBuilder.AddForeignKey( + name: "FK_Maps_Campaigns_CampaignId", + table: "Maps", + column: "CampaignId", + principalTable: "Campaigns", + principalColumn: "CampaignId", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/Sledgemapper.Api/Migrations/20210830220131_AddCampaignToMap.Designer.cs b/Sledgemapper.Api/Migrations/20210830220131_AddCampaignToMap.Designer.cs new file mode 100644 index 0000000..e1365d5 --- /dev/null +++ b/Sledgemapper.Api/Migrations/20210830220131_AddCampaignToMap.Designer.cs @@ -0,0 +1,506 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Sledgemapper.Api.Infrastructure.Data; + +namespace Sledgemapper.Api.Migrations +{ + [DbContext(typeof(SledgemapperDbContext))] + [Migration("20210830220131_AddCampaignToMap")] + partial class AddCampaignToMap + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "5.0.6"); + + modelBuilder.Entity("CampaignUser", b => + { + b.Property("CampaignsCampaignId") + .HasColumnType("TEXT"); + + b.Property("InvitedUsersId") + .HasColumnType("TEXT"); + + b.HasKey("CampaignsCampaignId", "InvitedUsersId"); + + b.HasIndex("InvitedUsersId"); + + b.ToTable("CampaignUser"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.Property("CampaignId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CampaignName") + .HasColumnType("TEXT"); + + b.Property("OwnerId") + .HasColumnType("TEXT"); + + b.HasKey("CampaignId"); + + b.HasIndex("OwnerId"); + + b.HasIndex("CampaignName", "OwnerId") + .IsUnique(); + + b.ToTable("Campaigns"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Map", b => + { + b.Property("MapId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CampaignId") + .HasColumnType("INTEGER"); + + b.Property("CampaignId1") + .HasColumnType("TEXT"); + + b.Property("MapName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("MapId"); + + b.HasIndex("CampaignId1"); + + b.ToTable("Maps"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.MapLog", b => + { + b.Property("MapLogId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Object") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("Operation") + .IsRequired() + .HasMaxLength(1) + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("Timestamp") + .HasColumnType("REAL"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("MapLogId"); + + b.ToTable("MapLogs"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Session", b => + { + b.Property("SessionId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CampaignId") + .HasColumnType("INTEGER"); + + b.Property("OwnerUserId") + .HasColumnType("INTEGER"); + + b.Property("SessionName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("SessionId"); + + b.ToTable("Sessions"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.SessionUser", b => + { + b.Property("SessionUserId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("SessionUserId"); + + b.ToTable("SessionUsers"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Snapshot", b => + { + b.Property("SnapshotId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Object") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("Timestamp") + .HasColumnType("REAL"); + + b.HasKey("SnapshotId"); + + b.ToTable("Snapshots"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.UserConnection", b => + { + b.Property("UserConnectionId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConnectionId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("UserConnectionId"); + + b.ToTable("UserConnections"); + }); + + modelBuilder.Entity("Sledgemapper.Entities.User", b => + { + b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityUser"); + + b.Property("FirstName") + .HasColumnType("TEXT"); + + b.Property("Initials") + .HasColumnType("TEXT"); + + b.Property("LastName") + .HasColumnType("TEXT"); + + b.Property("PasswordSalt") + .HasColumnType("BLOB"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("CampaignUser", b => + { + b.HasOne("Sledgemapper.Api.Core.Entities.Campaign", null) + .WithMany() + .HasForeignKey("CampaignsCampaignId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Sledgemapper.Entities.User", null) + .WithMany() + .HasForeignKey("InvitedUsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.HasOne("Sledgemapper.Entities.User", "Owner") + .WithMany() + .HasForeignKey("OwnerId"); + + b.Navigation("Owner"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Map", b => + { + b.HasOne("Sledgemapper.Api.Core.Entities.Campaign", null) + .WithMany("Maps") + .HasForeignKey("CampaignId1"); + }); + + modelBuilder.Entity("Sledgemapper.Entities.User", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithOne() + .HasForeignKey("Sledgemapper.Entities.User", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.Navigation("Maps"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Sledgemapper.Api/Migrations/20210830220131_AddCampaignToMap.cs b/Sledgemapper.Api/Migrations/20210830220131_AddCampaignToMap.cs new file mode 100644 index 0000000..2bd6cf7 --- /dev/null +++ b/Sledgemapper.Api/Migrations/20210830220131_AddCampaignToMap.cs @@ -0,0 +1,24 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Sledgemapper.Api.Migrations +{ + public partial class AddCampaignToMap : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "CampaignId", + table: "Sessions", + type: "INTEGER", + nullable: false, + defaultValue: 0); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "CampaignId", + table: "Sessions"); + } + } +} diff --git a/Sledgemapper.Api/Migrations/20210830220730_AddCampaignToMapGuid.Designer.cs b/Sledgemapper.Api/Migrations/20210830220730_AddCampaignToMapGuid.Designer.cs new file mode 100644 index 0000000..ebd924b --- /dev/null +++ b/Sledgemapper.Api/Migrations/20210830220730_AddCampaignToMapGuid.Designer.cs @@ -0,0 +1,506 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Sledgemapper.Api.Infrastructure.Data; + +namespace Sledgemapper.Api.Migrations +{ + [DbContext(typeof(SledgemapperDbContext))] + [Migration("20210830220730_AddCampaignToMapGuid")] + partial class AddCampaignToMapGuid + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "5.0.6"); + + modelBuilder.Entity("CampaignUser", b => + { + b.Property("CampaignsCampaignId") + .HasColumnType("TEXT"); + + b.Property("InvitedUsersId") + .HasColumnType("TEXT"); + + b.HasKey("CampaignsCampaignId", "InvitedUsersId"); + + b.HasIndex("InvitedUsersId"); + + b.ToTable("CampaignUser"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.Property("CampaignId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CampaignName") + .HasColumnType("TEXT"); + + b.Property("OwnerId") + .HasColumnType("TEXT"); + + b.HasKey("CampaignId"); + + b.HasIndex("OwnerId"); + + b.HasIndex("CampaignName", "OwnerId") + .IsUnique(); + + b.ToTable("Campaigns"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Map", b => + { + b.Property("MapId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CampaignId") + .HasColumnType("INTEGER"); + + b.Property("CampaignId1") + .HasColumnType("TEXT"); + + b.Property("MapName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("MapId"); + + b.HasIndex("CampaignId1"); + + b.ToTable("Maps"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.MapLog", b => + { + b.Property("MapLogId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Object") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("Operation") + .IsRequired() + .HasMaxLength(1) + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("Timestamp") + .HasColumnType("REAL"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("MapLogId"); + + b.ToTable("MapLogs"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Session", b => + { + b.Property("SessionId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CampaignId") + .HasColumnType("TEXT"); + + b.Property("OwnerUserId") + .HasColumnType("INTEGER"); + + b.Property("SessionName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("SessionId"); + + b.ToTable("Sessions"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.SessionUser", b => + { + b.Property("SessionUserId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("SessionUserId"); + + b.ToTable("SessionUsers"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Snapshot", b => + { + b.Property("SnapshotId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Object") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("Timestamp") + .HasColumnType("REAL"); + + b.HasKey("SnapshotId"); + + b.ToTable("Snapshots"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.UserConnection", b => + { + b.Property("UserConnectionId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConnectionId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("UserConnectionId"); + + b.ToTable("UserConnections"); + }); + + modelBuilder.Entity("Sledgemapper.Entities.User", b => + { + b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityUser"); + + b.Property("FirstName") + .HasColumnType("TEXT"); + + b.Property("Initials") + .HasColumnType("TEXT"); + + b.Property("LastName") + .HasColumnType("TEXT"); + + b.Property("PasswordSalt") + .HasColumnType("BLOB"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("CampaignUser", b => + { + b.HasOne("Sledgemapper.Api.Core.Entities.Campaign", null) + .WithMany() + .HasForeignKey("CampaignsCampaignId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Sledgemapper.Entities.User", null) + .WithMany() + .HasForeignKey("InvitedUsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.HasOne("Sledgemapper.Entities.User", "Owner") + .WithMany() + .HasForeignKey("OwnerId"); + + b.Navigation("Owner"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Map", b => + { + b.HasOne("Sledgemapper.Api.Core.Entities.Campaign", null) + .WithMany("Maps") + .HasForeignKey("CampaignId1"); + }); + + modelBuilder.Entity("Sledgemapper.Entities.User", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithOne() + .HasForeignKey("Sledgemapper.Entities.User", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.Navigation("Maps"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Sledgemapper.Api/Migrations/20210830220730_AddCampaignToMapGuid.cs b/Sledgemapper.Api/Migrations/20210830220730_AddCampaignToMapGuid.cs new file mode 100644 index 0000000..761e2b9 --- /dev/null +++ b/Sledgemapper.Api/Migrations/20210830220730_AddCampaignToMapGuid.cs @@ -0,0 +1,30 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Sledgemapper.Api.Migrations +{ + public partial class AddCampaignToMapGuid : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "CampaignId", + table: "Sessions", + type: "TEXT", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "CampaignId", + table: "Sessions", + type: "INTEGER", + nullable: false, + oldClrType: typeof(Guid), + oldType: "TEXT"); + } + } +} diff --git a/Sledgemapper.Api/Migrations/20210830222316_StringUserId.Designer.cs b/Sledgemapper.Api/Migrations/20210830222316_StringUserId.Designer.cs new file mode 100644 index 0000000..5376de8 --- /dev/null +++ b/Sledgemapper.Api/Migrations/20210830222316_StringUserId.Designer.cs @@ -0,0 +1,508 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Sledgemapper.Api.Infrastructure.Data; + +namespace Sledgemapper.Api.Migrations +{ + [DbContext(typeof(SledgemapperDbContext))] + [Migration("20210830222316_StringUserId")] + partial class StringUserId + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "5.0.6"); + + modelBuilder.Entity("CampaignUser", b => + { + b.Property("CampaignsCampaignId") + .HasColumnType("TEXT"); + + b.Property("InvitedUsersId") + .HasColumnType("TEXT"); + + b.HasKey("CampaignsCampaignId", "InvitedUsersId"); + + b.HasIndex("InvitedUsersId"); + + b.ToTable("CampaignUser"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.Property("CampaignId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CampaignName") + .HasColumnType("TEXT"); + + b.Property("OwnerId") + .HasColumnType("TEXT"); + + b.HasKey("CampaignId"); + + b.HasIndex("OwnerId"); + + b.HasIndex("CampaignName", "OwnerId") + .IsUnique(); + + b.ToTable("Campaigns"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Map", b => + { + b.Property("MapId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CampaignId") + .HasColumnType("INTEGER"); + + b.Property("CampaignId1") + .HasColumnType("TEXT"); + + b.Property("MapName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("MapId"); + + b.HasIndex("CampaignId1"); + + b.ToTable("Maps"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.MapLog", b => + { + b.Property("MapLogId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Object") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("Operation") + .IsRequired() + .HasMaxLength(1) + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("Timestamp") + .HasColumnType("REAL"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("MapLogId"); + + b.ToTable("MapLogs"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Session", b => + { + b.Property("SessionId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CampaignId") + .HasColumnType("TEXT"); + + b.Property("OwnerUserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SessionName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("SessionId"); + + b.ToTable("Sessions"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.SessionUser", b => + { + b.Property("SessionUserId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("SessionUserId"); + + b.ToTable("SessionUsers"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Snapshot", b => + { + b.Property("SnapshotId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Object") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("Timestamp") + .HasColumnType("REAL"); + + b.HasKey("SnapshotId"); + + b.ToTable("Snapshots"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.UserConnection", b => + { + b.Property("UserConnectionId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConnectionId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("UserConnectionId"); + + b.ToTable("UserConnections"); + }); + + modelBuilder.Entity("Sledgemapper.Entities.User", b => + { + b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityUser"); + + b.Property("FirstName") + .HasColumnType("TEXT"); + + b.Property("Initials") + .HasColumnType("TEXT"); + + b.Property("LastName") + .HasColumnType("TEXT"); + + b.Property("PasswordSalt") + .HasColumnType("BLOB"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("CampaignUser", b => + { + b.HasOne("Sledgemapper.Api.Core.Entities.Campaign", null) + .WithMany() + .HasForeignKey("CampaignsCampaignId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Sledgemapper.Entities.User", null) + .WithMany() + .HasForeignKey("InvitedUsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.HasOne("Sledgemapper.Entities.User", "Owner") + .WithMany() + .HasForeignKey("OwnerId"); + + b.Navigation("Owner"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Map", b => + { + b.HasOne("Sledgemapper.Api.Core.Entities.Campaign", null) + .WithMany("Maps") + .HasForeignKey("CampaignId1"); + }); + + modelBuilder.Entity("Sledgemapper.Entities.User", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithOne() + .HasForeignKey("Sledgemapper.Entities.User", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.Navigation("Maps"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Sledgemapper.Api/Migrations/20210830222316_StringUserId.cs b/Sledgemapper.Api/Migrations/20210830222316_StringUserId.cs new file mode 100644 index 0000000..d3bb947 --- /dev/null +++ b/Sledgemapper.Api/Migrations/20210830222316_StringUserId.cs @@ -0,0 +1,45 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Sledgemapper.Api.Migrations +{ + public partial class StringUserId : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "OwnerUserId", + table: "Sessions", + type: "TEXT", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AlterColumn( + name: "UserId", + table: "MapLogs", + type: "TEXT", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "OwnerUserId", + table: "Sessions", + type: "INTEGER", + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "UserId", + table: "MapLogs", + type: "INTEGER", + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT"); + } + } +} diff --git a/Sledgemapper.Api/Migrations/20210901220553_renameMapToSession.Designer.cs b/Sledgemapper.Api/Migrations/20210901220553_renameMapToSession.Designer.cs new file mode 100644 index 0000000..1546417 --- /dev/null +++ b/Sledgemapper.Api/Migrations/20210901220553_renameMapToSession.Designer.cs @@ -0,0 +1,507 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Sledgemapper.Api.Infrastructure.Data; + +namespace Sledgemapper.Api.Migrations +{ + [DbContext(typeof(SledgemapperDbContext))] + [Migration("20210901220553_renameMapToSession")] + partial class renameMapToSession + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "5.0.6"); + + modelBuilder.Entity("CampaignUser", b => + { + b.Property("CampaignsCampaignId") + .HasColumnType("TEXT"); + + b.Property("InvitedUsersId") + .HasColumnType("TEXT"); + + b.HasKey("CampaignsCampaignId", "InvitedUsersId"); + + b.HasIndex("InvitedUsersId"); + + b.ToTable("CampaignUser"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.Property("CampaignId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CampaignName") + .HasColumnType("TEXT"); + + b.Property("OwnerId") + .HasColumnType("TEXT"); + + b.HasKey("CampaignId"); + + b.HasIndex("OwnerId"); + + b.HasIndex("CampaignName", "OwnerId") + .IsUnique(); + + b.ToTable("Campaigns"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Map", b => + { + b.Property("MapId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CampaignId") + .HasColumnType("INTEGER"); + + b.Property("MapName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("MapId"); + + b.ToTable("Maps"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.MapLog", b => + { + b.Property("MapLogId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Object") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("Operation") + .IsRequired() + .HasMaxLength(1) + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("Timestamp") + .HasColumnType("REAL"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("MapLogId"); + + b.ToTable("MapLogs"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Session", b => + { + b.Property("SessionId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CampaignId") + .HasColumnType("TEXT"); + + b.Property("OwnerUserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SessionName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("SessionId"); + + b.HasIndex("CampaignId"); + + b.ToTable("Sessions"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.SessionUser", b => + { + b.Property("SessionUserId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("SessionUserId"); + + b.ToTable("SessionUsers"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Snapshot", b => + { + b.Property("SnapshotId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Object") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("Timestamp") + .HasColumnType("REAL"); + + b.HasKey("SnapshotId"); + + b.ToTable("Snapshots"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.UserConnection", b => + { + b.Property("UserConnectionId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConnectionId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("UserConnectionId"); + + b.ToTable("UserConnections"); + }); + + modelBuilder.Entity("Sledgemapper.Entities.User", b => + { + b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityUser"); + + b.Property("FirstName") + .HasColumnType("TEXT"); + + b.Property("Initials") + .HasColumnType("TEXT"); + + b.Property("LastName") + .HasColumnType("TEXT"); + + b.Property("PasswordSalt") + .HasColumnType("BLOB"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("CampaignUser", b => + { + b.HasOne("Sledgemapper.Api.Core.Entities.Campaign", null) + .WithMany() + .HasForeignKey("CampaignsCampaignId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Sledgemapper.Entities.User", null) + .WithMany() + .HasForeignKey("InvitedUsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.HasOne("Sledgemapper.Entities.User", "Owner") + .WithMany() + .HasForeignKey("OwnerId"); + + b.Navigation("Owner"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Session", b => + { + b.HasOne("Sledgemapper.Api.Core.Entities.Campaign", null) + .WithMany("Maps") + .HasForeignKey("CampaignId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Entities.User", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithOne() + .HasForeignKey("Sledgemapper.Entities.User", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.Navigation("Maps"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Sledgemapper.Api/Migrations/20210901220553_renameMapToSession.cs b/Sledgemapper.Api/Migrations/20210901220553_renameMapToSession.cs new file mode 100644 index 0000000..d40e21f --- /dev/null +++ b/Sledgemapper.Api/Migrations/20210901220553_renameMapToSession.cs @@ -0,0 +1,66 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Sledgemapper.Api.Migrations +{ + public partial class renameMapToSession : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Maps_Campaigns_CampaignId1", + table: "Maps"); + + migrationBuilder.DropIndex( + name: "IX_Maps_CampaignId1", + table: "Maps"); + + migrationBuilder.DropColumn( + name: "CampaignId1", + table: "Maps"); + + migrationBuilder.CreateIndex( + name: "IX_Sessions_CampaignId", + table: "Sessions", + column: "CampaignId"); + + migrationBuilder.AddForeignKey( + name: "FK_Sessions_Campaigns_CampaignId", + table: "Sessions", + column: "CampaignId", + principalTable: "Campaigns", + principalColumn: "CampaignId", + onDelete: ReferentialAction.Cascade); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Sessions_Campaigns_CampaignId", + table: "Sessions"); + + migrationBuilder.DropIndex( + name: "IX_Sessions_CampaignId", + table: "Sessions"); + + migrationBuilder.AddColumn( + name: "CampaignId1", + table: "Maps", + type: "TEXT", + nullable: true); + + migrationBuilder.CreateIndex( + name: "IX_Maps_CampaignId1", + table: "Maps", + column: "CampaignId1"); + + migrationBuilder.AddForeignKey( + name: "FK_Maps_Campaigns_CampaignId1", + table: "Maps", + column: "CampaignId1", + principalTable: "Campaigns", + principalColumn: "CampaignId", + onDelete: ReferentialAction.Restrict); + } + } +} diff --git a/Sledgemapper.Api/Migrations/20210901223606_uniquesessionindex.Designer.cs b/Sledgemapper.Api/Migrations/20210901223606_uniquesessionindex.Designer.cs new file mode 100644 index 0000000..6eed562 --- /dev/null +++ b/Sledgemapper.Api/Migrations/20210901223606_uniquesessionindex.Designer.cs @@ -0,0 +1,508 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Sledgemapper.Api.Infrastructure.Data; + +namespace Sledgemapper.Api.Migrations +{ + [DbContext(typeof(SledgemapperDbContext))] + [Migration("20210901223606_uniquesessionindex")] + partial class uniquesessionindex + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "5.0.6"); + + modelBuilder.Entity("CampaignUser", b => + { + b.Property("CampaignsCampaignId") + .HasColumnType("TEXT"); + + b.Property("InvitedUsersId") + .HasColumnType("TEXT"); + + b.HasKey("CampaignsCampaignId", "InvitedUsersId"); + + b.HasIndex("InvitedUsersId"); + + b.ToTable("CampaignUser"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.Property("CampaignId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CampaignName") + .HasColumnType("TEXT"); + + b.Property("OwnerId") + .HasColumnType("TEXT"); + + b.HasKey("CampaignId"); + + b.HasIndex("OwnerId"); + + b.HasIndex("CampaignName", "OwnerId") + .IsUnique(); + + b.ToTable("Campaigns"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Map", b => + { + b.Property("MapId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CampaignId") + .HasColumnType("INTEGER"); + + b.Property("MapName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("MapId"); + + b.ToTable("Maps"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.MapLog", b => + { + b.Property("MapLogId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Object") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("Operation") + .IsRequired() + .HasMaxLength(1) + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("Timestamp") + .HasColumnType("REAL"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("MapLogId"); + + b.ToTable("MapLogs"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Session", b => + { + b.Property("SessionId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CampaignId") + .HasColumnType("TEXT"); + + b.Property("OwnerUserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SessionName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("SessionId"); + + b.HasIndex("CampaignId", "SessionId") + .IsUnique(); + + b.ToTable("Sessions"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.SessionUser", b => + { + b.Property("SessionUserId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("SessionUserId"); + + b.ToTable("SessionUsers"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Snapshot", b => + { + b.Property("SnapshotId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Object") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("Timestamp") + .HasColumnType("REAL"); + + b.HasKey("SnapshotId"); + + b.ToTable("Snapshots"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.UserConnection", b => + { + b.Property("UserConnectionId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConnectionId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("UserConnectionId"); + + b.ToTable("UserConnections"); + }); + + modelBuilder.Entity("Sledgemapper.Entities.User", b => + { + b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityUser"); + + b.Property("FirstName") + .HasColumnType("TEXT"); + + b.Property("Initials") + .HasColumnType("TEXT"); + + b.Property("LastName") + .HasColumnType("TEXT"); + + b.Property("PasswordSalt") + .HasColumnType("BLOB"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("CampaignUser", b => + { + b.HasOne("Sledgemapper.Api.Core.Entities.Campaign", null) + .WithMany() + .HasForeignKey("CampaignsCampaignId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Sledgemapper.Entities.User", null) + .WithMany() + .HasForeignKey("InvitedUsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.HasOne("Sledgemapper.Entities.User", "Owner") + .WithMany() + .HasForeignKey("OwnerId"); + + b.Navigation("Owner"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Session", b => + { + b.HasOne("Sledgemapper.Api.Core.Entities.Campaign", null) + .WithMany("Maps") + .HasForeignKey("CampaignId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Entities.User", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithOne() + .HasForeignKey("Sledgemapper.Entities.User", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.Navigation("Maps"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Sledgemapper.Api/Migrations/20210901223606_uniquesessionindex.cs b/Sledgemapper.Api/Migrations/20210901223606_uniquesessionindex.cs new file mode 100644 index 0000000..e56f5ae --- /dev/null +++ b/Sledgemapper.Api/Migrations/20210901223606_uniquesessionindex.cs @@ -0,0 +1,32 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Sledgemapper.Api.Migrations +{ + public partial class uniquesessionindex : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_Sessions_CampaignId", + table: "Sessions"); + + migrationBuilder.CreateIndex( + name: "IX_Sessions_CampaignId_SessionId", + table: "Sessions", + columns: new[] { "CampaignId", "SessionId" }, + unique: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_Sessions_CampaignId_SessionId", + table: "Sessions"); + + migrationBuilder.CreateIndex( + name: "IX_Sessions_CampaignId", + table: "Sessions", + column: "CampaignId"); + } + } +} diff --git a/Sledgemapper.Api/Migrations/20210901224103_uniquesessionnameindex.Designer.cs b/Sledgemapper.Api/Migrations/20210901224103_uniquesessionnameindex.Designer.cs new file mode 100644 index 0000000..0d469c7 --- /dev/null +++ b/Sledgemapper.Api/Migrations/20210901224103_uniquesessionnameindex.Designer.cs @@ -0,0 +1,508 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Sledgemapper.Api.Infrastructure.Data; + +namespace Sledgemapper.Api.Migrations +{ + [DbContext(typeof(SledgemapperDbContext))] + [Migration("20210901224103_uniquesessionnameindex")] + partial class uniquesessionnameindex + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "5.0.6"); + + modelBuilder.Entity("CampaignUser", b => + { + b.Property("CampaignsCampaignId") + .HasColumnType("TEXT"); + + b.Property("InvitedUsersId") + .HasColumnType("TEXT"); + + b.HasKey("CampaignsCampaignId", "InvitedUsersId"); + + b.HasIndex("InvitedUsersId"); + + b.ToTable("CampaignUser"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.Property("CampaignId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CampaignName") + .HasColumnType("TEXT"); + + b.Property("OwnerId") + .HasColumnType("TEXT"); + + b.HasKey("CampaignId"); + + b.HasIndex("OwnerId"); + + b.HasIndex("CampaignName", "OwnerId") + .IsUnique(); + + b.ToTable("Campaigns"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Map", b => + { + b.Property("MapId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CampaignId") + .HasColumnType("INTEGER"); + + b.Property("MapName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("MapId"); + + b.ToTable("Maps"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.MapLog", b => + { + b.Property("MapLogId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Object") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("Operation") + .IsRequired() + .HasMaxLength(1) + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("Timestamp") + .HasColumnType("REAL"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("MapLogId"); + + b.ToTable("MapLogs"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Session", b => + { + b.Property("SessionId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CampaignId") + .HasColumnType("TEXT"); + + b.Property("OwnerUserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SessionName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("SessionId"); + + b.HasIndex("CampaignId", "SessionName") + .IsUnique(); + + b.ToTable("Sessions"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.SessionUser", b => + { + b.Property("SessionUserId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("SessionUserId"); + + b.ToTable("SessionUsers"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Snapshot", b => + { + b.Property("SnapshotId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Object") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasColumnType("INTEGER"); + + b.Property("Timestamp") + .HasColumnType("REAL"); + + b.HasKey("SnapshotId"); + + b.ToTable("Snapshots"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.UserConnection", b => + { + b.Property("UserConnectionId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConnectionId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("UserConnectionId"); + + b.ToTable("UserConnections"); + }); + + modelBuilder.Entity("Sledgemapper.Entities.User", b => + { + b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityUser"); + + b.Property("FirstName") + .HasColumnType("TEXT"); + + b.Property("Initials") + .HasColumnType("TEXT"); + + b.Property("LastName") + .HasColumnType("TEXT"); + + b.Property("PasswordSalt") + .HasColumnType("BLOB"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("CampaignUser", b => + { + b.HasOne("Sledgemapper.Api.Core.Entities.Campaign", null) + .WithMany() + .HasForeignKey("CampaignsCampaignId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Sledgemapper.Entities.User", null) + .WithMany() + .HasForeignKey("InvitedUsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.HasOne("Sledgemapper.Entities.User", "Owner") + .WithMany() + .HasForeignKey("OwnerId"); + + b.Navigation("Owner"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Session", b => + { + b.HasOne("Sledgemapper.Api.Core.Entities.Campaign", null) + .WithMany("Maps") + .HasForeignKey("CampaignId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Entities.User", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithOne() + .HasForeignKey("Sledgemapper.Entities.User", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.Navigation("Maps"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Sledgemapper.Api/Migrations/20210901224103_uniquesessionnameindex.cs b/Sledgemapper.Api/Migrations/20210901224103_uniquesessionnameindex.cs new file mode 100644 index 0000000..3dc4508 --- /dev/null +++ b/Sledgemapper.Api/Migrations/20210901224103_uniquesessionnameindex.cs @@ -0,0 +1,33 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Sledgemapper.Api.Migrations +{ + public partial class uniquesessionnameindex : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_Sessions_CampaignId_SessionId", + table: "Sessions"); + + migrationBuilder.CreateIndex( + name: "IX_Sessions_CampaignId_SessionName", + table: "Sessions", + columns: new[] { "CampaignId", "SessionName" }, + unique: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_Sessions_CampaignId_SessionName", + table: "Sessions"); + + migrationBuilder.CreateIndex( + name: "IX_Sessions_CampaignId_SessionId", + table: "Sessions", + columns: new[] { "CampaignId", "SessionId" }, + unique: true); + } + } +} diff --git a/Sledgemapper.Api/Migrations/20210916154553_SessionIdToGuid.Designer.cs b/Sledgemapper.Api/Migrations/20210916154553_SessionIdToGuid.Designer.cs new file mode 100644 index 0000000..1b1ec88 --- /dev/null +++ b/Sledgemapper.Api/Migrations/20210916154553_SessionIdToGuid.Designer.cs @@ -0,0 +1,508 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Sledgemapper.Api.Infrastructure.Data; + +namespace Sledgemapper.Api.Migrations +{ + [DbContext(typeof(SledgemapperDbContext))] + [Migration("20210916154553_SessionIdToGuid")] + partial class SessionIdToGuid + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "5.0.6"); + + modelBuilder.Entity("CampaignUser", b => + { + b.Property("CampaignsCampaignId") + .HasColumnType("TEXT"); + + b.Property("InvitedUsersId") + .HasColumnType("TEXT"); + + b.HasKey("CampaignsCampaignId", "InvitedUsersId"); + + b.HasIndex("InvitedUsersId"); + + b.ToTable("CampaignUser"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.Property("CampaignId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CampaignName") + .HasColumnType("TEXT"); + + b.Property("OwnerId") + .HasColumnType("TEXT"); + + b.HasKey("CampaignId"); + + b.HasIndex("OwnerId"); + + b.HasIndex("CampaignName", "OwnerId") + .IsUnique(); + + b.ToTable("Campaigns"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Map", b => + { + b.Property("MapId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CampaignId") + .HasColumnType("INTEGER"); + + b.Property("MapName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("MapId"); + + b.ToTable("Maps"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.MapLog", b => + { + b.Property("MapLogId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Object") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("Operation") + .IsRequired() + .HasMaxLength(1) + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasColumnType("TEXT"); + + b.Property("Timestamp") + .HasColumnType("REAL"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("MapLogId"); + + b.ToTable("MapLogs"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Session", b => + { + b.Property("SessionId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CampaignId") + .HasColumnType("TEXT"); + + b.Property("OwnerUserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SessionName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("SessionId"); + + b.HasIndex("CampaignId", "SessionName") + .IsUnique(); + + b.ToTable("Sessions"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.SessionUser", b => + { + b.Property("SessionUserId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("SessionId") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("SessionUserId"); + + b.ToTable("SessionUsers"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Snapshot", b => + { + b.Property("SnapshotId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Object") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasColumnType("TEXT"); + + b.Property("Timestamp") + .HasColumnType("REAL"); + + b.HasKey("SnapshotId"); + + b.ToTable("Snapshots"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.UserConnection", b => + { + b.Property("UserConnectionId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConnectionId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("UserConnectionId"); + + b.ToTable("UserConnections"); + }); + + modelBuilder.Entity("Sledgemapper.Entities.User", b => + { + b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityUser"); + + b.Property("FirstName") + .HasColumnType("TEXT"); + + b.Property("Initials") + .HasColumnType("TEXT"); + + b.Property("LastName") + .HasColumnType("TEXT"); + + b.Property("PasswordSalt") + .HasColumnType("BLOB"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("CampaignUser", b => + { + b.HasOne("Sledgemapper.Api.Core.Entities.Campaign", null) + .WithMany() + .HasForeignKey("CampaignsCampaignId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Sledgemapper.Entities.User", null) + .WithMany() + .HasForeignKey("InvitedUsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.HasOne("Sledgemapper.Entities.User", "Owner") + .WithMany() + .HasForeignKey("OwnerId"); + + b.Navigation("Owner"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Session", b => + { + b.HasOne("Sledgemapper.Api.Core.Entities.Campaign", null) + .WithMany("Maps") + .HasForeignKey("CampaignId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Entities.User", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithOne() + .HasForeignKey("Sledgemapper.Entities.User", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.Navigation("Maps"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Sledgemapper.Api/Migrations/20210916154553_SessionIdToGuid.cs b/Sledgemapper.Api/Migrations/20210916154553_SessionIdToGuid.cs new file mode 100644 index 0000000..7d7fcca --- /dev/null +++ b/Sledgemapper.Api/Migrations/20210916154553_SessionIdToGuid.cs @@ -0,0 +1,80 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Sledgemapper.Api.Migrations +{ + public partial class SessionIdToGuid : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "SessionId", + table: "Snapshots", + type: "TEXT", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AlterColumn( + name: "SessionId", + table: "SessionUsers", + type: "TEXT", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AlterColumn( + name: "SessionId", + table: "Sessions", + type: "TEXT", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER") + .OldAnnotation("Sqlite:Autoincrement", true); + + migrationBuilder.AlterColumn( + name: "SessionId", + table: "MapLogs", + type: "TEXT", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "SessionId", + table: "Snapshots", + type: "INTEGER", + nullable: false, + oldClrType: typeof(Guid), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "SessionId", + table: "SessionUsers", + type: "INTEGER", + nullable: false, + oldClrType: typeof(Guid), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "SessionId", + table: "Sessions", + type: "INTEGER", + nullable: false, + oldClrType: typeof(Guid), + oldType: "TEXT") + .Annotation("Sqlite:Autoincrement", true); + + migrationBuilder.AlterColumn( + name: "SessionId", + table: "MapLogs", + type: "INTEGER", + nullable: false, + oldClrType: typeof(Guid), + oldType: "TEXT"); + } + } +} diff --git a/Sledgemapper.Api/Migrations/20210917091001_SessionIdToGuidAuto.Designer.cs b/Sledgemapper.Api/Migrations/20210917091001_SessionIdToGuidAuto.Designer.cs new file mode 100644 index 0000000..78a2012 --- /dev/null +++ b/Sledgemapper.Api/Migrations/20210917091001_SessionIdToGuidAuto.Designer.cs @@ -0,0 +1,508 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Sledgemapper.Api.Infrastructure.Data; + +namespace Sledgemapper.Api.Migrations +{ + [DbContext(typeof(SledgemapperDbContext))] + [Migration("20210917091001_SessionIdToGuidAuto")] + partial class SessionIdToGuidAuto + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "5.0.6"); + + modelBuilder.Entity("CampaignUser", b => + { + b.Property("CampaignsCampaignId") + .HasColumnType("TEXT"); + + b.Property("InvitedUsersId") + .HasColumnType("TEXT"); + + b.HasKey("CampaignsCampaignId", "InvitedUsersId"); + + b.HasIndex("InvitedUsersId"); + + b.ToTable("CampaignUser"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.Property("CampaignId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CampaignName") + .HasColumnType("TEXT"); + + b.Property("OwnerId") + .HasColumnType("TEXT"); + + b.HasKey("CampaignId"); + + b.HasIndex("OwnerId"); + + b.HasIndex("CampaignName", "OwnerId") + .IsUnique(); + + b.ToTable("Campaigns"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Map", b => + { + b.Property("MapId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CampaignId") + .HasColumnType("INTEGER"); + + b.Property("MapName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("MapId"); + + b.ToTable("Maps"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.MapLog", b => + { + b.Property("MapLogId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Object") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("Operation") + .IsRequired() + .HasMaxLength(1) + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasColumnType("TEXT"); + + b.Property("Timestamp") + .HasColumnType("REAL"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("MapLogId"); + + b.ToTable("MapLogs"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Session", b => + { + b.Property("SessionId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CampaignId") + .HasColumnType("TEXT"); + + b.Property("OwnerUserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SessionName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("SessionId"); + + b.HasIndex("CampaignId", "SessionName") + .IsUnique(); + + b.ToTable("Sessions"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.SessionUser", b => + { + b.Property("SessionUserId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("SessionId") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("SessionUserId"); + + b.ToTable("SessionUsers"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Snapshot", b => + { + b.Property("SnapshotId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Object") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasColumnType("TEXT"); + + b.Property("Timestamp") + .HasColumnType("REAL"); + + b.HasKey("SnapshotId"); + + b.ToTable("Snapshots"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.UserConnection", b => + { + b.Property("UserConnectionId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConnectionId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("UserConnectionId"); + + b.ToTable("UserConnections"); + }); + + modelBuilder.Entity("Sledgemapper.Entities.User", b => + { + b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityUser"); + + b.Property("FirstName") + .HasColumnType("TEXT"); + + b.Property("Initials") + .HasColumnType("TEXT"); + + b.Property("LastName") + .HasColumnType("TEXT"); + + b.Property("PasswordSalt") + .HasColumnType("BLOB"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("CampaignUser", b => + { + b.HasOne("Sledgemapper.Api.Core.Entities.Campaign", null) + .WithMany() + .HasForeignKey("CampaignsCampaignId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Sledgemapper.Entities.User", null) + .WithMany() + .HasForeignKey("InvitedUsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.HasOne("Sledgemapper.Entities.User", "Owner") + .WithMany() + .HasForeignKey("OwnerId"); + + b.Navigation("Owner"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Session", b => + { + b.HasOne("Sledgemapper.Api.Core.Entities.Campaign", null) + .WithMany("Maps") + .HasForeignKey("CampaignId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Entities.User", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithOne() + .HasForeignKey("Sledgemapper.Entities.User", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.Navigation("Maps"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Sledgemapper.Api/Migrations/20210917091001_SessionIdToGuidAuto.cs b/Sledgemapper.Api/Migrations/20210917091001_SessionIdToGuidAuto.cs new file mode 100644 index 0000000..25382c0 --- /dev/null +++ b/Sledgemapper.Api/Migrations/20210917091001_SessionIdToGuidAuto.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Sledgemapper.Api.Migrations +{ + public partial class SessionIdToGuidAuto : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/Sledgemapper.Api/Migrations/20210917112525_UserIdGuid.Designer.cs b/Sledgemapper.Api/Migrations/20210917112525_UserIdGuid.Designer.cs new file mode 100644 index 0000000..6f3ecc9 --- /dev/null +++ b/Sledgemapper.Api/Migrations/20210917112525_UserIdGuid.Designer.cs @@ -0,0 +1,508 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Sledgemapper.Api.Infrastructure.Data; + +namespace Sledgemapper.Api.Migrations +{ + [DbContext(typeof(SledgemapperDbContext))] + [Migration("20210917112525_UserIdGuid")] + partial class UserIdGuid + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "5.0.6"); + + modelBuilder.Entity("CampaignUser", b => + { + b.Property("CampaignsCampaignId") + .HasColumnType("TEXT"); + + b.Property("InvitedUsersId") + .HasColumnType("TEXT"); + + b.HasKey("CampaignsCampaignId", "InvitedUsersId"); + + b.HasIndex("InvitedUsersId"); + + b.ToTable("CampaignUser"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.Property("CampaignId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CampaignName") + .HasColumnType("TEXT"); + + b.Property("OwnerId") + .HasColumnType("TEXT"); + + b.HasKey("CampaignId"); + + b.HasIndex("OwnerId"); + + b.HasIndex("CampaignName", "OwnerId") + .IsUnique(); + + b.ToTable("Campaigns"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Map", b => + { + b.Property("MapId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CampaignId") + .HasColumnType("INTEGER"); + + b.Property("MapName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("MapId"); + + b.ToTable("Maps"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.MapLog", b => + { + b.Property("MapLogId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Object") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("Operation") + .IsRequired() + .HasMaxLength(1) + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasColumnType("TEXT"); + + b.Property("Timestamp") + .HasColumnType("REAL"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("MapLogId"); + + b.ToTable("MapLogs"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Session", b => + { + b.Property("SessionId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CampaignId") + .HasColumnType("TEXT"); + + b.Property("OwnerUserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SessionName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("SessionId"); + + b.HasIndex("CampaignId", "SessionName") + .IsUnique(); + + b.ToTable("Sessions"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.SessionUser", b => + { + b.Property("SessionUserId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("SessionId") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("SessionUserId"); + + b.ToTable("SessionUsers"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Snapshot", b => + { + b.Property("SnapshotId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Object") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasColumnType("TEXT"); + + b.Property("Timestamp") + .HasColumnType("REAL"); + + b.HasKey("SnapshotId"); + + b.ToTable("Snapshots"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.UserConnection", b => + { + b.Property("UserConnectionId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConnectionId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("UserConnectionId"); + + b.ToTable("UserConnections"); + }); + + modelBuilder.Entity("Sledgemapper.Entities.User", b => + { + b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityUser"); + + b.Property("FirstName") + .HasColumnType("TEXT"); + + b.Property("Initials") + .HasColumnType("TEXT"); + + b.Property("LastName") + .HasColumnType("TEXT"); + + b.Property("PasswordSalt") + .HasColumnType("BLOB"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("CampaignUser", b => + { + b.HasOne("Sledgemapper.Api.Core.Entities.Campaign", null) + .WithMany() + .HasForeignKey("CampaignsCampaignId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Sledgemapper.Entities.User", null) + .WithMany() + .HasForeignKey("InvitedUsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.HasOne("Sledgemapper.Entities.User", "Owner") + .WithMany() + .HasForeignKey("OwnerId"); + + b.Navigation("Owner"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Session", b => + { + b.HasOne("Sledgemapper.Api.Core.Entities.Campaign", null) + .WithMany("Maps") + .HasForeignKey("CampaignId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Entities.User", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithOne() + .HasForeignKey("Sledgemapper.Entities.User", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.Navigation("Maps"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Sledgemapper.Api/Migrations/20210917112525_UserIdGuid.cs b/Sledgemapper.Api/Migrations/20210917112525_UserIdGuid.cs new file mode 100644 index 0000000..4a28622 --- /dev/null +++ b/Sledgemapper.Api/Migrations/20210917112525_UserIdGuid.cs @@ -0,0 +1,46 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Sledgemapper.Api.Migrations +{ + public partial class UserIdGuid : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "UserId", + table: "UserConnections", + type: "TEXT", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AlterColumn( + name: "UserId", + table: "SessionUsers", + type: "TEXT", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "UserId", + table: "UserConnections", + type: "INTEGER", + nullable: false, + oldClrType: typeof(Guid), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "UserId", + table: "SessionUsers", + type: "INTEGER", + nullable: false, + oldClrType: typeof(Guid), + oldType: "TEXT"); + } + } +} diff --git a/Sledgemapper.Api/Migrations/SledgemapperDbContextModelSnapshot.cs b/Sledgemapper.Api/Migrations/SledgemapperDbContextModelSnapshot.cs new file mode 100644 index 0000000..a477060 --- /dev/null +++ b/Sledgemapper.Api/Migrations/SledgemapperDbContextModelSnapshot.cs @@ -0,0 +1,506 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Sledgemapper.Api.Infrastructure.Data; + +namespace Sledgemapper.Api.Migrations +{ + [DbContext(typeof(SledgemapperDbContext))] + partial class SledgemapperDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "5.0.6"); + + modelBuilder.Entity("CampaignUser", b => + { + b.Property("CampaignsCampaignId") + .HasColumnType("TEXT"); + + b.Property("InvitedUsersId") + .HasColumnType("TEXT"); + + b.HasKey("CampaignsCampaignId", "InvitedUsersId"); + + b.HasIndex("InvitedUsersId"); + + b.ToTable("CampaignUser"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.Property("CampaignId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CampaignName") + .HasColumnType("TEXT"); + + b.Property("OwnerId") + .HasColumnType("TEXT"); + + b.HasKey("CampaignId"); + + b.HasIndex("OwnerId"); + + b.HasIndex("CampaignName", "OwnerId") + .IsUnique(); + + b.ToTable("Campaigns"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Map", b => + { + b.Property("MapId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CampaignId") + .HasColumnType("INTEGER"); + + b.Property("MapName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("MapId"); + + b.ToTable("Maps"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.MapLog", b => + { + b.Property("MapLogId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Object") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("Operation") + .IsRequired() + .HasMaxLength(1) + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasColumnType("TEXT"); + + b.Property("Timestamp") + .HasColumnType("REAL"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("MapLogId"); + + b.ToTable("MapLogs"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Session", b => + { + b.Property("SessionId") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CampaignId") + .HasColumnType("TEXT"); + + b.Property("OwnerUserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SessionName") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("SessionId"); + + b.HasIndex("CampaignId", "SessionName") + .IsUnique(); + + b.ToTable("Sessions"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.SessionUser", b => + { + b.Property("SessionUserId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("SessionId") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("SessionUserId"); + + b.ToTable("SessionUsers"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Snapshot", b => + { + b.Property("SnapshotId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Object") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SessionId") + .HasColumnType("TEXT"); + + b.Property("Timestamp") + .HasColumnType("REAL"); + + b.HasKey("SnapshotId"); + + b.ToTable("Snapshots"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.UserConnection", b => + { + b.Property("UserConnectionId") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConnectionId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("UserConnectionId"); + + b.ToTable("UserConnections"); + }); + + modelBuilder.Entity("Sledgemapper.Entities.User", b => + { + b.HasBaseType("Microsoft.AspNetCore.Identity.IdentityUser"); + + b.Property("FirstName") + .HasColumnType("TEXT"); + + b.Property("Initials") + .HasColumnType("TEXT"); + + b.Property("LastName") + .HasColumnType("TEXT"); + + b.Property("PasswordSalt") + .HasColumnType("BLOB"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("CampaignUser", b => + { + b.HasOne("Sledgemapper.Api.Core.Entities.Campaign", null) + .WithMany() + .HasForeignKey("CampaignsCampaignId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Sledgemapper.Entities.User", null) + .WithMany() + .HasForeignKey("InvitedUsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.HasOne("Sledgemapper.Entities.User", "Owner") + .WithMany() + .HasForeignKey("OwnerId"); + + b.Navigation("Owner"); + }); + + modelBuilder.Entity("Sledgemapper.Api.Models.Session", b => + { + b.HasOne("Sledgemapper.Api.Core.Entities.Campaign", null) + .WithMany("Maps") + .HasForeignKey("CampaignId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Entities.User", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + .WithOne() + .HasForeignKey("Sledgemapper.Entities.User", "Id") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Sledgemapper.Api.Core.Entities.Campaign", b => + { + b.Navigation("Maps"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Sledgemapper.Api/Migrations/SqlServerMigrations/20200102103423_InitialCreate.Designer.cs b/Sledgemapper.Api/Migrations/SqlServerMigrations/20200102103423_InitialCreate.Designer.cs deleted file mode 100644 index 1d57dc6..0000000 --- a/Sledgemapper.Api/Migrations/SqlServerMigrations/20200102103423_InitialCreate.Designer.cs +++ /dev/null @@ -1,53 +0,0 @@ -// // -// using System; -// using Microsoft.EntityFrameworkCore; -// using Microsoft.EntityFrameworkCore.Infrastructure; -// using Microsoft.EntityFrameworkCore.Metadata; -// using Microsoft.EntityFrameworkCore.Migrations; -// using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -// using Sledgemapper.Helpers; - -// namespace Sledgemapper.Migrations.SqlServerMigrations -// { -// [DbContext(typeof(DataContext))] -// [Migration("20200102103423_InitialCreate")] -// partial class InitialCreate -// { -// protected override void BuildTargetModel(ModelBuilder modelBuilder) -// { -// #pragma warning disable 612, 618 -// modelBuilder -// .HasAnnotation("ProductVersion", "3.1.0") -// .HasAnnotation("Relational:MaxIdentifierLength", 128) -// .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - -// modelBuilder.Entity("Sledgemapper.Entities.User", b => -// { -// b.Property("Id") -// .ValueGeneratedOnAdd() -// .HasColumnType("int") -// .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - -// b.Property("FirstName") -// .HasColumnType("nvarchar(max)"); - -// b.Property("LastName") -// .HasColumnType("nvarchar(max)"); - -// b.Property("PasswordHash") -// .HasColumnType("varbinary(max)"); - -// b.Property("PasswordSalt") -// .HasColumnType("varbinary(max)"); - -// b.Property("Username") -// .HasColumnType("nvarchar(max)"); - -// b.HasKey("Id"); - -// b.ToTable("Users"); -// }); -// #pragma warning restore 612, 618 -// } -// } -// } diff --git a/Sledgemapper.Api/Migrations/SqlServerMigrations/20200102103423_InitialCreate.cs b/Sledgemapper.Api/Migrations/SqlServerMigrations/20200102103423_InitialCreate.cs deleted file mode 100644 index cae048f..0000000 --- a/Sledgemapper.Api/Migrations/SqlServerMigrations/20200102103423_InitialCreate.cs +++ /dev/null @@ -1,33 +0,0 @@ -// using Microsoft.EntityFrameworkCore.Migrations; - -// namespace Sledgemapper.Migrations.SqlServerMigrations -// { -// public partial class InitialCreate : Migration -// { -// protected override void Up(MigrationBuilder migrationBuilder) -// { -// migrationBuilder.CreateTable( -// name: "Users", -// columns: table => new -// { -// Id = table.Column(nullable: false) -// .Annotation("SqlServer:Identity", "1, 1"), -// FirstName = table.Column(nullable: true), -// LastName = table.Column(nullable: true), -// Username = table.Column(nullable: true), -// PasswordHash = table.Column(nullable: true), -// PasswordSalt = table.Column(nullable: true) -// }, -// constraints: table => -// { -// table.PrimaryKey("PK_Users", x => x.Id); -// }); -// } - -// protected override void Down(MigrationBuilder migrationBuilder) -// { -// migrationBuilder.DropTable( -// name: "Users"); -// } -// } -// } diff --git a/Sledgemapper.Api/Migrations/SqlServerMigrations/DataContextModelSnapshot.cs b/Sledgemapper.Api/Migrations/SqlServerMigrations/DataContextModelSnapshot.cs deleted file mode 100644 index d481d75..0000000 --- a/Sledgemapper.Api/Migrations/SqlServerMigrations/DataContextModelSnapshot.cs +++ /dev/null @@ -1,51 +0,0 @@ -// // -// using System; -// using Microsoft.EntityFrameworkCore; -// using Microsoft.EntityFrameworkCore.Infrastructure; -// using Microsoft.EntityFrameworkCore.Metadata; -// using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -// using Sledgemapper.Helpers; - -// namespace Sledgemapper.Migrations.SqlServerMigrations -// { -// [DbContext(typeof(DataContext))] -// partial class DataContextModelSnapshot : ModelSnapshot -// { -// protected override void BuildModel(ModelBuilder modelBuilder) -// { -// #pragma warning disable 612, 618 -// modelBuilder -// .HasAnnotation("ProductVersion", "3.1.0") -// .HasAnnotation("Relational:MaxIdentifierLength", 128) -// .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - -// modelBuilder.Entity("Sledgemapper.Entities.User", b => -// { -// b.Property("Id") -// .ValueGeneratedOnAdd() -// .HasColumnType("int") -// .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - -// b.Property("FirstName") -// .HasColumnType("nvarchar(max)"); - -// b.Property("LastName") -// .HasColumnType("nvarchar(max)"); - -// b.Property("PasswordHash") -// .HasColumnType("varbinary(max)"); - -// b.Property("PasswordSalt") -// .HasColumnType("varbinary(max)"); - -// b.Property("Username") -// .HasColumnType("nvarchar(max)"); - -// b.HasKey("Id"); - -// b.ToTable("Users"); -// }); -// #pragma warning restore 612, 618 -// } -// } -// } diff --git a/Sledgemapper.Api/Migrations/SqliteMigrations/20200102102942_InitialCreate.Designer.cs b/Sledgemapper.Api/Migrations/SqliteMigrations/20200102102942_InitialCreate.Designer.cs deleted file mode 100644 index 1bf96db..0000000 --- a/Sledgemapper.Api/Migrations/SqliteMigrations/20200102102942_InitialCreate.Designer.cs +++ /dev/null @@ -1,52 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Sledgemapper.Helpers; - -namespace Sledgemapper.Migrations.SqliteMigrations -{ - [DbContext(typeof(SqliteDataContext))] - [Migration("20200102102942_InitialCreate")] - partial class InitialCreate - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "3.1.0"); - - modelBuilder.Entity("Sledgemapper.Entities.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("FirstName") - .HasColumnType("TEXT"); - - b.Property("LastName") - .HasColumnType("TEXT"); - - b.Property("Initials") - .HasColumnType("TEXT"); - - b.Property("PasswordHash") - .HasColumnType("BLOB"); - - b.Property("PasswordSalt") - .HasColumnType("BLOB"); - - b.Property("Username") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.ToTable("Users"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Sledgemapper.Api/Migrations/SqliteMigrations/20200102102942_InitialCreate.cs b/Sledgemapper.Api/Migrations/SqliteMigrations/20200102102942_InitialCreate.cs deleted file mode 100644 index 65b8fc1..0000000 --- a/Sledgemapper.Api/Migrations/SqliteMigrations/20200102102942_InitialCreate.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -namespace Sledgemapper.Migrations.SqliteMigrations -{ - public partial class InitialCreate : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "Users", - columns: table => new - { - Id = table.Column(nullable: false) - .Annotation("Sqlite:Autoincrement", true), - FirstName = table.Column(nullable: true), - LastName = table.Column(nullable: true), - Username = table.Column(nullable: true), - Initials = table.Column(nullable: true), - PasswordHash = table.Column(nullable: true), - PasswordSalt = table.Column(nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Users", x => x.Id); - }); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "Users"); - } - } -} diff --git a/Sledgemapper.Api/Migrations/SqliteMigrations/SqliteDataContextModelSnapshot.cs b/Sledgemapper.Api/Migrations/SqliteMigrations/SqliteDataContextModelSnapshot.cs deleted file mode 100644 index d1eab3f..0000000 --- a/Sledgemapper.Api/Migrations/SqliteMigrations/SqliteDataContextModelSnapshot.cs +++ /dev/null @@ -1,50 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Sledgemapper.Helpers; - -namespace Sledgemapper.Migrations.SqliteMigrations -{ - [DbContext(typeof(SqliteDataContext))] - partial class SqliteDataContextModelSnapshot : ModelSnapshot - { - protected override void BuildModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "3.1.0"); - - modelBuilder.Entity("Sledgemapper.Entities.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("FirstName") - .HasColumnType("TEXT"); - - b.Property("LastName") - .HasColumnType("TEXT"); - - b.Property("Initials") - .HasColumnType("TEXT"); - - b.Property("PasswordHash") - .HasColumnType("BLOB"); - - b.Property("PasswordSalt") - .HasColumnType("BLOB"); - - b.Property("Username") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.ToTable("Users"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Sledgemapper.Api/Models copy/Users/UpdateModel.cs b/Sledgemapper.Api/Models copy/Users/UpdateModel.cs deleted file mode 100644 index fb421f7..0000000 --- a/Sledgemapper.Api/Models copy/Users/UpdateModel.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Sledgemapper.Models.Users -{ - public class UpdateModel - { - public string FirstName { get; set; } - public string LastName { get; set; } - public string Username { get; set; } - public string Password { get; set; } - } -} \ No newline at end of file diff --git a/Sledgemapper.Api/Models copy/Users/UserModel.cs b/Sledgemapper.Api/Models copy/Users/UserModel.cs deleted file mode 100644 index c1bb502..0000000 --- a/Sledgemapper.Api/Models copy/Users/UserModel.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Sledgemapper.Models.Users -{ - public class UserModel - { - public int Id { get; set; } - public string FirstName { get; set; } - public string LastName { get; set; } - public string Username { get; set; } - public string Initials { get; set; } - } -} \ No newline at end of file diff --git a/Sledgemapper.Api/Models/AuthResult.cs b/Sledgemapper.Api/Models/AuthResult.cs new file mode 100644 index 0000000..cf42c6a --- /dev/null +++ b/Sledgemapper.Api/Models/AuthResult.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; + +namespace Sledgemapper.Api.Models +{ + public class AuthResult + { + public string Token { get; set; } + public bool Result { get; set; } + public List Errors { get; set; } + } +} \ No newline at end of file diff --git a/Sledgemapper.Api/Models copy/Users/AuthenticateModel.cs b/Sledgemapper.Api/Models/AuthenticateModel.cs similarity index 86% rename from Sledgemapper.Api/Models copy/Users/AuthenticateModel.cs rename to Sledgemapper.Api/Models/AuthenticateModel.cs index f164138..48e743f 100644 --- a/Sledgemapper.Api/Models copy/Users/AuthenticateModel.cs +++ b/Sledgemapper.Api/Models/AuthenticateModel.cs @@ -1,6 +1,6 @@ using System.ComponentModel.DataAnnotations; -namespace Sledgemapper.Models.Users +namespace Sledgemapper.Api.Models { public class AuthenticateModel { diff --git a/Sledgemapper.Api/Models/LoginResponse.cs b/Sledgemapper.Api/Models/LoginResponse.cs new file mode 100644 index 0000000..03d7fd5 --- /dev/null +++ b/Sledgemapper.Api/Models/LoginResponse.cs @@ -0,0 +1,9 @@ +namespace Sledgemapper.Api.Models +{ + public class LoginResponse : AuthResult + { + public string Username { get; set; } + public string Initials { get; set; } + public string Id { get; internal set; } + } +} \ No newline at end of file diff --git a/Sledgemapper.Api/Models copy/Users/RegisterModel.cs b/Sledgemapper.Api/Models/RegisterModel.cs similarity index 72% rename from Sledgemapper.Api/Models copy/Users/RegisterModel.cs rename to Sledgemapper.Api/Models/RegisterModel.cs index 98e3af3..646a3f3 100644 --- a/Sledgemapper.Api/Models copy/Users/RegisterModel.cs +++ b/Sledgemapper.Api/Models/RegisterModel.cs @@ -1,21 +1,23 @@ using System.ComponentModel.DataAnnotations; -namespace Sledgemapper.Models.Users +namespace Sledgemapper.Api.Models { public class RegisterModel { [Required] public string FirstName { get; set; } + [Required] + public string UserName { get; set; } [Required] public string LastName { get; set; } [Required] - public string Username { get; set; } + public string Email { get; set; } [Required] public string Password { get; set; } - + [Required] public string Initials { get; set; } } diff --git a/Sledgemapper.Api/Models/RegistrationResponse.cs b/Sledgemapper.Api/Models/RegistrationResponse.cs new file mode 100644 index 0000000..6f9a61f --- /dev/null +++ b/Sledgemapper.Api/Models/RegistrationResponse.cs @@ -0,0 +1,7 @@ +namespace Sledgemapper.Api.Models +{ + public class RegistrationResponse : AuthResult + { + + } +} \ No newline at end of file diff --git a/Sledgemapper.Api/Models/Session.cs b/Sledgemapper.Api/Models/Session.cs deleted file mode 100644 index ac1d57c..0000000 --- a/Sledgemapper.Api/Models/Session.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace Sledgemapper.Api.Models -{ - public class Session - { - [Key] - public int SessionId { get; set; } - - [Required] - public string SessionName{get;set;} - - [Required] - public int OwnerUserId { get; set; } - } -} diff --git a/Sledgemapper.Api/Models/UserLoginRequest.cs b/Sledgemapper.Api/Models/UserLoginRequest.cs new file mode 100644 index 0000000..3a2a152 --- /dev/null +++ b/Sledgemapper.Api/Models/UserLoginRequest.cs @@ -0,0 +1,12 @@ +using System.ComponentModel.DataAnnotations; + +namespace Sledgemapper.Api.Models +{ + public class UserLoginRequest + { + [Required] + public string Email { get; set; } + [Required] + public string Password { get; set; } + } +} \ No newline at end of file diff --git a/Sledgemapper.Api/Notifications/BaseNotification.cs b/Sledgemapper.Api/Notifications/BaseNotification.cs index a577ce8..7786bdf 100644 --- a/Sledgemapper.Api/Notifications/BaseNotification.cs +++ b/Sledgemapper.Api/Notifications/BaseNotification.cs @@ -1,16 +1,17 @@ using MediatR; using System; +using Sledgemapper.Api.Core.Entities; namespace Sledgemapper.Api.Notifications { public abstract class BaseNotification : INotification { public double Timestamp { get; private set; } - public int UserId { get; private set; } + public string UserId { get; private set; } public int SessionId { get; set; } - public Models.Session Session { get; set; } + public Session Session { get; set; } - public BaseNotification(Models.Session session, int userId) + public BaseNotification(Session session, string userId) { Timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds(); Session = session; ; diff --git a/Sledgemapper.Api/Notifications/DeleteNoteNotification.cs b/Sledgemapper.Api/Notifications/DeleteNoteNotification.cs index 1052f6e..3b5fb5f 100644 --- a/Sledgemapper.Api/Notifications/DeleteNoteNotification.cs +++ b/Sledgemapper.Api/Notifications/DeleteNoteNotification.cs @@ -1,4 +1,5 @@ using Sledgemapper.Shared.Entities; +using Session = Sledgemapper.Api.Core.Entities.Session; namespace Sledgemapper.Api.Notifications { @@ -6,7 +7,7 @@ namespace Sledgemapper.Api.Notifications { public Note Note { get; private set; } - public DeleteNoteNotification(Models.Session session, Note note, int userId) : base(session, userId) + public DeleteNoteNotification(Session session, Note note, string userId) : base(session, userId) { Note = note; } diff --git a/Sledgemapper.Api/Notifications/DeleteOverlayNotification.cs b/Sledgemapper.Api/Notifications/DeleteOverlayNotification.cs index 6673611..d246d94 100644 --- a/Sledgemapper.Api/Notifications/DeleteOverlayNotification.cs +++ b/Sledgemapper.Api/Notifications/DeleteOverlayNotification.cs @@ -1,4 +1,6 @@ using Sledgemapper.Shared.Entities; +using Session = Sledgemapper.Api.Core.Entities.Session; + namespace Sledgemapper.Api.Notifications { @@ -6,7 +8,7 @@ namespace Sledgemapper.Api.Notifications { public Overlay Overlay { get; private set; } - public DeleteOverlayNotification(Models.Session session, Overlay overlay, int userId) : base(session, userId) + public DeleteOverlayNotification(Session session, Overlay overlay, string userId) : base(session, userId) { Overlay = overlay; } diff --git a/Sledgemapper.Api/Notifications/DeleteTileNotification.cs b/Sledgemapper.Api/Notifications/DeleteTileNotification.cs index 8c9a1ff..7533f9c 100644 --- a/Sledgemapper.Api/Notifications/DeleteTileNotification.cs +++ b/Sledgemapper.Api/Notifications/DeleteTileNotification.cs @@ -1,4 +1,6 @@ using Sledgemapper.Shared.Entities; +using Session = Sledgemapper.Api.Core.Entities.Session; + namespace Sledgemapper.Api.Notifications { @@ -6,7 +8,7 @@ namespace Sledgemapper.Api.Notifications { public Tile Tile { get; private set; } - public DeleteTileNotification(Models.Session session, Tile tile, int userId) : base(session, userId) + public DeleteTileNotification(Session session, Tile tile, string userId) : base(session, userId) { Tile = tile; } diff --git a/Sledgemapper.Api/Notifications/DeleteWallNotification.cs b/Sledgemapper.Api/Notifications/DeleteWallNotification.cs index f56a362..ff87cef 100644 --- a/Sledgemapper.Api/Notifications/DeleteWallNotification.cs +++ b/Sledgemapper.Api/Notifications/DeleteWallNotification.cs @@ -1,4 +1,5 @@ using Sledgemapper.Shared.Entities; +using Session = Sledgemapper.Api.Core.Entities.Session; namespace Sledgemapper.Api.Notifications { @@ -6,7 +7,7 @@ namespace Sledgemapper.Api.Notifications { public Wall Wall { get; private set; } - public DeleteWallNotification(Models.Session session, Wall wall, int userId) : base(session, userId) + public DeleteWallNotification(Session session, Wall wall, string userId) : base(session, userId) { Wall = wall; } diff --git a/Sledgemapper.Api/Notifications/NewLineNotification.cs b/Sledgemapper.Api/Notifications/NewLineNotification.cs index 25c3005..881d866 100644 --- a/Sledgemapper.Api/Notifications/NewLineNotification.cs +++ b/Sledgemapper.Api/Notifications/NewLineNotification.cs @@ -1,4 +1,6 @@ using Sledgemapper.Shared.Entities; +using Session = Sledgemapper.Api.Core.Entities.Session; + namespace Sledgemapper.Api.Notifications { @@ -6,7 +8,7 @@ namespace Sledgemapper.Api.Notifications { public Line Line { get; private set; } - public NewLineNotification(Models.Session session, Line line, int userId) : base(session, userId) + public NewLineNotification(Session session, Line line, string userId) : base(session, userId) { Line = line; } diff --git a/Sledgemapper.Api/Notifications/NewNoteNotification.cs b/Sledgemapper.Api/Notifications/NewNoteNotification.cs index bf65b42..301d2f4 100644 --- a/Sledgemapper.Api/Notifications/NewNoteNotification.cs +++ b/Sledgemapper.Api/Notifications/NewNoteNotification.cs @@ -1,4 +1,5 @@ using Sledgemapper.Shared.Entities; +using Session = Sledgemapper.Api.Core.Entities.Session; namespace Sledgemapper.Api.Notifications { @@ -6,7 +7,7 @@ namespace Sledgemapper.Api.Notifications { public Note Note { get; private set; } - public NewNoteNotification(Models.Session session, Note note, int userId) : base(session, userId) + public NewNoteNotification(Session session, Note note, string userId) : base(session, userId) { Note = note; } diff --git a/Sledgemapper.Api/Notifications/NewOverlayNotification.cs b/Sledgemapper.Api/Notifications/NewOverlayNotification.cs index fe5a7a8..34faef4 100644 --- a/Sledgemapper.Api/Notifications/NewOverlayNotification.cs +++ b/Sledgemapper.Api/Notifications/NewOverlayNotification.cs @@ -1,4 +1,5 @@ using Sledgemapper.Shared.Entities; +using Session = Sledgemapper.Api.Core.Entities.Session; namespace Sledgemapper.Api.Notifications { @@ -6,7 +7,7 @@ namespace Sledgemapper.Api.Notifications { public Overlay Overlay { get; private set; } - public NewOverlayNotification(Models.Session session, Overlay overlay, int userId) : base(session, userId) + public NewOverlayNotification(Session session, Overlay overlay, string userId) : base(session, userId) { Overlay = overlay; } diff --git a/Sledgemapper.Api/Notifications/NewRoomNotification.cs b/Sledgemapper.Api/Notifications/NewRoomNotification.cs index d83e27d..36fb484 100644 --- a/Sledgemapper.Api/Notifications/NewRoomNotification.cs +++ b/Sledgemapper.Api/Notifications/NewRoomNotification.cs @@ -1,4 +1,5 @@ using Sledgemapper.Shared.Entities; +using Session = Sledgemapper.Api.Core.Entities.Session; namespace Sledgemapper.Api.Notifications { @@ -6,7 +7,7 @@ namespace Sledgemapper.Api.Notifications { public Room Room { get; private set; } - public NewRoomNotification(Models.Session session, Room room, int userId) : base(session, userId) + public NewRoomNotification(Session session, Room room, string userId) : base(session, userId) { Room = room; } diff --git a/Sledgemapper.Api/Notifications/NewSessionNotification.cs b/Sledgemapper.Api/Notifications/NewSessionNotification.cs index af6bf84..864c923 100644 --- a/Sledgemapper.Api/Notifications/NewSessionNotification.cs +++ b/Sledgemapper.Api/Notifications/NewSessionNotification.cs @@ -1,8 +1,10 @@ +using Sledgemapper.Api.Core.Entities; + namespace Sledgemapper.Api.Notifications { public class NewSessionNotification : BaseNotification { - public NewSessionNotification(string sessionName, int userId) : base(new Models.Session { SessionName = sessionName }, userId) + public NewSessionNotification(string sessionName, string userId) : base(new Session { SessionName = sessionName }, userId) { } } } \ No newline at end of file diff --git a/Sledgemapper.Api/Notifications/NewTileNotification.cs b/Sledgemapper.Api/Notifications/NewTileNotification.cs index 00ae89f..909d677 100644 --- a/Sledgemapper.Api/Notifications/NewTileNotification.cs +++ b/Sledgemapper.Api/Notifications/NewTileNotification.cs @@ -1,4 +1,6 @@ using Sledgemapper.Shared.Entities; +using Session = Sledgemapper.Api.Core.Entities.Session; + namespace Sledgemapper.Api.Notifications { @@ -6,7 +8,7 @@ namespace Sledgemapper.Api.Notifications { public Tile Tile { get; private set; } - public NewTileNotification(Models.Session session, Tile tile, int userId) : base(session, userId) + public NewTileNotification(Session session, Tile tile, string userId) : base(session, userId) { Tile = tile; } diff --git a/Sledgemapper.Api/Notifications/NewWallNotification.cs b/Sledgemapper.Api/Notifications/NewWallNotification.cs index efae53c..be092cb 100644 --- a/Sledgemapper.Api/Notifications/NewWallNotification.cs +++ b/Sledgemapper.Api/Notifications/NewWallNotification.cs @@ -1,4 +1,5 @@ using Sledgemapper.Shared.Entities; +using Session = Sledgemapper.Api.Core.Entities.Session; namespace Sledgemapper.Api.Notifications { @@ -6,7 +7,7 @@ namespace Sledgemapper.Api.Notifications { public Wall Wall { get; private set; } - public NewWallNotification(Models.Session session, Wall wall, int userId) : base(session, userId) + public NewWallNotification(Session session, Wall wall, string userId) : base(session, userId) { Wall = wall; } diff --git a/Sledgemapper.Api/Program.cs b/Sledgemapper.Api/Program.cs index f8fd8e5..774d2dc 100644 --- a/Sledgemapper.Api/Program.cs +++ b/Sledgemapper.Api/Program.cs @@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; -using Sledgemapper.Api.Data; +using Sledgemapper.Api.Infrastructure.Data; namespace Sledgemapper.Api { @@ -37,8 +37,8 @@ namespace Sledgemapper.Api var services = scope.ServiceProvider; try { - var context = services.GetRequiredService(); - DbInitializer.Initialize(context); + var context = services.GetRequiredService(); + // DbInitializer.Initialize(context); } catch (Exception ex) { diff --git a/Sledgemapper.Api/Services/UserService.cs b/Sledgemapper.Api/Services/UserService.cs deleted file mode 100644 index 6bc586b..0000000 --- a/Sledgemapper.Api/Services/UserService.cs +++ /dev/null @@ -1,159 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Sledgemapper.Entities; -using Sledgemapper.Helpers; - -namespace Sledgemapper.Services -{ - public interface IUserService - { - User Authenticate(string username, string password); - IEnumerable GetAll(); - User GetById(int id); - User Create(User user, string password); - void Update(User user, string password = null); - void Delete(int id); - } - - public class UserService : IUserService - { - private DataContext _context; - - public UserService(DataContext context) - { - _context = context; - } - - public User Authenticate(string username, string password) - { - if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password)) - return null; - - var user = _context.Users.SingleOrDefault(x => x.Username == username); - - // check if username exists - if (user == null) - return null; - - // check if password is correct - if (!VerifyPasswordHash(password, user.PasswordHash, user.PasswordSalt)) - return null; - - // authentication successful - return user; - } - - public IEnumerable GetAll() - { - return _context.Users; - } - - public User GetById(int id) - { - return _context.Users.Find(id); - } - - public User Create(User user, string password) - { - // validation - if (string.IsNullOrWhiteSpace(password)) - throw new AppException("Password is required"); - - if (_context.Users.Any(x => x.Username == user.Username)) - throw new AppException("Username \"" + user.Username + "\" is already taken"); - - byte[] passwordHash, passwordSalt; - CreatePasswordHash(password, out passwordHash, out passwordSalt); - - user.PasswordHash = passwordHash; - user.PasswordSalt = passwordSalt; - - _context.Users.Add(user); - _context.SaveChanges(); - - return user; - } - - public void Update(User userParam, string password = null) - { - var user = _context.Users.Find(userParam.Id); - - if (user == null) - throw new AppException("User not found"); - - // update username if it has changed - if (!string.IsNullOrWhiteSpace(userParam.Username) && userParam.Username != user.Username) - { - // throw error if the new username is already taken - if (_context.Users.Any(x => x.Username == userParam.Username)) - throw new AppException("Username " + userParam.Username + " is already taken"); - - user.Username = userParam.Username; - } - - // update user properties if provided - if (!string.IsNullOrWhiteSpace(userParam.FirstName)) - user.FirstName = userParam.FirstName; - - if (!string.IsNullOrWhiteSpace(userParam.LastName)) - user.LastName = userParam.LastName; - - // update password if provided - if (!string.IsNullOrWhiteSpace(password)) - { - byte[] passwordHash, passwordSalt; - CreatePasswordHash(password, out passwordHash, out passwordSalt); - - user.PasswordHash = passwordHash; - user.PasswordSalt = passwordSalt; - } - - _context.Users.Update(user); - _context.SaveChanges(); - } - - public void Delete(int id) - { - var user = _context.Users.Find(id); - if (user != null) - { - _context.Users.Remove(user); - _context.SaveChanges(); - } - } - - // private helper methods - - private static void CreatePasswordHash(string password, out byte[] passwordHash, out byte[] passwordSalt) - { - if (password == null) throw new ArgumentNullException("password"); - if (string.IsNullOrWhiteSpace(password)) throw new ArgumentException("Value cannot be empty or whitespace only string.", "password"); - - using (var hmac = new System.Security.Cryptography.HMACSHA512()) - { - passwordSalt = hmac.Key; - passwordHash = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password)); - } - } - - private static bool VerifyPasswordHash(string password, byte[] storedHash, byte[] storedSalt) - { - if (password == null) throw new ArgumentNullException("password"); - if (string.IsNullOrWhiteSpace(password)) throw new ArgumentException("Value cannot be empty or whitespace only string.", "password"); - if (storedHash.Length != 64) throw new ArgumentException("Invalid length of password hash (64 bytes expected).", "passwordHash"); - if (storedSalt.Length != 128) throw new ArgumentException("Invalid length of password salt (128 bytes expected).", "passwordHash"); - - using (var hmac = new System.Security.Cryptography.HMACSHA512(storedSalt)) - { - var computedHash = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password)); - for (int i = 0; i < computedHash.Length; i++) - { - if (computedHash[i] != storedHash[i]) return false; - } - } - - return true; - } - } -} \ No newline at end of file diff --git a/Sledgemapper.Api/Sledgemapper.Api.csproj b/Sledgemapper.Api/Sledgemapper.Api.csproj index be04316..a5dbc63 100644 --- a/Sledgemapper.Api/Sledgemapper.Api.csproj +++ b/Sledgemapper.Api/Sledgemapper.Api.csproj @@ -6,17 +6,22 @@ - + - - + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - - - + + + + + diff --git a/Sledgemapper.Api/Startup.cs b/Sledgemapper.Api/Startup.cs index 64ee362..0928fd3 100644 --- a/Sledgemapper.Api/Startup.cs +++ b/Sledgemapper.Api/Startup.cs @@ -1,123 +1,47 @@ using System; -using System.Linq; -using System.Threading.Tasks; +using System.Text; +using MediatR; +using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; -using Sledgemapper.Api.Data; -using Microsoft.EntityFrameworkCore; -using MediatR; using Microsoft.IdentityModel.Tokens; -using Sledgemapper.Helpers; -using Microsoft.AspNetCore.Authentication.JwtBearer; -using System.Text; -using AutoMapper; -using Sledgemapper.Services; -using System.Security.Claims; +using Microsoft.OpenApi.Models; +using Newtonsoft.Json; +using Sledgemapper.Api.Core.Entities; using Sledgemapper.Api.Hubs; +using Sledgemapper.Api.Infrastructure.Data; namespace Sledgemapper.Api { public class Startup { private readonly IWebHostEnvironment _env; - public IConfiguration Configuration { get; } + public Startup(IWebHostEnvironment env, IConfiguration configuration) { Configuration = configuration; _env = env; - } - - // This method gets called by the runtime. Use this method to add services to the container. - public void ConfigureServices(IServiceCollection services) - { - // if (_env.IsProduction()) - // services.AddDbContext(); - // else - services.AddDbContext(); - - // services.AddRazorPages(); - services.AddCors(); - services.AddControllers(); - services.AddSignalR(); - services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); - services.AddMediatR(typeof(Startup)); - services.AddDbContext(options => {options.UseSqlite("Data Source=db/sledgemapper.db"); options.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);}); - - // services.AddEntityFrameworkSqlite().AddDbContext(); - // configure strongly typed settings objects - var c = Configuration.GetSection("AppSettings"); - var appSettingsSection = Configuration.GetSection("AppSettings"); - services.Configure(appSettingsSection); - - // configure jwt authentication - var appSettings = appSettingsSection.Get(); - var key = Encoding.ASCII.GetBytes(appSettings.Secret); - services.AddAuthentication(x => - { - x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; - x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; - }) - .AddJwtBearer(x => - { - x.Events = new JwtBearerEvents - { - OnTokenValidated = context => - { - var userService = context.HttpContext.RequestServices.GetRequiredService(); - var userId = int.Parse(context.Principal.Identity.Name); - var user = userService.GetById(userId); - if (user == null) - { - // return unauthorized if user no longer exists - context.Fail("Unauthorized"); - } - context.HttpContext.User.Claims.Append(new Claim(ClaimTypes.Name, user.Username)); - context.HttpContext.User.Claims.Append(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString())); - return Task.CompletedTask; - } - }; - x.RequireHttpsMetadata = false; - x.SaveToken = true; - x.TokenValidationParameters = new TokenValidationParameters - { - ValidateIssuerSigningKey = true, - IssuerSigningKey = new SymmetricSecurityKey(key), - ValidateIssuer = false, - ValidateAudience = false - }; - }); - - // configure DI for application services - services.AddScoped(); - - } + public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env, DataContext dataContext) + public void Configure(IApplicationBuilder app, IWebHostEnvironment env, SledgemapperDbContext dataContext) { - dataContext.Database.Migrate(); + // Enable middleware to serve generated Swagger as a JSON endpoint. + app.UseSwagger(); - // if (env.IsDevelopment()) - // { - // app.UseDeveloperExceptionPage(); - // } - // else - // { - // app.UseExceptionHandler("/Error"); - // // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. - // app.UseHsts(); - // } + // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), + // specifying the Swagger JSON endpoint. + app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"); }); - // //app.UseHttpsRedirection(); - // app.UseStaticFiles(); + dataContext.Database.Migrate(); app.UseRouting(); - // global cors policy + app.UseCors(x => x .AllowAnyOrigin() .AllowAnyMethod() @@ -125,17 +49,89 @@ namespace Sledgemapper.Api app.UseAuthentication(); app.UseAuthorization(); - app.UseEndpoints(endpoints => - { - endpoints.MapControllers(); - }); + app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); - app.UseEndpoints(endpoints => + app.UseEndpoints(endpoints => { endpoints.MapHub("/sledgemapperhub"); }); + } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + services.AddCors(); + services.AddControllers().AddNewtonsoftJson(o => { - // endpoints.MapRazorPages(); - endpoints.MapHub("/sledgemapperhub"); + o.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; + }); + services.AddSignalR(); + services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); + services.AddMediatR(typeof(Startup)); + services.AddDbContext(options => + { + options.UseSqlite("Data Source=db/sledgemapper.db"); + options.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking); + }); + + services.Configure(Configuration.GetSection("JwtConfig")); + + // configure DI for application services + + // within this section we are configuring the authentication and setting the default scheme + services.AddAuthentication(options => + { + options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; + }) + .AddJwtBearer(jwt => + { + var key = Encoding.ASCII.GetBytes(Configuration["JwtConfig:Secret"]); + + jwt.SaveToken = true; + jwt.TokenValidationParameters = new TokenValidationParameters + { + ValidateIssuerSigningKey = + true, // this will validate the 3rd part of the jwt token using the secret that we added in the appsettings and verify we have generated the jwt token + IssuerSigningKey = new SymmetricSecurityKey(key), // Add the secret key to our Jwt encryption + ValidateIssuer = false, + ValidateAudience = false, + RequireExpirationTime = false, + ValidateLifetime = true + }; + }); + + services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = false) + .AddEntityFrameworkStores(); + + services.AddSwaggerGen(c => + { + c.SwaggerDoc("v1", new OpenApiInfo + { + Title = "My API", + Version = "v1" + }); + c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme + { + In = ParameterLocation.Header, + Description = "Please insert JWT with Bearer into field", + Name = "Authorization", + Type = SecuritySchemeType.ApiKey + }); + c.AddSecurityRequirement(new OpenApiSecurityRequirement + { + { + new OpenApiSecurityScheme + { + Reference = new OpenApiReference + { + Type = ReferenceType.SecurityScheme, + Id = "Bearer" + } + }, + Array.Empty() + } + }); }); } } -} +} \ No newline at end of file diff --git a/Sledgemapper.Api/appsettings.Development.json b/Sledgemapper.Api/appsettings.Development.json index 996eb73..f66b5e3 100644 --- a/Sledgemapper.Api/appsettings.Development.json +++ b/Sledgemapper.Api/appsettings.Development.json @@ -1,12 +1,12 @@ -{ - "ConnectionStrings": { - "WebApiDatabase": "Data Source=db/LocalDatabase.db" - }, - "Logging": { - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" +{ + "ConnectionStrings": { + "WebApiDatabase": "Data Source=db/sledgemapper.db" + }, + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } } - } } diff --git a/Sledgemapper.Api/appsettings.Production.json b/Sledgemapper.Api/appsettings.Production.json index 996eb73..f66b5e3 100644 --- a/Sledgemapper.Api/appsettings.Production.json +++ b/Sledgemapper.Api/appsettings.Production.json @@ -1,12 +1,12 @@ -{ - "ConnectionStrings": { - "WebApiDatabase": "Data Source=db/LocalDatabase.db" - }, - "Logging": { - "LogLevel": { - "Default": "Debug", - "System": "Information", - "Microsoft": "Information" +{ + "ConnectionStrings": { + "WebApiDatabase": "Data Source=db/sledgemapper.db" + }, + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } } - } } diff --git a/Sledgemapper.Api/appsettings.json b/Sledgemapper.Api/appsettings.json index 8df0888..3471d80 100644 --- a/Sledgemapper.Api/appsettings.json +++ b/Sledgemapper.Api/appsettings.json @@ -1,16 +1,16 @@ { - "AppSettings": { - "Secret": "THIS IS USED TO SIGN AND VERIFY JWT TOKENS, REPLACE IT WITH YOUR OWN SECRET, IT CAN BE ANY STRING" - }, - "ConnectionStrings": { - "WebApiDatabase": "ENTER PRODUCTION SQL SERVER CONNECTION STRING HERE" - }, - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft": "Warning", - "Microsoft.Hosting.Lifetime": "Information" - } - }, - "AllowedHosts": "*" -} + "JwtConfig": { + "Secret": "ALy9zGFVZBza9cju458dVC2rBdwPqfb7" + }, + "ConnectionStrings": { + "WebApiDatabase": "ENTER PRODUCTION SQL SERVER CONNECTION STRING HERE" + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*" +} \ No newline at end of file diff --git a/Sledgemapper.Api/db/LocalDatabase.db b/Sledgemapper.Api/db/LocalDatabase.db deleted file mode 100644 index 29abb43..0000000 Binary files a/Sledgemapper.Api/db/LocalDatabase.db and /dev/null differ diff --git a/Sledgemapper.Api/db/sledgemapper.db b/Sledgemapper.Api/db/sledgemapper.db deleted file mode 100644 index 6e14010..0000000 Binary files a/Sledgemapper.Api/db/sledgemapper.db and /dev/null differ diff --git a/Sledgemapper.Api/sledgemapper.db b/Sledgemapper.Api/sledgemapper.db deleted file mode 100644 index 376d51c..0000000 Binary files a/Sledgemapper.Api/sledgemapper.db and /dev/null differ diff --git a/Sledgemapper.Shared/Clients/ISledgemapperClient.cs b/Sledgemapper.Shared/Clients/ISledgemapperClient.cs index 4e8bc07..7a4ab09 100644 --- a/Sledgemapper.Shared/Clients/ISledgemapperClient.cs +++ b/Sledgemapper.Shared/Clients/ISledgemapperClient.cs @@ -1,7 +1,7 @@ using Sledgemapper.Shared.Entities; using System.Threading.Tasks; -namespace Sledgemapper.Clients +namespace Sledgemapper.Shared.Clients { public interface ISledgemapperClient { @@ -21,5 +21,7 @@ namespace Sledgemapper.Clients Task RefreshPlayers(); Task NewLine(Line line); Task Ping(Ping ping); + //Task NewCampaign(string campaignName); + //Task> GetCampaigns(); } } diff --git a/Sledgemapper.Shared/Entities/AuthenticateModel.cs b/Sledgemapper.Shared/Entities/AuthenticateModel.cs index 61c8d20..cb13fb3 100644 --- a/Sledgemapper.Shared/Entities/AuthenticateModel.cs +++ b/Sledgemapper.Shared/Entities/AuthenticateModel.cs @@ -9,5 +9,8 @@ namespace Sledgemapper.Shared.Entities [Required] public string Password { get; set; } + + [Required] + public string Email { get; set; } } } \ No newline at end of file diff --git a/Sledgemapper.Shared/Entities/Campaign.cs b/Sledgemapper.Shared/Entities/Campaign.cs new file mode 100644 index 0000000..99e8e2c --- /dev/null +++ b/Sledgemapper.Shared/Entities/Campaign.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; + +namespace Sledgemapper.Shared.Entities +{ + public class Campaign + { + public Guid Id { get; set; } + public string Name { get; set; } + public List Maps { get; set; } + } +} \ No newline at end of file diff --git a/Sledgemapper.Shared/Entities/Note.cs b/Sledgemapper.Shared/Entities/Note.cs index 6dac5bb..a89257f 100644 --- a/Sledgemapper.Shared/Entities/Note.cs +++ b/Sledgemapper.Shared/Entities/Note.cs @@ -1,9 +1,21 @@ -namespace Sledgemapper.Shared.Entities +namespace Sledgemapper.Shared.Entities { public class Note :BaseMapEntity { + public Note(){} + public Note(Note n) + { + X=n.X; + Y=n.Y; + Text=n.Text; + ID = n.ID; + Rotation = n.Rotation; + Timestamp = n.Timestamp; + + } + public string Text { get; set; } } diff --git a/Sledgemapper.Shared/Entities/Player.cs b/Sledgemapper.Shared/Entities/Player.cs index 976d516..d750c70 100644 --- a/Sledgemapper.Shared/Entities/Player.cs +++ b/Sledgemapper.Shared/Entities/Player.cs @@ -1,9 +1,12 @@ +using System; + namespace Sledgemapper.Shared.Entities { public class Player { - public int UserId { get; set; } + public Guid UserId { get; set; } public string Color { get; set; } + public string UserName { get; set; } public string Initials { get; set; } public Tile Position { get; set; } diff --git a/Sledgemapper.Shared/Entities/RegisterModel.cs b/Sledgemapper.Shared/Entities/RegisterModel.cs index d739ba1..b349269 100644 --- a/Sledgemapper.Shared/Entities/RegisterModel.cs +++ b/Sledgemapper.Shared/Entities/RegisterModel.cs @@ -13,6 +13,9 @@ namespace Sledgemapper.Shared.Entities [Required] public string Username { get; set; } + [Required] + public string Email { get; set; } + [Required] public string Password { get; set; } [Required] diff --git a/Sledgemapper.Shared/Entities/Session.cs b/Sledgemapper.Shared/Entities/Session.cs index 4ded5e6..84d8454 100644 --- a/Sledgemapper.Shared/Entities/Session.cs +++ b/Sledgemapper.Shared/Entities/Session.cs @@ -16,6 +16,11 @@ namespace Sledgemapper.Shared.Entities public MapEntityDeletedEventArgs(BaseMapEntity mapEntity) => MapEntity = mapEntity; } +public class Map:Session +{ + +} + public class Session { public event EventHandler MapEntityAdded; @@ -42,9 +47,9 @@ namespace Sledgemapper.Shared.Entities public List Players { get; set; } public ConcurrentDictionary Pings { get; set; } public List Colors { get; set; } - public string SessionName { get; set; } - public int SessionId { get; set; } - public ConcurrentDictionary Lines { get; set; } + public string SessionName { get; set; } + public Guid SessionId { get; set; } + public ConcurrentDictionary Lines { get; set; } public ConcurrentDictionary Rooms { get; set; } public void NewTile(Tile selectedTile, string tileId) @@ -117,7 +122,7 @@ namespace Sledgemapper.Shared.Entities var newNote = new Note { X = selectedNote.X, Y = selectedNote.Y, Text = selectedNote.Text }; if (noteExists) { - Walls.TryRemove(note.ToString(), out var _); + Notes.TryRemove(note.ToString(), out var _); } Notes.TryAdd(newNote.ToString(), newNote); diff --git a/Sledgemapper.Shared/Entities/Tile.cs b/Sledgemapper.Shared/Entities/Tile.cs index f1e21e1..aeace6a 100644 --- a/Sledgemapper.Shared/Entities/Tile.cs +++ b/Sledgemapper.Shared/Entities/Tile.cs @@ -1,5 +1,4 @@ using System; -using System.Security.Cryptography; namespace Sledgemapper.Shared.Entities { diff --git a/Sledgemapper.Shared/ExtensionMethods.cs b/Sledgemapper.Shared/ExtensionMethods.cs index f96159c..e0448d5 100644 --- a/Sledgemapper.Shared/ExtensionMethods.cs +++ b/Sledgemapper.Shared/ExtensionMethods.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace Sledgemapper.Api.Hubs +namespace Sledgemapper.Shared { public static class ExtensionMethods { @@ -20,6 +20,6 @@ namespace Sledgemapper.Api.Hubs } } - + } } \ No newline at end of file diff --git a/Sledgemapper.Shared/ObservableConcurrentDictionary.cs b/Sledgemapper.Shared/ObservableConcurrentDictionary.cs index 7173e08..6bf7b4b 100644 --- a/Sledgemapper.Shared/ObservableConcurrentDictionary.cs +++ b/Sledgemapper.Shared/ObservableConcurrentDictionary.cs @@ -8,8 +8,10 @@ using System.Collections.Specialized; using System.ComponentModel; using System.Threading; using System.Diagnostics; +using System.Collections; +using System.Collections.Concurrent; -namespace System.Collections.Concurrent +namespace Sledgemapper.Shared { /// /// Provides a thread-safe dictionary for use with data binding. diff --git a/Sledgemapper.sln.DotSettings b/Sledgemapper.sln.DotSettings new file mode 100644 index 0000000..b22b302 --- /dev/null +++ b/Sledgemapper.sln.DotSettings @@ -0,0 +1,2 @@ + + True \ No newline at end of file diff --git a/Sledgemapper/AuthenticatedHttpClientHandler.cs b/Sledgemapper/AuthenticatedHttpClientHandler.cs new file mode 100644 index 0000000..4f691bf --- /dev/null +++ b/Sledgemapper/AuthenticatedHttpClientHandler.cs @@ -0,0 +1,38 @@ +using System; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading; +using System.Threading.Tasks; + +namespace Sledgemapper +{ + internal class AuthenticatedHttpClientHandler : HttpClientHandler + { + private readonly Func> _getToken; + + public AuthenticatedHttpClientHandler(Func> getToken) + { + _getToken = getToken ?? throw new ArgumentNullException(nameof(getToken)); + + //if (myConfigurationService.VerifySslCertificate == false) + //{ + ServerCertificateCustomValidationCallback = + (message, certificate, chain, sslPolicyErrors) => true; + //} + } + + protected override async Task SendAsync(HttpRequestMessage request, + CancellationToken cancellationToken) + { + // See if the request has an authorize header + var auth = request.Headers.Authorization; + if (auth != null) + { + var token = await _getToken().ConfigureAwait(false); + request.Headers.Authorization = new AuthenticationHeaderValue(auth.Scheme, token); + } + + return await base.SendAsync(request, cancellationToken).ConfigureAwait(false); + } + } +} \ No newline at end of file diff --git a/Sledgemapper/CacheSettings.cs b/Sledgemapper/CacheSettings.cs new file mode 100644 index 0000000..3dd06a5 --- /dev/null +++ b/Sledgemapper/CacheSettings.cs @@ -0,0 +1,30 @@ +using Microsoft.Identity.Client.Extensions.Msal; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Sledgemapper +{ + public static class CacheSettings + { + // computing the root directory is not very simple on Linux and Mac, so a helper is provided + private static readonly string s_cacheFilePath = + Path.Combine(MsalCacheHelper.UserRootDirectory, "sledgemapper.scandysoft.cache"); + + public static readonly string CacheFileName = Path.GetFileName(s_cacheFilePath); + public static readonly string CacheDir = Path.GetDirectoryName(s_cacheFilePath); + + + public static readonly string KeyChainServiceName = "Scandysoft.Sledgemapper"; + public static readonly string KeyChainAccountName = "MSALCache"; + + public static readonly string LinuxKeyRingSchema = "com.scandysoft.sledgemappertokencache"; + public static readonly string LinuxKeyRingCollection = MsalCacheHelper.LinuxKeyRingDefaultCollection; + public static readonly string LinuxKeyRingLabel = "Sledgemapper API token."; + public static readonly KeyValuePair LinuxKeyRingAttr1 = new KeyValuePair("Version", "1"); + public static readonly KeyValuePair LinuxKeyRingAttr2 = new KeyValuePair("ProductGroup", "MyApps"); + } +} diff --git a/Sledgemapper/CachedContent.cs b/Sledgemapper/CachedContent.cs new file mode 100644 index 0000000..61c0c86 --- /dev/null +++ b/Sledgemapper/CachedContent.cs @@ -0,0 +1,33 @@ +using Microsoft.Xna.Framework.Graphics; + +namespace Sledgemapper +{ + public class CachedContent + { + private static readonly CachedContent instance = new CachedContent(); + + // Explicit static constructor to tell C# compiler + // not to mark type as beforefieldinit + static CachedContent() + { + } + + private CachedContent() + { + + } + + public static CachedContent Instance + { + get + { + return instance; + } + } + + + + public Texture2D Eye { get; set; } + public Texture2D Location { get; set; } + } +} diff --git a/Sledgemapper/ChannelsQueue.cs b/Sledgemapper/ChannelsQueue.cs index 5515c41..c5fbb25 100644 --- a/Sledgemapper/ChannelsQueue.cs +++ b/Sledgemapper/ChannelsQueue.cs @@ -1,17 +1,20 @@ using System; using System.Threading.Tasks; using System.Threading.Channels; -using Exceptionless; -using Exceptionless.Models; +using Sentry; +using Sledgemapper.Messages; +using TinyMessenger; namespace Sledgemapper { public class ChannelsQueue { + public TinyMessengerHub Messenger { get; } private readonly ChannelWriter _writer; - public ChannelsQueue() + public ChannelsQueue(TinyMessenger.TinyMessengerHub messenger) { + Messenger = messenger; var channel = Channel.CreateUnbounded(new UnboundedChannelOptions() { SingleReader = true }); var reader = channel.Reader; _writer = channel.Writer; @@ -20,8 +23,8 @@ namespace Sledgemapper { while (await reader.WaitToReadAsync()) { - // Fast loop around available jobs - while (reader.TryRead(out var job)) + // Fast loop around available jobs + while (reader.TryRead(out var job)) { try { @@ -29,8 +32,8 @@ namespace Sledgemapper } catch (Exception ex) { - ExceptionlessClient.Default.SubmitException(ex); - throw; + SentrySdk.CaptureException(ex); + messenger.Publish(new ErrorMessage(this, ex.Message)); } } } diff --git a/Sledgemapper/CommunicationManager.cs b/Sledgemapper/CommunicationManager.cs index ccb35e9..c584097 100644 --- a/Sledgemapper/CommunicationManager.cs +++ b/Sledgemapper/CommunicationManager.cs @@ -1,148 +1,144 @@ -using Microsoft.AspNetCore.SignalR.Client; -using Microsoft.Extensions.Configuration; -using Polly; -using Refit; -using Sledgemapper.Shared.Entities; using System; +using System.Collections; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Net; using System.Net.Http; -using System.Net.Http.Headers; -using System.Threading; +using System.Text; +using System.Text.Json; using System.Threading.Tasks; +using Microsoft.AspNetCore.SignalR.Client; +using Polly; +using Polly.Retry; +using Refit; +using SharpFontInternal; +using Sledgemapper.Messages; +using Sledgemapper.Shared.Entities; +using TinyMessenger; namespace Sledgemapper { public class CommunicationManager { - public IMapApi Api { get; private set; } - public HubConnection Connection { get; private set; } + public TinyMessengerHub Messenger { get; } + public IMapApi Api { get; } + public HubConnection Connection { get; } + + private readonly ChannelsQueue _queue; + private readonly AsyncRetryPolicy _retryPolicy; public readonly Session SessionData; - private readonly ChannelsQueue Queue = new(); private AuthenticateResponse _authenticateResponse; - public CommunicationManager(Session sessionData) + public CommunicationManager(Session sessionData, TinyMessengerHub messenger) { - + Messenger = messenger; + _queue = new ChannelsQueue(Messenger); #if DEBUG var baseAddress = "http://localhost:5000"; + //baseAddress = "http://hub.michelescandura.com:5001"; #else - var baseAddress = "http://hub.michelescandura.com:5000"; + var baseAddress = "http://hub.michelescandura.com:5001"; #endif + CheckLogin(); + + _retryPolicy = Policy + .Handle(ex => ex.StatusCode == HttpStatusCode.RequestTimeout) + .Or() + .RetryAsync(3); + + //.RetryAsync(Polly.RetrySyntax., async (exception, retryCount) => await Task.Delay(500)) + + SessionData = sessionData; Connection = new HubConnectionBuilder() - .WithAutomaticReconnect() - - .WithUrl($"{baseAddress}/SledgemapperHub", options => - { - options.AccessTokenProvider = () => Task.FromResult(_authenticateResponse.Token); - }) - .Build(); + .WithAutomaticReconnect() + .WithUrl($"{baseAddress}/SledgemapperHub", + options => { options.AccessTokenProvider = () => Task.FromResult(_authenticateResponse.Token); }) + .Build(); Api = RestService.For( - new HttpClient(new AuthenticatedHttpClientHandler(GetToken)) - { - BaseAddress = new Uri(baseAddress) - } - ); + new HttpClient(new AuthenticatedHttpClientHandler(GetToken)) + { + BaseAddress = new Uri(baseAddress) + } + ); - Connection.On("UpdateMap", (map) => + Connection.On("UpdateMap", map => { SessionData.Map = map.Map; SessionData.Walls = map.Walls; SessionData.Overlays = map.Overlays; }); - Connection.On("PlayerUpdate", (player) => + Connection.On("PlayerUpdate", player => { var p = SessionData.Players.FirstOrDefault(m => m.UserId == player.UserId); if (p != null) - { p.Position = player.Position; - } else - { SessionData.Players.Add(player); - } }); - Connection.On("DeleteTile", (tile) => + Connection.On("DeleteTile", tile => { SessionData.Map.Remove(tile.ToString(), out var _); }); + + Connection.On("DeleteWall", tile => { SessionData.Walls.Remove(tile.ToString(), out var _); }); + + Connection.On("DeleteNote", tile => { SessionData.Notes.Remove(tile.ToString(), out var _); }); + + Connection.On("DeleteOverlay", + tile => { SessionData.Overlays.Remove(tile.ToString(), out var _); }); + + Connection.On("NewTile", tile => { SessionData.Map.Remove(tile.ToString(), out var _); + SessionData.Map.TryAdd(tile.ToString(), tile); }); - Connection.On("DeleteWall", (tile) => - { - SessionData.Walls.Remove(tile.ToString(), out var _); - }); + Connection.On("NewRoom", room => + { + SessionData.Rooms.Remove(room.ToString(), out var _); + SessionData.Rooms.TryAdd(room.ToString(), room); + }); - Connection.On("DeleteNote", (tile) => - { - SessionData.Notes.Remove(tile.ToString(), out var _); - }); - - Connection.On("DeleteOverlay", (tile) => - { - SessionData.Overlays.Remove(tile.ToString(), out var _); - }); - - Connection.On("NewTile", (tile) => - { - SessionData.Map.Remove(tile.ToString(), out var _); - SessionData.Map.TryAdd(tile.ToString(), tile); - }); - - Connection.On("NewRoom", (room) => - { - SessionData.Rooms.Remove(room.ToString(), out var _); - SessionData.Rooms.TryAdd(room.ToString(), room); - }); - - Connection.On("NewLine", (line) => - { - SessionData.Lines.Remove(line.ToString(), out var _); - SessionData.Lines.TryAdd(line.ToString(), line); - }); + Connection.On("NewLine", line => + { + SessionData.Lines.Remove(line.ToString(), out var _); + SessionData.Lines.TryAdd(line.ToString(), line); + }); Connection.On("RefreshPlayers", () => - { - if (!string.IsNullOrWhiteSpace(SessionData.SessionName)) - { - Connection?.SendAsync("UpdatePosition", SessionData.SessionName, SessionData.SessionId, SessionData.Players.First(p => p.UserId == int.Parse(_authenticateResponse.Id))); - } - }); + { + if (!string.IsNullOrWhiteSpace(State.Instance.MapName)) + Connection?.SendAsync("UpdatePosition", State.Instance.MapName, State.Instance.MapId, + SessionData.Players.First(p => p.UserId == new Guid(_authenticateResponse.Id))); + }); - Connection.On("RemovePlayer", (player) => - { - var p = SessionData.Players.FirstOrDefault(m => m.UserId == player.UserId); - if (p != null) - { - SessionData.Players.Remove(p); - } - }); + Connection.On("RemovePlayer", player => + { + var p = SessionData.Players.FirstOrDefault(m => m.UserId == player.UserId); + if (p != null) SessionData.Players.Remove(p); + }); - Connection.On("NewWall", (tile) => - { - SessionData.Walls.Remove(tile.ToString(), out var _); - SessionData.Walls.TryAdd(tile.ToString(), tile); - }); + Connection.On("NewWall", tile => + { + SessionData.Walls.Remove(tile.ToString(), out var _); + SessionData.Walls.TryAdd(tile.ToString(), tile); + }); - Connection.On("NewOverlay", (tile) => + Connection.On("NewOverlay", tile => { SessionData.Overlays.Remove(tile.ToString(), out var _); SessionData.Overlays.TryAdd(tile.ToString(), tile); }); - Connection.On("NewNote", (note) => + Connection.On("NewNote", note => { //SessionData.Notes.Remove(note.ToString(), out var _); SessionData.Notes.AddOrUpdate(note.ToString(), note, (key, oldnote) => note); }); - Connection.On("NewPlayer", (player) => + Connection.On("NewPlayer", player => { var p = SessionData.Players.FirstOrDefault(m => m.UserId == player.UserId); if (p is null) @@ -156,38 +152,7 @@ namespace Sledgemapper } }); - Connection.On("Ping", (ping) => - { - SessionData.Pings.TryAdd(Guid.NewGuid(), ping); - }); - } - - private Task GetToken() - { - return Task.FromResult(_authenticateResponse.Token); - } - - public async Task Register(RegisterModel registerModel) - { - var result = await Api.Register(registerModel).ConfigureAwait(false); - return result; - } - - public async Task Login(AuthenticateModel authenticateModel) - { - _authenticateResponse = await Api.Authenticate(authenticateModel).ConfigureAwait(false); - return _authenticateResponse; - } - - private async Task Execute(Func call) - { - await Policy - .Handle(ex => ex.StatusCode == HttpStatusCode.RequestTimeout) - - .RetryForeverAsync() - //.RetryAsync(Polly.RetrySyntax., async (exception, retryCount) => await Task.Delay(500)) - .ExecuteAsync(async () => await call().ConfigureAwait(false)) - .ConfigureAwait(false); + Connection.On("Ping", ping => { SessionData.Pings.TryAdd(Guid.NewGuid(), ping); }); } public void Enqueue(BaseMapEntity entity, TileAction action) @@ -198,83 +163,183 @@ namespace Sledgemapper switch (entity) { case Tile tile: - Queue.Enqueue(async () => await Execute(async () => await Api.NewTile(tile, SessionData.SessionName).ConfigureAwait(false))); + _queue.Enqueue(async () => await Execute(async () => + await Api.NewTile(tile, State.Instance.CampaignId, State.Instance.MapId) + .ConfigureAwait(false))); break; case Overlay overlay: - Queue.Enqueue(async () => await Execute(async () => await Api.NewOverlay(overlay, SessionData.SessionName).ConfigureAwait(false))); + _queue.Enqueue(async () => await Execute(async () => + await Api.NewOverlay(overlay, State.Instance.CampaignId, State.Instance.MapId) + .ConfigureAwait(false))); break; case Wall wall: - Queue.Enqueue(async () => await Execute(async () => await Api.NewWall(wall, SessionData.SessionName).ConfigureAwait(false))); + _queue.Enqueue(async () => await Execute(async () => + await Api.NewWall(wall, State.Instance.CampaignId, State.Instance.MapId) + .ConfigureAwait(false))); break; case Note note: - Queue.Enqueue(async () => await Execute(async () => await Api.NewNote(note, SessionData.SessionName).ConfigureAwait(false))); + _queue.Enqueue(async () => await Execute(async () => + await Api.NewNote(note, State.Instance.CampaignId, State.Instance.MapId) + .ConfigureAwait(false))); break; case Room room: - Queue.Enqueue(async () => await Execute(async () => await Api.NewRoom(room, SessionData.SessionName).ConfigureAwait(false))); + _queue.Enqueue(async () => await Execute(async () => + await Api.NewRoom(room, State.Instance.CampaignId, State.Instance.MapId) + .ConfigureAwait(false))); break; case Line line: - Queue.Enqueue(async () => await Execute(async () => await Api.NewLine(line, SessionData.SessionName).ConfigureAwait(false))); + _queue.Enqueue(async () => await Execute(async () => + await Api.NewLine(line, State.Instance.CampaignId, State.Instance.MapId) + .ConfigureAwait(false))); break; } + break; case TileAction.Delete: switch (entity) { case Tile tile: - Queue.Enqueue(async () => await Execute(async () => await Api.DeleteTile(tile, SessionData.SessionName).ConfigureAwait(false))); + _queue.Enqueue(async () => await Execute(async () => + await Api.DeleteTile(tile, State.Instance.CampaignId, State.Instance.MapId) + .ConfigureAwait(false))); break; case Overlay overlay: - Queue.Enqueue(async () => await Execute(async () => await Api.DeleteOverlay(overlay, SessionData.SessionName).ConfigureAwait(false))); + _queue.Enqueue(async () => await Execute(async () => + await Api.DeleteOverlay(overlay, State.Instance.CampaignId, State.Instance.MapId) + .ConfigureAwait(false))); break; case Wall wall: - Queue.Enqueue(async () => await Execute(async () => await Api.DeleteWall(wall, SessionData.SessionName).ConfigureAwait(false))); + _queue.Enqueue(async () => await Execute(async () => + await Api.DeleteWall(wall, State.Instance.CampaignId, State.Instance.MapId) + .ConfigureAwait(false))); break; case Note note: - Queue.Enqueue(async () => await Execute(async () => await Api.DeleteNote(note, SessionData.SessionName).ConfigureAwait(false))); + _queue.Enqueue(async () => await Execute(async () => + await Api.DeleteNote(note, State.Instance.CampaignId, State.Instance.MapId) + .ConfigureAwait(false))); break; } + break; } + } + private async Task Execute(Func call) + { + await Policy + .Handle(ex => ex.StatusCode == HttpStatusCode.RequestTimeout) + .Or() + .RetryForeverAsync() + //.RetryAsync(Polly.RetrySyntax., async (exception, retryCount) => await Task.Delay(500)) + .ExecuteAsync(async () => await call().ConfigureAwait(false)) + .ConfigureAwait(false); + } + + private Task GetToken() + { + return Task.FromResult(_authenticateResponse?.Token ?? ""); + } + + public async Task> GetCampaigns() + { + try + { + return await _retryPolicy.ExecuteAsync(Api.GetCampaigns); + } + catch (Exception e) + { + Sentry.SentrySdk.CaptureException(e); + Messenger.Publish(new ErrorMessage(this, "Error loading campaigns")); + } + + return null; + } + + public async Task> GetMaps(Guid campaignId) + { + try + { + return await _retryPolicy.ExecuteAsync(() => Api.GetMaps(campaignId)); + } + catch (Exception e) + { + Sentry.SentrySdk.CaptureException(e); + Messenger.Publish(new ErrorMessage(this, "Error loading maps")); + } + + return null; + } + + public async Task> GetPlayers(Guid campaignId) + { + try + { + return await _retryPolicy.ExecuteAsync(() => Api.GetPlayers(campaignId)); + } + catch (Exception e) + { + Sentry.SentrySdk.CaptureException(e); + Messenger.Publish(new ErrorMessage(this, "Error loading players")); + } + + return null; + } + + public async Task Login(AuthenticateModel authenticateModel) + { + _authenticateResponse = await Policy + .Handle(ex => ex.StatusCode == HttpStatusCode.RequestTimeout) + .Or() + .RetryAsync(3) + //.RetryAsync(Polly.RetrySyntax., async (exception, retryCount) => await Task.Delay(500)) + .ExecuteAsync(async () => await Api.Authenticate(authenticateModel)) + .ConfigureAwait(false); + + //_authenticateResponse = await Api.Authenticate(authenticateModel).ConfigureAwait(false); + var data = Encoding.UTF8.GetBytes(JsonSerializer.Serialize(_authenticateResponse)); + + Program.helper.SaveUnencryptedTokenCache(JsonSerializer.SerializeToUtf8Bytes(_authenticateResponse)); + + await Connection.StopAsync(); + + State.Instance.CampaignId=Guid.Empty; + State.Instance.CampaignName = string.Empty; + State.Instance.SessionId = Guid.Empty; + State.Instance.MapId = Guid.Empty; + State.Instance.MapName = string.Empty; + SessionData.SessionId = Guid.Empty; + SessionData.SessionName = string.Empty; + SessionData.Players.Clear(); + + return _authenticateResponse; } internal async Task Ping(Tile location) { - if (Connection!=null && Connection.State == HubConnectionState.Connected) + if (Connection is { State: HubConnectionState.Connected }) + await Connection.InvokeAsync("Ping", SessionData.SessionId, location); + } + + public async Task Register(RegisterModel registerModel) + { + var result = await Api.Register(registerModel).ConfigureAwait(false); + return result; + } + + public void CheckLogin() + { + var data = Program.helper.LoadUnencryptedTokenCache(); + if (data != null && data.Any()) { - await Connection.InvokeAsync("Ping",SessionData.SessionName, location); + try + { + _authenticateResponse = JsonSerializer.Deserialize(Encoding.UTF8.GetString(data)); + Messenger.Publish(new LoginSuccesfulMessage(this) { UserName = _authenticateResponse.Username, Initials = _authenticateResponse.Initials }); + } + catch + { } } } } - - class AuthenticatedHttpClientHandler : HttpClientHandler - { - private readonly Func> getToken; - - public AuthenticatedHttpClientHandler(Func> getToken) - { - if (getToken == null) throw new ArgumentNullException(nameof(getToken)); - this.getToken = getToken; - - //if (myConfigurationService.VerifySslCertificate == false) - //{ - ServerCertificateCustomValidationCallback = - (message, certificate, chain, sslPolicyErrors) => true; - //} - } - - protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) - { - // See if the request has an authorize header - var auth = request.Headers.Authorization; - if (auth != null) - { - var token = await getToken().ConfigureAwait(false); - request.Headers.Authorization = new AuthenticationHeaderValue(auth.Scheme, token); - } - - return await base.SendAsync(request, cancellationToken).ConfigureAwait(false); - } - } -} +} \ No newline at end of file diff --git a/Sledgemapper/Content/Content.mgcb b/Sledgemapper/Content/Content.mgcb index 7b85633..96d1fe1 100644 --- a/Sledgemapper/Content/Content.mgcb +++ b/Sledgemapper/Content/Content.mgcb @@ -107,7 +107,7 @@ #begin handcursorsIndex /importer:XmlImporter -/processor: +/processor:PassThroughProcessor /build:handcursorsIndex #begin icon_delete.png @@ -146,6 +146,18 @@ /processorParam:TextureFormat=Color /build:icon_room.png +#begin listBackground.png +/importer:TextureImporter +/processor:TextureProcessor +/processorParam:ColorKeyColor=255,0,255,255 +/processorParam:ColorKeyEnabled=True +/processorParam:GenerateMipmaps=False +/processorParam:PremultiplyAlpha=True +/processorParam:ResizeToPowerOfTwo=False +/processorParam:MakeSquare=False +/processorParam:TextureFormat=Color +/build:listBackground.png + #begin location.png /importer:TextureImporter /processor:TextureProcessor diff --git a/Sledgemapper/Content/listBackground.png b/Sledgemapper/Content/listBackground.png new file mode 100644 index 0000000..a762eea Binary files /dev/null and b/Sledgemapper/Content/listBackground.png differ diff --git a/Sledgemapper/ExtensionMethods.cs b/Sledgemapper/ExtensionMethods.cs index 7c799ea..1effa91 100644 --- a/Sledgemapper/ExtensionMethods.cs +++ b/Sledgemapper/ExtensionMethods.cs @@ -1,36 +1,96 @@ +using System; using System.Collections.Generic; using System.IO; -using Microsoft.Xna.Framework.Content; -using Microsoft.Xna.Framework; using System.Linq; +using System.Threading.Tasks; +using AsyncAwaitBestPractices; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Myra.Graphics2D.Brushes; +using Myra.Graphics2D.UI; namespace Sledgemapper { public static class ExtensionMethods { + public static Point AbsPoint(this Point point) + { + return new Point(Math.Abs(point.X), Math.Abs(point.Y)); + } + + public static Window GetContainingWindow(this Widget widget) + { + var container = widget.Parent; + while (container is not Window or null) container = container.Parent; + + return container as Window; + } + + public static (Window Window, TC Content) GetParentContentInWindow(this Widget widget) where TC : Widget + { + var container = widget.Parent; + while (container is not Window) container = container.Parent; + + var localWindow = (Window)container; + var localContent = localWindow.Content as TC; + return (localWindow, localContent); + } + public static Dictionary LoadContentFolder(this ContentManager contentManager, string contentFolder) { DirectoryInfo dir = new(contentManager.RootDirectory + "/" + contentFolder); if (!dir.Exists) + { throw new DirectoryNotFoundException(); + } + Dictionary result = new(); - FileInfo[] files = dir.GetFiles("*.*"); - foreach (FileInfo file in files.Where(f => f.Extension != ".ttf" && f.Extension != ".otf")) + var files = dir.GetFiles("*.*"); + + foreach (var file in files.Where(f => f.Extension != ".ttf" && f.Extension != ".otf")) { result.Add(file.Name.Split('.')[0], contentManager.Load(contentFolder + "/" + file.Name.Split('.')[0])); + } + return result; } - public static IEnumerable Split(this string str, int chunkSize) => Enumerable.Range(0, str.Length / chunkSize) - .Select(i => str.Substring(i * chunkSize, chunkSize)); - - public static Point AbsPoint(this Point point) + public static void ShowInModalWindow(this Widget widget, Desktop desktop, string title) { - return new Point(System.Math.Abs(point.X), System.Math.Abs(point.Y)); + Window window = new() + { + Title = title, + Content = widget + }; + + window.ShowModal(desktop); + } + + public static IEnumerable Split(this string str, int chunkSize) + { + return Enumerable.Range(0, str.Length / chunkSize) + .Select(i => str.Substring(i * chunkSize, chunkSize)); + } + + public static void Toast(this Widget widget, Desktop desktop) + { + widget.Left = desktop.BoundsFetcher().Center.X - widget.Width.Value / 2; + widget.Top = desktop.BoundsFetcher().Height - 90; + widget.ZIndex = 1000; + desktop.Widgets.Add(widget); + + Task.Delay(2000).ContinueWith(_ => { desktop.Widgets.Remove(widget); } + ).SafeFireAndForget(); + } + + public static bool ValidateTextbox(this TextBox textBox) + { + var valid = !string.IsNullOrWhiteSpace(textBox.Text); + textBox.Background = valid ? new SolidBrush(new Color(51, 51, 51)) : new SolidBrush(Color.Red); + + return valid; } } - -} - +} \ No newline at end of file diff --git a/Sledgemapper/IMapApi.cs b/Sledgemapper/IMapApi.cs index a68b3cd..b831739 100644 --- a/Sledgemapper/IMapApi.cs +++ b/Sledgemapper/IMapApi.cs @@ -1,6 +1,7 @@ using Refit; using Sledgemapper.Shared.Entities; -using System.Net.Http; +using System; +using System.Collections.Generic; using System.Threading.Tasks; namespace Sledgemapper @@ -8,52 +9,90 @@ namespace Sledgemapper [Headers("Authorization: Bearer")] public interface IMapApi { + [Headers("Authorization")] + [Post("/authmanagement/register")] + Task Register([Body] RegisterModel registerModel); + + [Headers("Authorization")] + [Post("/authmanagement/login")] + Task Authenticate([Body] AuthenticateModel registerModel); + + [Post("/map/{campaignId}/{mapId}/overlay")] + Task NewOverlay([Body] Overlay overlay, Guid campaignId, Guid mapId); + + [Post("/map/{campaignId}/{mapId}/note")] + Task NewNote([Body] Note note, Guid campaignId, Guid mapId); + + [Post("/map/{campaignId}/{mapId}/wall")] + Task NewWall([Body] Wall overlay, Guid campaignId, Guid mapId); + + [Post("/map/{campaignId}/{mapId}/room")] + Task NewRoom(Room room, Guid campaignId, Guid mapId); + + [Post("/map/{campaignId}/{mapId}/line")] + Task NewLine(Line line, Guid campaignId, Guid mapId); + + [Post("/campaign/{campaignName}")] + Task NewCampaign(string campaignName); + + [Get("/campaign/")] + Task> GetCampaigns(); + + [Get("/campaign/{campaignName}/players")] + Task> GetPlayers(Guid campaignName); + + + [Get("/campaign/{campaignId}/maps")] + Task> GetMaps(Guid campaignId); + + [Get("/map/{campaignId}/{mapId}")] + Task GetMap(Guid campaignId, Guid mapId); + + + [Post("/campaign/{campaignId}/players/{email}")] + Task InvitePlayer(Guid campaignId, string email); + + + [Get("/session/{sessionName}")] Task Session(string sessionName); - [Post("/session/{sessionName}")] - Task NewSession(string sessionName); + [Post("/map/{campaignid}/{sessionName}")] + Task NewSession(Guid campaignid, string sessionName); [Post("/session/{sessionName}/snapshot")] - Task SaveSnapshot([Body] Session session, string sessionName); + Task SaveSnapshot([Body] Session session, Guid sessionName); - [Post("/session/{sessionName}/tile")] - Task NewTile([Body] Tile tile, string sessionName); + [Post("/map/{campaignId}/{mapId}/tile")] + Task NewTile([Body] Tile tile, Guid campaignId, Guid mapId); - [Post("/session/{sessionName}/overlay")] - Task NewOverlay([Body] Overlay overlay, string sessionName); - - [Post("/session/{sessionName}/note")] - Task NewNote([Body] Note note, string sessionName); - - [Post("/session/{sessionName}/wall")] - Task NewWall([Body] Wall overlay, string sessionName); - - [Delete("/session/{sessionName}/wall")] - Task DeleteWall([Body] Wall wall, string sessionName); - - [Delete("/session/{sessionName}/tile")] - Task DeleteTile([Body] Tile tile, string sessionName); - - [Delete("/session/{sessionName}/overlay")] - Task DeleteOverlay([Body] Overlay overlay, string sessionName); - - [Delete("/session/{sessionName}/note")] - Task DeleteNote([Body] Note overlay, string sessionName); - - - [Headers("Authorization")] - [Post("/users/register")] - Task Register([Body] RegisterModel registerModel); - - [Headers("Authorization")] - [Post("/users/authenticate")] - Task Authenticate([Body] AuthenticateModel registerModel); - [Post("/session/{sessionName}/room")] - Task NewRoom(Room room, string sessionName); - - [Post("/session/{sessionName}/line")] - Task NewLine(Line line, string sessionName); + + + + [Delete("/map/{campaignId}/{mapId}/wall")] + Task DeleteWall([Body] Wall wall, Guid campaignId, Guid mapId); + + [Delete("/map/{campaignId}/{mapId}/tile")] + Task DeleteTile([Body] Tile tile, Guid campaignId, Guid mapId); + + [Delete("/map/{campaignId}/{mapId}/overlay")] + Task DeleteOverlay([Body] Overlay overlay, Guid campaignId, Guid mapId); + + [Delete("/map/{campaignId}/{mapId}/note")] + Task DeleteNote([Body] Note overlay, Guid campaignId, Guid mapId); + + + public class AuthResult + { + public string Token { get; set; } + public bool Result { get; set; } + public List Errors { get; set; } + } + + + + + } } \ No newline at end of file diff --git a/Sledgemapper/Messages/CampaignSelectedMessage - Copy.cs b/Sledgemapper/Messages/CampaignSelectedMessage - Copy.cs new file mode 100644 index 0000000..5933491 --- /dev/null +++ b/Sledgemapper/Messages/CampaignSelectedMessage - Copy.cs @@ -0,0 +1,9 @@ +namespace Sledgemapper.Messages +{ + public class CampaignSelectedMessage : TinyMessenger.TinyMessageBase + { + public CampaignSelectedMessage(object sender) : base(sender) + { + } + } +} \ No newline at end of file diff --git a/Sledgemapper/Messages/CenterOnTileMessage.cs b/Sledgemapper/Messages/CenterOnTileMessage.cs new file mode 100644 index 0000000..647cec4 --- /dev/null +++ b/Sledgemapper/Messages/CenterOnTileMessage.cs @@ -0,0 +1,12 @@ +namespace Sledgemapper.Messages +{ + public class CenterOnTileMessage : TinyMessenger.TinyMessageBase + { + public CenterOnTileMessage(object sender) : base(sender) + { + } + + public int X { get; internal set; } + public int Y { get; internal set; } + } +} \ No newline at end of file diff --git a/Sledgemapper/Messages/ErrorMessage.cs b/Sledgemapper/Messages/ErrorMessage.cs new file mode 100644 index 0000000..81fe030 --- /dev/null +++ b/Sledgemapper/Messages/ErrorMessage.cs @@ -0,0 +1,12 @@ +namespace Sledgemapper.Messages +{ + public class ErrorMessage : TinyMessenger.TinyMessageBase + { + public string Message { get; } + + public ErrorMessage(object sender, string message) : base(sender) + { + Message = message; + } + } +} \ No newline at end of file diff --git a/Sledgemapper/Messages/LoginSuccessfulMessage.cs b/Sledgemapper/Messages/LoginSuccessfulMessage.cs new file mode 100644 index 0000000..4fb7eec --- /dev/null +++ b/Sledgemapper/Messages/LoginSuccessfulMessage.cs @@ -0,0 +1,12 @@ +namespace Sledgemapper.Messages +{ + public class LoginSuccesfulMessage : TinyMessenger.TinyMessageBase + { + public LoginSuccesfulMessage(object sender) : base(sender) + { + } + + public string UserName { get; internal set; } + public string Initials { get; internal set; } + } +} \ No newline at end of file diff --git a/Sledgemapper/Messages/MapOpenedMessage.cs b/Sledgemapper/Messages/MapOpenedMessage.cs new file mode 100644 index 0000000..baa6ab6 --- /dev/null +++ b/Sledgemapper/Messages/MapOpenedMessage.cs @@ -0,0 +1,16 @@ +using System; + +namespace Sledgemapper.Messages +{ + public class MapOpenedMessage : TinyMessenger.TinyMessageBase + { + public string MapName { get; } + public Guid MapId { get; } + + public MapOpenedMessage(object sender, string mapName, Guid mapId) : base(sender) + { + MapName = mapName; + MapId = mapId; + } + } +} \ No newline at end of file diff --git a/Sledgemapper/Messages/SignalrConnectionUpdateMessage.cs b/Sledgemapper/Messages/SignalrConnectionUpdateMessage.cs new file mode 100644 index 0000000..8cabee6 --- /dev/null +++ b/Sledgemapper/Messages/SignalrConnectionUpdateMessage.cs @@ -0,0 +1,9 @@ +namespace Sledgemapper.Messages +{ + public class SignalrConnectionUpdateMessage : TinyMessenger.TinyMessageBase + { + public SignalrConnectionUpdateMessage(object sender) : base(sender) + { + } + } +} \ No newline at end of file diff --git a/Sledgemapper/ObjectExtensions.cs b/Sledgemapper/ObjectExtensions.cs deleted file mode 100644 index 5749b10..0000000 --- a/Sledgemapper/ObjectExtensions.cs +++ /dev/null @@ -1,131 +0,0 @@ -using System.Collections.Generic; -using System.Reflection; -using System.ArrayExtensions; - -namespace System -{ - public static class ObjectExtensions - { - private static readonly MethodInfo CloneMethod = typeof(object).GetMethod("MemberwiseClone", BindingFlags.NonPublic | BindingFlags.Instance); - - public static bool IsPrimitive(this Type type) - { - if (type == typeof(string)) return true; - return type.IsValueType && type.IsPrimitive; - } - - public static object Copy(this object originalObject) - { - return InternalCopy(originalObject, new Dictionary(new ReferenceEqualityComparer())); - } - private static object InternalCopy(object originalObject, IDictionary visited) - { - if (originalObject == null) return null; - var typeToReflect = originalObject.GetType(); - if (IsPrimitive(typeToReflect)) return originalObject; - if (visited.ContainsKey(originalObject)) return visited[originalObject]; - if (typeof(Delegate).IsAssignableFrom(typeToReflect)) return null; - var cloneObject = CloneMethod.Invoke(originalObject, null); - if (typeToReflect.IsArray) - { - var arrayType = typeToReflect.GetElementType(); - if (!IsPrimitive(arrayType)) - { - Array clonedArray = (Array)cloneObject; - clonedArray.ForEach((array, indices) => array.SetValue(InternalCopy(clonedArray.GetValue(indices), visited), indices)); - } - - } - visited.Add(originalObject, cloneObject); - CopyFields(originalObject, visited, cloneObject, typeToReflect); - RecursiveCopyBaseTypePrivateFields(originalObject, visited, cloneObject, typeToReflect); - return cloneObject; - } - - private static void RecursiveCopyBaseTypePrivateFields(object originalObject, IDictionary visited, object cloneObject, Type typeToReflect) - { - if (typeToReflect.BaseType != null) - { - RecursiveCopyBaseTypePrivateFields(originalObject, visited, cloneObject, typeToReflect.BaseType); - CopyFields(originalObject, visited, cloneObject, typeToReflect.BaseType, BindingFlags.Instance | BindingFlags.NonPublic, info => info.IsPrivate); - } - } - - private static void CopyFields(object originalObject, IDictionary visited, object cloneObject, Type typeToReflect, BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy, Func filter = null) - { - foreach (FieldInfo fieldInfo in typeToReflect.GetFields(bindingFlags)) - { - if (filter != null && !filter(fieldInfo)) continue; - if (IsPrimitive(fieldInfo.FieldType)) continue; - var originalFieldValue = fieldInfo.GetValue(originalObject); - var clonedFieldValue = InternalCopy(originalFieldValue, visited); - fieldInfo.SetValue(cloneObject, clonedFieldValue); - } - } - public static T Copy(this T original) - { - return (T)Copy((object)original); - } - } - - public class ReferenceEqualityComparer : EqualityComparer - { - public override bool Equals(object x, object y) - { - return ReferenceEquals(x, y); - } - public override int GetHashCode(object obj) - { - if (obj == null) return 0; - return obj.GetHashCode(); - } - } - - namespace ArrayExtensions - { - public static class ArrayExtensions - { - public static void ForEach(this Array array, Action action) - { - if (array.LongLength == 0) return; - ArrayTraverse walker = new(array); - do action(array, walker.Position); - while (walker.Step()); - } - } - - internal class ArrayTraverse - { - public int[] Position; - private readonly int[] maxLengths; - - public ArrayTraverse(Array array) - { - maxLengths = new int[array.Rank]; - for (int i = 0; i < array.Rank; ++i) - { - maxLengths[i] = array.GetLength(i) - 1; - } - Position = new int[array.Rank]; - } - - public bool Step() - { - for (int i = 0; i < Position.Length; ++i) - { - if (Position[i] < maxLengths[i]) - { - Position[i]++; - for (int j = 0; j < i; j++) - { - Position[j] = 0; - } - return true; - } - } - return false; - } - } - } - -} \ No newline at end of file diff --git a/Sledgemapper/Program.cs b/Sledgemapper/Program.cs index c61c5d3..58eada1 100644 --- a/Sledgemapper/Program.cs +++ b/Sledgemapper/Program.cs @@ -1,23 +1,52 @@ -using System; -using Exceptionless; +using System; +using System.Text; +using Microsoft.Extensions.Configuration; +using Microsoft.Identity.Client; +using Microsoft.Identity.Client.Extensions.Msal; namespace Sledgemapper { public static class Program { + private static IConfiguration configuration; + public static MsalCacheHelper helper; + [STAThread] static void Main() { - ExceptionlessClient.Default.Configuration.ServerUrl = "https://exceptionless.michelescandura.com"; + var builder = new ConfigurationBuilder() + .SetBasePath(System.IO.Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json"); -#if DEBUG - ExceptionlessClient.Default.Startup("Qvdn6odZRJyGNnorjayMkiwjVsnAK3rNkFtn9bvL"); - #else - ExceptionlessClient.Default.Startup("uprV1LocxAlUPPC9oB4eOlt8jGZ5WypMZKdJCsdL"); -#endif + configuration = builder.Build(); + // Loading PublicClientApplicationOptions from the values set on appsettings.json + + + + // Building StorageCreationProperties + var storageProperties = + new StorageCreationPropertiesBuilder(CacheSettings.CacheFileName, CacheSettings.CacheDir) + .WithLinuxKeyring( + CacheSettings.LinuxKeyRingSchema, + CacheSettings.LinuxKeyRingCollection, + CacheSettings.LinuxKeyRingLabel, + CacheSettings.LinuxKeyRingAttr1, + CacheSettings.LinuxKeyRingAttr2) + .WithMacKeyChain( + CacheSettings.KeyChainServiceName, + CacheSettings.KeyChainAccountName) + .Build(); + // storage = Storage.Create(storageProperties); + + helper = MsalCacheHelper.CreateAsync(storageProperties).Result; + + using (Sentry.SentrySdk.Init("https://973ac1606651454ba7a19f642d0a9bc1@glitchtip.michelescandura.com/1")) using (var game = new Sledgemapper()) + { + Sentry.SentrySdk.CaptureEvent(new Sentry.SentryEvent() { Message = "App starting" }); game.Run(); + } } } } diff --git a/Sledgemapper/Settings.cs b/Sledgemapper/Settings.cs index 3188725..f3aa679 100644 --- a/Sledgemapper/Settings.cs +++ b/Sledgemapper/Settings.cs @@ -1,6 +1,6 @@ using System; -using Exceptionless; using Microsoft.Xna.Framework; +using Sentry; namespace Sledgemapper { @@ -14,7 +14,15 @@ namespace Sledgemapper public int TileDeleteDivider { get; set; } public int PingDuration {get;set;} - public Settings() + private static readonly Settings instance = new (); + + // Explicit static constructor to tell C# compiler + // not to mark type as beforefieldinit + static Settings() + { + } + + private Settings() { BackgroundColor = Color.LightGray; GridColor = Color.Black; @@ -28,9 +36,17 @@ namespace Sledgemapper } catch (Exception ex) { - ExceptionlessClient.Default.SubmitException(ex); + SentrySdk.CaptureException(ex); MachineName = "n/a"; } } + + public static Settings Instance + { + get + { + return instance; + } + } } } diff --git a/Sledgemapper/Sledgemapper.cs b/Sledgemapper/Sledgemapper.cs index 07b9220..57e8de1 100644 --- a/Sledgemapper/Sledgemapper.cs +++ b/Sledgemapper/Sledgemapper.cs @@ -1,695 +1,77 @@ -using Exceptionless; -using Exceptionless.Models; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using AsyncAwaitBestPractices; using Microsoft.AspNetCore.SignalR.Client; using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using MonoGame.Extended; -using MonoGame.Extended.VectorDraw; using Myra; using Myra.Graphics2D.Brushes; using Myra.Graphics2D.TextureAtlases; using Myra.Graphics2D.UI; -using Myra.Graphics2D.UI.File; -using Myra.Graphics2D.UI.Properties; using Myra.Utility; -using Newtonsoft.Json; using Sledgemapper.Shared.Entities; using Sledgemapper.UI; -using System; -using System.Buffers; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using AsyncAwaitBestPractices; +using TinyMessenger; +using Thickness = Myra.Graphics2D.Thickness; namespace Sledgemapper { public class Sledgemapper : Game { private readonly CommunicationManager _communicationManager; - private readonly State _state; - private readonly GraphicsDeviceManager _graphics; - private SpriteBatch _spriteBatch; private readonly Desktop _desktop; - private KeyboardState oldState; - private MouseState oldMouseState; - private Vector3 _viewportCenter = new(0, 0, 0); - private bool _isDraggin; - private Dictionary _fonts; - private Texture2D _eye; - private Texture2D _location; - private Texture2D _comment; + private readonly GraphicsDeviceManager _graphics; + private readonly TinyMessengerHub _messenger; private readonly Session _sessionData; - private AuthenticateResponse _authResponse; - private RenderTarget2D rendertarget; + private readonly State _state; + private CachedContent _cachedContent; + private Texture2D _comment; + private Dictionary _fonts; + private bool _isDragging; + private Label _lblOverlayName; private MainWidget _mainWidget; - private bool _showCellNumbers; - private readonly Settings _settings; + private MouseState _oldMouseState; + private KeyboardState _oldState; + private Effect _outlineShader; + private RenderTarget2D _renderTarget; + private SpriteSheet _rippleSpriteSheet; + private SpriteBatch _spriteBatch; + private SpriteSheet _spriteSheet; + private Texture2D _transparentRedRectangle; + private Dictionary _wallsContent; + private Texture2D _whiteRectangle; public Sledgemapper() { _graphics = new GraphicsDeviceManager(this); _graphics.GraphicsProfile = GraphicsProfile.Reach; - _graphics.PreferMultiSampling = false; - + _graphics.PreferMultiSampling = true; + Content.RootDirectory = "Content"; _desktop = new Desktop(); MyraEnvironment.Game = this; + _sessionData = new Session(); IsFixedTimeStep = true; TargetElapsedTime = TimeSpan.FromSeconds(1d / 30d); - _communicationManager = new CommunicationManager(_sessionData); + _messenger = new TinyMessengerHub(); + _communicationManager = new CommunicationManager(_sessionData,_messenger); _communicationManager.Connection.Reconnected += OnHubReconnected; _communicationManager.Connection.Reconnecting += OnHubReconnecting; _communicationManager.Connection.Closed += OnHubDisconnected; - _state = new State(); - _settings = new Settings(); - _vector2Pool = ArrayPool.Create(); - } - - private async Task OnHubDisconnected(Exception arg) - { - ExceptionlessClient.Default.SubmitEvent(new Event { Message = "Hub disconnected", Type = "SignalR Client Events", Source = _settings.MachineName }); - _mainWidget.lblConnectionStatus.Text = "Disconnected"; - await Task.Yield(); - } - - private async Task OnHubReconnecting(Exception arg) - { - ExceptionlessClient.Default.SubmitEvent(new Event { Message = "Reconnecting Hub", Type = "SignalR Client Events", Source = _settings.MachineName }); - _mainWidget.lblConnectionStatus.Text = "Reconnecting"; - await Task.Yield(); - } - private async Task OnHubReconnected(string arg) - { - ExceptionlessClient.Default.SubmitEvent(new Event { Message = "Hub reconnected", Type = "SignalR Client Events", Source = _settings.MachineName }); - _mainWidget.lblConnectionStatus.Text = "Connected"; - await Task.Yield(); - } - - protected override void Initialize() - { - ExceptionlessClient.Default.SubmitEvent(new Event { Message = "Initialize", Type = "AppLifecycle", Source = _settings.MachineName }); - IsMouseVisible = true; - Window.AllowUserResizing = true; - Window.ClientSizeChanged += OnClientSizeChanged; - - base.Initialize(); - } - - private void ResetRenderTarget() - { - rendertarget = new RenderTarget2D(GraphicsDevice, - GraphicsDevice.Viewport.Width, - GraphicsDevice.Viewport.Height, - false, - SurfaceFormat.Color, - DepthFormat.None, - 0, - RenderTargetUsage.DiscardContents); - } - - private void OnClientSizeChanged(object sender, EventArgs e) - { - rendertarget?.Dispose(); - try - { - ResetRenderTarget(); - } - catch - { - System.Console.WriteLine("rendertarget dispose exception"); - } - - } - - - private void AddItemToToolGrid(Grid grid, EventHandler eventAction, Dictionary tilesFolderContent) - { - var indexX = 0; - var indexY = 0; - foreach (var item in tilesFolderContent) - { - var tileButton = new ImageButton { Image = new TextureRegion(item.Value), GridColumn = indexY, GridRow = indexX, Id = item.Key, Width = 40, Height = 40 }; - tileButton.Click += eventAction; - grid.Widgets.Add(tileButton); - indexY++; - if (indexY == 4) - { - indexY = 0; - indexX++; - } - } - } - - private void AddItemToToolGrid(Grid grid, EventHandler eventAction, SpriteSheet spriteSheet, string e = "") - { - var indexX = 0; - var indexY = 0; - grid.Widgets.Clear(); - _mainWidget.ScrOverlay.ResetScroll(); - foreach (var item in spriteSheet.index.Where(t => String.IsNullOrWhiteSpace(e) || t.Key.ToLower().Contains(e.ToLower()))) - { - var tileButton = new ImageButton { Image = new TextureRegion(spriteSheet.Texture, item.Value), GridColumn = indexY, GridRow = indexX, Id = item.Key, Width = 40, Height = 40 }; - tileButton.Click += eventAction; - tileButton.MouseMoved += OnTileButtonTouchEntered; - tileButton.MouseLeft += OnTileButtonTouchLeft; - grid.Widgets.Add(tileButton); - indexY++; - if (indexY == 4) - { - indexY = 0; - indexX++; - } - } - } - - private void OnTileButtonTouchLeft(object sender, EventArgs e) - { - _desktop.HideContextMenu(); - _lblOverlayName.Visible = false; - } - - private SpriteSheet _rippleSpriteSheet; - Label _lblOverlayName; - - private void OnTileButtonTouchEntered(object sender, EventArgs e) - { - var mouseState = Mouse.GetState().Position; - mouseState.X += 10; - mouseState.Y += 10; - _lblOverlayName.Visible = true; - _lblOverlayName.Text = ((ImageButton)sender).Id; - _desktop.ShowContextMenu(_lblOverlayName, mouseState); - } - - protected override void LoadContent() - { - _spriteBatch = new SpriteBatch(GraphicsDevice); - outlineShader = Content.Load("shaders/OutlineShader"); - MyraEnvironment.Game = this; - ResetRenderTarget(); - - _mainWidget = new MainWidget(); - - _mainWidget.MenuConnectSync.Selected += OnMenuConnectSyncSelected; - _mainWidget.MenuFileLoad.Selected += OnMenuFileLoadSelected; - _mainWidget.MenuFileSave.Selected += OnMenuFileSaveSelected; - _mainWidget.MenuFileSettings.Selected += OneMenuFileSettingsSelected; - _mainWidget.MenuConnectLogin.Selected += OnMenuConnectLoginSelected; - _mainWidget.MenuConnectNew.Selected += OnMenuConnectNewSelected; - _mainWidget.MenuConnectJoin.Selected += OnMenuConnectJoinSelected; - _mainWidget.MenuConnectUpload.Selected += OnMenuConnectUploadSelected; - _mainWidget.MenuViewCenterOnSelection.Selected += OnMenuViewCenterOnSelectionSelected; - _mainWidget.MenuViewShowCellNUmbers.Selected += OnMenuViewShowCellNUmbersSelected; - _mainWidget.MenuViewShowNotes.Selected += OnMenuViewNotesSelected; - _mainWidget.MenuConnectNew.Enabled = false; - _mainWidget.MenuConnectJoin.Enabled = false; - _mainWidget.MenuConnectSync.Enabled = false; - _mainWidget.MenuConnectUpload.Enabled = false; - _mainWidget.BtnToolbarLine.Click += OnBtnToolbarLinClicked; - _mainWidget.BtnToolbarRoom.Click += OnBtnToolbarRoomClicked; - _mainWidget.BtnToolbarDelete.Click += OnBtnToolbarDeleteClicked; - - _wallsContent = Content.LoadContentFolder("walls"); - - _spriteSheet = new SpriteSheet(); - _spriteSheet.LoadContent(Content, "spriteIndex", "sprites"); - _rippleSpriteSheet = new SpriteSheet(); - _rippleSpriteSheet.LoadContent(Content, "handcursorsIndex", "handcursors"); - - _lblOverlayName = new Label(); - _lblOverlayName.Background = new SolidBrush(Color.SlateGray); - _lblOverlayName.Padding = new Myra.Graphics2D.Thickness(4); - - AddItemToToolGrid(_mainWidget.GridWalls, OnWallButtonClicked, _wallsContent); - AddItemToToolGrid(_mainWidget.GridOverlays, OnOverlayButtonClicked, _spriteSheet); - - _fonts = Content.LoadContentFolder("fonts"); - _eye = Content.Load("eye"); - _location = Content.Load("location"); - _comment = Content.Load("comment"); - _mainWidget.BtnToolbarLine.Image = new TextureRegion(Content.Load("icon_line")); - _mainWidget.BtnToolbarRoom.Image = new TextureRegion(Content.Load("icon_room")); - _mainWidget.BtnToolbarDelete.Image = new TextureRegion(Content.Load("icon_delete")); - _mainWidget.TxtOverlaySearch.TextChangedByUser += OnTxtOverlaySearchChange; - - _desktop.Root = _mainWidget; - - _transparentRedRectangle = new Texture2D(GraphicsDevice, 1, 1); - _transparentRedRectangle.SetData(new[] { new Color(Color.Red, 80) }); - - _whiteRectangle = new Texture2D(GraphicsDevice, 1, 1); - _whiteRectangle.SetData(new[] { Color.White }); - } - - private void OnTxtOverlaySearchChange(object sender, ValueChangedEventArgs e) - { - AddItemToToolGrid(_mainWidget.GridOverlays, OnOverlayButtonClicked, _spriteSheet, e.NewValue); - } - - private void OnBtnToolbarDeleteClicked(object sender, EventArgs e) - { - _state.InsertMode = InsertMode.NewDelete; - - _mainWidget.ClearSelection(); - ((ImageTextButton)sender).Border = new SolidBrush(Color.Red); - ((ImageTextButton)sender).BorderThickness = new Myra.Graphics2D.Thickness(2); - } - - private void OnBtnToolbarWallClicked(object sender, EventArgs e) - { - _state.InsertMode = InsertMode.NewWall; - _mainWidget.ClearSelection(); - ((ImageTextButton)sender).Border = new SolidBrush(Color.Red); - ((ImageTextButton)sender).BorderThickness = new Myra.Graphics2D.Thickness(2); - } - - private void OnBtnToolbarTileClicked(object sender, EventArgs e) - { - _state.InsertMode = InsertMode.NewTile; - _mainWidget.ClearSelection(); - ((ImageTextButton)sender).Border = new SolidBrush(Color.Red); - ((ImageTextButton)sender).BorderThickness = new Myra.Graphics2D.Thickness(2); - } - - private void OnBtnToolbarRoomClicked(object sender, EventArgs e) - { - _state.InsertMode = InsertMode.NewRoom; - _mainWidget.ClearSelection(); - ((ImageTextButton)sender).Border = new SolidBrush(Color.Red); - ((ImageTextButton)sender).BorderThickness = new Myra.Graphics2D.Thickness(2); - - } - - private void OnBtnToolbarLinClicked(object sender, EventArgs e) - { - _state.InsertMode = InsertMode.NewLine; - _mainWidget.ClearSelection(); - ((ImageTextButton)sender).Border = new SolidBrush(Color.Red); - ((ImageTextButton)sender).BorderThickness = new Myra.Graphics2D.Thickness(2); - } - - private void OneMenuFileSettingsSelected(object sender, EventArgs e) - { - var propertyGrid = new PropertyGrid - { - Object = _settings, - Width = 350 - }; - - var _windowEditor = new Window - { - Title = "Object Editor", - Content = propertyGrid - }; - _windowEditor.ShowModal(_desktop); - } - - private void OnMenuViewShowCellNUmbersSelected(object sender, EventArgs e) - { - _showCellNumbers = !_showCellNumbers; - } - - private void OnMenuViewCenterOnSelectionSelected(object sender, EventArgs e) - { - CenterOnSelectedTile(); - } - - private void OnMenuViewNotesSelected(object sender, EventArgs e) - { - Window window = new() - { - Title = "Notes" - }; - - var content = new NoteList(); - - for (var i = 0; i < _sessionData.Notes.Values.Count; i++) - { - var note = _sessionData.Notes.Values.ElementAt(i); - var item = new NoteListItem(); - item.LblNoteText.Text = $"{note.ToString()} - {note.Text}"; - item.BtnNoteCenter.Image = new TextureRegion(_location); - item.BtnNoteView.Image = new TextureRegion(_eye); - item.BtnNoteCenter.Click += (s, e) => { CenterOnTile(note.X, note.Y); }; - item.BtnNoteView.Click += (s, e) => { EditNote(note); window.Close(); }; - content.StackNotesList.AddChild(item); - } - - window.Content = content; - window.ShowModal(_desktop); - } - - private void EditNote(Note note) - { - _state.SelectedNote = new Note { X = note.X, Y = note.Y, Text = note.Text }; - var noteWindow = new NoteWindow(); - - Window window = new() - { - Title = $" Note on {note.X}:{note.Y}" - }; - noteWindow.NoteText.Text = note.Text; - noteWindow.BtnOk.Click += OnButtonNoteOkClick; - noteWindow.BtnCancel.Click += OnButtonNoteCancelClick; - - window.Content = noteWindow; - window.ShowModal(_desktop); - noteWindow.NoteText.SetKeyboardFocus(); - } - - protected override void Update(GameTime gameTime) - { - KeyboardState newState = Keyboard.GetState(); - - if (IsActive && GraphicsDevice.Viewport.Bounds.Contains(Mouse.GetState().Position) && !_desktop.IsMouseOverGUI && !_desktop.HasModalWidget) - { - var mouseState = Mouse.GetState(); - - var screenPosition = new Point(mouseState.Position.X - (int)_viewportCenter.X, mouseState.Position.Y - (int)_viewportCenter.Y); - - _state.HoveredTile.X = screenPosition.X / _state.TileSize; - _state.HoveredTile.Y = screenPosition.Y / _state.TileSize; - if (screenPosition.X < 0) - { - _state.HoveredTile.X--; - } - - if (screenPosition.Y < 0) - { - _state.HoveredTile.Y--; - } - - if (_state.InsertMode == InsertMode.Wall) - { - _state.SelectClosestWall(screenPosition); - } - - if (_state.InsertMode == InsertMode.Overlay) - { - _state.SelectOverlay(screenPosition); - } - - if (_state.InsertMode == InsertMode.NewLine || _state.InsertMode == InsertMode.NewRoom || _state.InsertMode == InsertMode.NewDelete) - { - _state.SelectClosestSnapPoint(screenPosition); - } - - if (!newState.IsKeyDown(Keys.LeftControl) && mouseState.LeftButton == ButtonState.Pressed && mouseState.LeftButton == oldMouseState.LeftButton) - { - _viewportCenter = new Vector3(_viewportCenter.X + mouseState.Position.X - oldMouseState.Position.X, _viewportCenter.Y + mouseState.Position.Y - oldMouseState.Position.Y, 0); - if (mouseState.Position != oldMouseState.Position) - { - _isDraggin = true; - } - } - - if (mouseState.LeftButton == ButtonState.Released && mouseState.LeftButton != oldMouseState.LeftButton) - { - if (_isDraggin) - { - _isDraggin = false; - } - else - { - _state.SelectedTile.X = _state.HoveredTile.X; - _state.SelectedTile.Y = _state.HoveredTile.Y; - _communicationManager.Connection?.SendAsync("UpdatePosition", _sessionData.SessionName, _sessionData.SessionId, _state.SelectedTile); - - } - } - - if (mouseState.RightButton == ButtonState.Released && mouseState.RightButton != oldMouseState.RightButton) - { - _state.SelectedNote.X = _state.HoveredTile.X; - _state.SelectedNote.Y = _state.HoveredTile.Y; - - var popup = new VerticalStackPanel { Padding = new Myra.Graphics2D.Thickness(1), Spacing = 2, Background = new SolidBrush(Color.DarkGray) }; - - if (!_sessionData.Notes.ContainsKey(_state.SelectedNote.ToString())) - { - var newNoteButton = new TextButton { Text = "New Note", Width = 80, Height = 20, Padding = new Myra.Graphics2D.Thickness(2), HorizontalAlignment = HorizontalAlignment.Left }; - newNoteButton.Click += OnContextMenuNewNoteClick; - popup.AddChild(newNoteButton); - - - } - else - { - _sessionData.Notes.TryGetValue(_state.SelectedNote.ToString(), out var n); - _state.SelectedNote = n; - var viewNoteButton = new TextButton { Text = "View Note", Width = 80, Height = 20, Padding = new Myra.Graphics2D.Thickness(2), HorizontalAlignment = HorizontalAlignment.Left }; - var deleteNoteButton = new TextButton { Text = "Delete Note", Width = 80, Height = 20, Padding = new Myra.Graphics2D.Thickness(2), HorizontalAlignment = HorizontalAlignment.Left }; - viewNoteButton.Click += OnContextMenuViewNoteClick; - deleteNoteButton.Click += OnContextMenuDeleteNoteClick; - - popup.AddChild(viewNoteButton); - popup.AddChild(deleteNoteButton); - } - - var pingButton = new TextButton { Text = "Ping", Width = 80, Height = 20, Padding = new Myra.Graphics2D.Thickness(2), HorizontalAlignment = HorizontalAlignment.Left }; - var location = new Tile { X = _state.HoveredTile.X, Y = _state.HoveredTile.Y }; - pingButton.Click += (s, e) => OnContextMenuPingClick(s, e, location); - popup.AddChild(pingButton); - - _desktop.ShowContextMenu(popup, mouseState.Position); - } - - if (newState.IsKeyDown(Keys.LeftControl) - && mouseState.LeftButton == ButtonState.Released - && mouseState.LeftButton != oldMouseState.LeftButton) - { - switch (_state.InsertMode) - { - case InsertMode.Tile: - _state.SelectedTile.X = _state.HoveredTile.X; - _state.SelectedTile.Y = _state.HoveredTile.Y; - _communicationManager.Connection?.SendAsync("UpdatePosition", _sessionData.SessionName, _sessionData.SessionId, _state.SelectedTile); - - _sessionData.NewTile(_state.SelectedTile, _state.CurrentTileId); - break; - case InsertMode.Wall: - _sessionData.NewWall(_state.SelectedWall, _state.CurrentWallId); - - break; - case InsertMode.Overlay: - _sessionData.NewOverlay(_state.SelectedOverlay, _state.CurrentOverlayId); - break; - } - } - - - if (_state.InsertMode == InsertMode.NewLine && newState.IsKeyDown(Keys.LeftControl) - && mouseState.LeftButton == ButtonState.Released - && mouseState.LeftButton != oldMouseState.LeftButton) - { - if (_state.LineStart is null) - { - _state.LineStart = new SnapPoint { X = _state.SelectedSnapPoint.X, Y = _state.SelectedSnapPoint.Y, Index = _state.SelectedSnapPoint.Index }; - } - else - { - - var line = new Line - { - Start = new SnapPoint { X = _state.LineStart.X, Y = _state.LineStart.Y, Index = _state.LineStart.Index }, - End = new SnapPoint { X = _state.SelectedSnapPoint.X, Y = _state.SelectedSnapPoint.Y, Index = _state.SelectedSnapPoint.Index }, - Width = _state.LineWidth - }; - _state.LineStart = null; - _state.LineWidth = 1; - _sessionData.NewLine(line); - } - } - - if (_state.InsertMode == InsertMode.NewRoom && newState.IsKeyDown(Keys.LeftControl) - && mouseState.LeftButton == ButtonState.Released - && mouseState.LeftButton != oldMouseState.LeftButton) - { - if (_state.LineStart is null) - { - _state.LineStart = new SnapPoint { X = _state.SelectedSnapPoint.X, Y = _state.SelectedSnapPoint.Y, Index = _state.SelectedSnapPoint.Index }; - } - else - { - - var line = new Room - { - Start = new SnapPoint { X = _state.LineStart.X, Y = _state.LineStart.Y, Index = _state.LineStart.Index }, - End = new SnapPoint { X = _state.SelectedSnapPoint.X, Y = _state.SelectedSnapPoint.Y, Index = _state.SelectedSnapPoint.Index } - }; - _state.LineStart = null; - _state.LineWidth = 1; - _sessionData.NewRoom(line); - } - - } - - - if (_state.InsertMode == InsertMode.NewDelete && newState.IsKeyDown(Keys.LeftControl) - && mouseState.LeftButton == ButtonState.Released - && mouseState.LeftButton != oldMouseState.LeftButton) - { - if (_state.LineStart is null) - { - _state.LineStart = new SnapPoint { X = _state.SelectedSnapPoint.X, Y = _state.SelectedSnapPoint.Y, Index = _state.SelectedSnapPoint.Index }; - } - else - { - - var line = new Room - { - Start = new SnapPoint { X = _state.LineStart.X, Y = _state.LineStart.Y, Index = _state.LineStart.Index }, - End = new SnapPoint { X = _state.SelectedSnapPoint.X, Y = _state.SelectedSnapPoint.Y, Index = _state.SelectedSnapPoint.Index }, - Delete = true - }; - _state.LineStart = null; - _state.LineWidth = 1; - _sessionData.NewRoom(line); - } - - } - - if (_state.InsertMode == InsertMode.NewLine && _state.LineStart != null) - { - if (mouseState.ScrollWheelValue > oldMouseState.ScrollWheelValue) - { - _state.LineWidth += .01f; - } - else if (mouseState.ScrollWheelValue < oldMouseState.ScrollWheelValue) - { - _state.LineWidth -= .01f; - } - } - - if (newState.IsKeyDown(Keys.LeftControl) && mouseState.ScrollWheelValue != oldMouseState.ScrollWheelValue) - { - var maxTileSize = 500; - var center = new Point((Window.ClientBounds.Width + 200) / 2 - _state.TileSize / 2, Window.ClientBounds.Height / 2 - _state.TileSize / 2); - - var tx = (center.X - (int)_viewportCenter.X) / _state.TileSize; - var ty = (center.Y - (int)_viewportCenter.Y) / _state.TileSize; - - if (mouseState.ScrollWheelValue > oldMouseState.ScrollWheelValue) - { - _state.TileSize = Math.Min(maxTileSize, _state.TileSize + 10); - - } - else if (mouseState.ScrollWheelValue < oldMouseState.ScrollWheelValue) - { - _state.TileSize = Math.Max(10, _state.TileSize - 10); - } - - CenterOnTile(tx, ty); - } - - oldMouseState = mouseState; - } - - - if (newState.IsKeyDown(Keys.Delete)) - { - switch (_state.InsertMode) - { - case InsertMode.Tile: - case InsertMode.NewRoom: - case InsertMode.NewLine: - case InsertMode.NewDelete: - _state.SelectedTile.X = _state.HoveredTile.X; - _state.SelectedTile.Y = _state.HoveredTile.Y; - _sessionData.DeleteTile(_state.SelectedTile); - break; - case InsertMode.Wall: - _sessionData.DeleteWall(_state.SelectedWall); - break; - case InsertMode.Overlay: - _sessionData.DeleteOverlay(_state.SelectedOverlay); - break; - } - } - - if (oldState.IsKeyDown(Keys.P) && newState.IsKeyUp(Keys.P)) - { - _communicationManager.Ping(_state.HoveredTile).SafeFireAndForget(); - } - - foreach (var key in newState.GetPressedKeys()) - { - switch (key) - { - case Keys.Left: - if (oldState.IsKeyUp(Keys.Left) && newState.IsKeyDown(Keys.Left)) - { - _state.SelectedTile.X--; - _communicationManager.Connection?.SendAsync("UpdatePosition", _sessionData.SessionName, _state.SelectedTile); - } - break; - case Keys.Right: - if (oldState.IsKeyUp(Keys.Right) && newState.IsKeyDown(Keys.Right)) - { - _state.SelectedTile.X++; - _communicationManager.Connection?.SendAsync("UpdatePosition", _sessionData.SessionName, _state.SelectedTile); - } - break; - case Keys.Up: - if (oldState.IsKeyUp(Keys.Up) && newState.IsKeyDown(Keys.Up)) - { - _state.SelectedTile.Y--; - _communicationManager.Connection?.SendAsync("UpdatePosition", _sessionData.SessionName, _state.SelectedTile); - } - break; - case Keys.Down: - if (oldState.IsKeyUp(Keys.Down) && newState.IsKeyDown(Keys.Down)) - { - _state.SelectedTile.Y++; - _communicationManager.Connection?.SendAsync("UpdatePosition", _sessionData.SessionName, _state.SelectedTile); - } - break; - } - - } - - oldState = newState; - - base.Update(gameTime); - } - - private void CenterOnSelectedTile() - { - CenterOnTile(_state.SelectedTile.X, _state.SelectedTile.Y); - } - - private void CenterOnTile(int x, int y) - { - var center = new Point((Window.ClientBounds.Width + 200) / 2 - _state.TileSize / 2, Window.ClientBounds.Height / 2 - _state.TileSize / 2); - var dx = center.X - x * _state.TileSize - _viewportCenter.X; - var dy = center.Y - y * _state.TileSize - _viewportCenter.Y; - - _viewportCenter.X += dx; - _viewportCenter.Y += dy; - } - - private void OnContextMenuPingClick(object sender, EventArgs e, Tile location) - { - _desktop.HideContextMenu(); - _communicationManager.Ping(location).SafeFireAndForget(); + _state = State.Instance; } protected override void Draw(GameTime gameTime) { - if (_spriteBatch is null) - { - return; - } + if (_spriteBatch is null) return; var visibleTilesX = GraphicsDevice.Viewport.Width / _state.TileSize + 1; var visibleTilesY = GraphicsDevice.Viewport.Height / _state.TileSize + 1; @@ -697,8 +79,8 @@ namespace Sledgemapper ApplyShaderToMap(); _spriteBatch.Begin( - transformMatrix: Matrix.CreateTranslation(_viewportCenter), - sortMode: SpriteSortMode.Texture, samplerState: SamplerState.PointClamp); + transformMatrix: Matrix.CreateTranslation(_state.ViewportCenter), + sortMode: SpriteSortMode.Texture, samplerState: SamplerState.PointClamp); DrawTiles(); @@ -732,255 +114,685 @@ namespace Sledgemapper } catch { - System.Console.WriteLine("Desktop render error"); + Console.WriteLine("Desktop render error"); } + base.Draw(gameTime); } - private void DrawRipple(GameTime gameTime) + protected override void Initialize() { - _spriteBatch.Begin( - blendState: BlendState.NonPremultiplied, - transformMatrix: Matrix.CreateTranslation(_viewportCenter)); + // ExceptionlessClient.Default.SubmitEvent(new Event { Message = "Initialize", Type = "AppLifecycle", Source = _settings.MachineName }); + IsMouseVisible = true; + Window.AllowUserResizing = true; + Window.ClientSizeChanged += OnClientSizeChanged; + base.Initialize(); + } - var durationMs = 2000; - var baseRadius = _state.TileSize / 4f; - var baseOuterRadius = (float)_state.TileSize; - var iterations = 3f; - var guids = _sessionData.Pings.Keys.ToArray(); + protected override void LoadContent() + { + _spriteBatch = new SpriteBatch(GraphicsDevice); + _cachedContent = CachedContent.Instance; - foreach (var guid in guids) + _outlineShader = Content.Load("shaders/OutlineShader"); + MyraEnvironment.Game = this; + ResetRenderTarget(); + // Inform Myra that external text input is available + // So it stops translating Keys to chars + _desktop.HasExternalTextInput = true; + + // Provide that text input + Window.TextInput += (s, a) => { - var pingFound = _sessionData.Pings.TryGetValue(guid, out var ping); - if (!pingFound) + _desktop.OnChar(a.Character); + + }; + + _mainWidget = new MainWidget(_communicationManager, _messenger, Window); + _communicationManager.CheckLogin(); + + _wallsContent = Content.LoadContentFolder("walls"); + + _spriteSheet = new SpriteSheet(); + _spriteSheet.LoadContent(Content, "spriteIndex", "sprites"); + _rippleSpriteSheet = new SpriteSheet(); + _rippleSpriteSheet.LoadContent(Content, "handcursorsIndex", "handcursors"); + + _lblOverlayName = new Label + { + Background = new SolidBrush(Color.SlateGray), + Padding = new Thickness(4) + }; + + AddItemToToolGrid(_mainWidget.GridWalls, OnWallButtonClicked, _wallsContent); + AddItemToToolGrid(_mainWidget.GridOverlays, OnOverlayButtonClicked, _spriteSheet); + + _fonts = Content.LoadContentFolder("fonts"); + _cachedContent.Eye = Content.Load("eye"); + _cachedContent.Location = Content.Load("location"); + _comment = Content.Load("comment"); + _mainWidget.BtnToolbarLine.Image = new TextureRegion(Content.Load("icon_line")); + _mainWidget.BtnToolbarRoom.Image = new TextureRegion(Content.Load("icon_room")); + _mainWidget.BtnToolbarDelete.Image = new TextureRegion(Content.Load("icon_delete")); + _mainWidget.TxtOverlaySearch.TextChangedByUser += OnTxtOverlaySearchChange; + + _desktop.Root = _mainWidget; + + _transparentRedRectangle = new Texture2D(GraphicsDevice, 1, 1); + _transparentRedRectangle.SetData(new[] { new Color(Color.Red, 80) }); + + _whiteRectangle = new Texture2D(GraphicsDevice, 1, 1); + _whiteRectangle.SetData(new[] { Color.White }); + + CenterOnTile(0, 0); + } + + protected override void Update(GameTime gameTime) + { + var newState = Keyboard.GetState(); + + if (IsActive && GraphicsDevice.Viewport.Bounds.Contains(Mouse.GetState().Position) && + !_desktop.IsMouseOverGUI && !_desktop.HasModalWidget) + { + var mouseState = Mouse.GetState(); + + var screenPosition = new Point(mouseState.Position.X - (int)_state.ViewportCenter.X, + mouseState.Position.Y - (int)_state.ViewportCenter.Y); + + if (!_desktop.ContextMenu?.Visible ?? true) { - continue; + _state.HoveredTile.X = screenPosition.X / _state.TileSize; + _state.HoveredTile.Y = screenPosition.Y / _state.TileSize; + + + if (screenPosition.X < 0) _state.HoveredTile.X--; + + if (screenPosition.Y < 0) _state.HoveredTile.Y--; } - if (ping.StartTime == 0) + if (_state.InsertMode == InsertMode.Wall) _state.SelectClosestWall(screenPosition); + + if (_state.InsertMode == InsertMode.Overlay) _state.SelectOverlay(screenPosition); + + if (_state.InsertMode == InsertMode.NewLine || _state.InsertMode == InsertMode.NewRoom || + _state.InsertMode == InsertMode.NewDelete) _state.SelectClosestSnapPoint(screenPosition); + + if (!newState.IsKeyDown(Keys.LeftControl) && mouseState.LeftButton == ButtonState.Pressed && + mouseState.LeftButton == _oldMouseState.LeftButton && + !_desktop.IsMouseOverGUI + ) { - ping.StartTime = gameTime.TotalGameTime.TotalMilliseconds; + _state.ViewportCenter = + new Vector3(_state.ViewportCenter.X + mouseState.Position.X - _oldMouseState.Position.X, + _state.ViewportCenter.Y + mouseState.Position.Y - _oldMouseState.Position.Y, 0); + if (mouseState.Position != _oldMouseState.Position) _isDragging = true; } - var x = ping.X * _state.TileSize + _state.TileSize / 2f; - var y = ping.Y * _state.TileSize + _state.TileSize / 2f; - - if (IsOffscreen(new Tile { X = ping.X, Y = ping.Y })) + if (mouseState.LeftButton == ButtonState.Released && mouseState.LeftButton != _oldMouseState.LeftButton) { - DrawPingPointer(ping, gameTime); - } - else - { - - _spriteBatch.DrawCircle( - center: new Vector2(x, y), - radius: baseRadius, - sides: 20, - color: ping.Player.Color.ToColor(), - thickness: baseRadius); - - for (var i = 0; i < iterations; i++) + if (_isDragging) { - var cycleTime = (((float)gameTime.TotalGameTime.TotalMilliseconds + (float)i * durationMs / iterations) % durationMs) / durationMs; - var easing = Easings.Interpolate(cycleTime, Easings.Functions.SineEaseInOut); - _spriteBatch.DrawCircle( - center: new Vector2(x, y), - radius: baseRadius + baseOuterRadius * easing, - sides: 20, - color: new Color(ping.Player.Color.ToColor(), (1 - easing)), - thickness: 2 + 5 * (1 - easing)); - - + _isDragging = false; + } + else + { + _state.SelectedTile.X = _state.HoveredTile.X; + _state.SelectedTile.Y = _state.HoveredTile.Y; + _communicationManager.Connection?.SendAsync("UpdatePosition", State.Instance.MapName, + State.Instance.MapId, _state.SelectedTile); } } + + if (mouseState.RightButton == ButtonState.Released && + mouseState.RightButton != _oldMouseState.RightButton) + { + _state.SelectedNote.X = _state.HoveredTile.X; + _state.SelectedNote.Y = _state.HoveredTile.Y; + + var popup = new VerticalStackPanel + { Padding = new Thickness(1), Spacing = 2, Background = new SolidBrush(Color.DarkGray) }; + + if (!_sessionData.Notes.ContainsKey(_state.SelectedNote.ToString())) + { + var newNoteButton = new TextButton + { + Text = "New Note", Width = 80, Height = 20, Padding = new Thickness(2), + HorizontalAlignment = HorizontalAlignment.Left + }; + newNoteButton.Click += OnContextMenuNewNoteClick; + popup.AddChild(newNoteButton); + } + else + { + _sessionData.Notes.TryGetValue(_state.SelectedNote.ToString(), out var n); + _state.SelectedNote = new Note(n); + var viewNoteButton = new TextButton + { + Text = "View Note", Width = 80, Height = 20, Padding = new Thickness(2), + HorizontalAlignment = HorizontalAlignment.Left + }; + var deleteNoteButton = new TextButton + { + Text = "Delete Note", Width = 80, Height = 20, Padding = new Thickness(2), + HorizontalAlignment = HorizontalAlignment.Left + }; + viewNoteButton.Click += OnContextMenuViewNoteClick; + deleteNoteButton.Click += OnContextMenuDeleteNoteClick; + + popup.AddChild(viewNoteButton); + popup.AddChild(deleteNoteButton); + } + + var pingButton = new TextButton + { + Text = "Ping", Width = 80, Height = 20, Padding = new Thickness(2), + HorizontalAlignment = HorizontalAlignment.Left + }; + var location = new Tile { X = _state.HoveredTile.X, Y = _state.HoveredTile.Y }; + pingButton.Click += (s, e) => OnContextMenuPingClick(s, e, location); + popup.AddChild(pingButton); + + _desktop.ShowContextMenu(popup, mouseState.Position); + } + + if (newState.IsKeyDown(Keys.LeftControl) + && mouseState.LeftButton == ButtonState.Released + && mouseState.LeftButton != _oldMouseState.LeftButton) + switch (_state.InsertMode) + { + case InsertMode.Tile: + _state.SelectedTile.X = _state.HoveredTile.X; + _state.SelectedTile.Y = _state.HoveredTile.Y; + _communicationManager.Connection?.SendAsync("UpdatePosition", State.Instance.MapName, + State.Instance.MapId, _state.SelectedTile); + + _sessionData.NewTile(_state.SelectedTile, _state.CurrentTileId); + break; + case InsertMode.Wall: + _sessionData.NewWall(_state.SelectedWall, _state.CurrentWallId); + + break; + case InsertMode.Overlay: + _sessionData.NewOverlay(_state.SelectedOverlay, _state.CurrentOverlayId); + break; + } + + + if (_state.InsertMode == InsertMode.NewLine && newState.IsKeyDown(Keys.LeftControl) + && mouseState.LeftButton == ButtonState.Released + && mouseState.LeftButton != _oldMouseState.LeftButton) + { + if (_state.LineStart is null) + { + _state.LineStart = new SnapPoint + { + X = _state.SelectedSnapPoint.X, Y = _state.SelectedSnapPoint.Y, + Index = _state.SelectedSnapPoint.Index + }; + } + else + { + var line = new Line + { + Start = new SnapPoint + { X = _state.LineStart.X, Y = _state.LineStart.Y, Index = _state.LineStart.Index }, + End = new SnapPoint + { + X = _state.SelectedSnapPoint.X, Y = _state.SelectedSnapPoint.Y, + Index = _state.SelectedSnapPoint.Index + }, + Width = _state.LineWidth + }; + _state.LineStart = null; + _state.LineWidth = 1; + _sessionData.NewLine(line); + } + } + + if (_state.InsertMode == InsertMode.NewRoom && newState.IsKeyDown(Keys.LeftControl) + && mouseState.LeftButton == ButtonState.Released + && mouseState.LeftButton != _oldMouseState.LeftButton) + { + if (_state.LineStart is null) + { + _state.LineStart = new SnapPoint + { + X = _state.SelectedSnapPoint.X, Y = _state.SelectedSnapPoint.Y, + Index = _state.SelectedSnapPoint.Index + }; + } + else + { + var line = new Room + { + Start = new SnapPoint + { X = _state.LineStart.X, Y = _state.LineStart.Y, Index = _state.LineStart.Index }, + End = new SnapPoint + { + X = _state.SelectedSnapPoint.X, Y = _state.SelectedSnapPoint.Y, + Index = _state.SelectedSnapPoint.Index + } + }; + _state.LineStart = null; + _state.LineWidth = 1; + _sessionData.NewRoom(line); + } + } + + + if (_state.InsertMode == InsertMode.NewDelete && newState.IsKeyDown(Keys.LeftControl) + && mouseState.LeftButton == ButtonState.Released + && mouseState.LeftButton != _oldMouseState.LeftButton) + { + if (_state.LineStart is null) + { + _state.LineStart = new SnapPoint + { + X = _state.SelectedSnapPoint.X, Y = _state.SelectedSnapPoint.Y, + Index = _state.SelectedSnapPoint.Index + }; + } + else + { + var line = new Room + { + Start = new SnapPoint + { X = _state.LineStart.X, Y = _state.LineStart.Y, Index = _state.LineStart.Index }, + End = new SnapPoint + { + X = _state.SelectedSnapPoint.X, Y = _state.SelectedSnapPoint.Y, + Index = _state.SelectedSnapPoint.Index + }, + Delete = true + }; + _state.LineStart = null; + _state.LineWidth = 1; + _sessionData.NewRoom(line); + } + } + + if (_state.InsertMode == InsertMode.NewLine && _state.LineStart != null) + { + if (mouseState.ScrollWheelValue > _oldMouseState.ScrollWheelValue) + _state.LineWidth += .01f; + else if (mouseState.ScrollWheelValue < _oldMouseState.ScrollWheelValue) _state.LineWidth -= .01f; + } + + if (newState.IsKeyDown(Keys.LeftControl) && + mouseState.ScrollWheelValue != _oldMouseState.ScrollWheelValue) + { + var maxTileSize = 500; + var center = new Point((Window.ClientBounds.Width + 200) / 2 - _state.TileSize / 2, + Window.ClientBounds.Height / 2 - _state.TileSize / 2); + + var tx = (center.X - (int)_state.ViewportCenter.X) / _state.TileSize; + var ty = (center.Y - (int)_state.ViewportCenter.Y) / _state.TileSize; + + if (mouseState.ScrollWheelValue > _oldMouseState.ScrollWheelValue) + _state.TileSize = Math.Min(maxTileSize, _state.TileSize + 10); + else if (mouseState.ScrollWheelValue < _oldMouseState.ScrollWheelValue) + _state.TileSize = Math.Max(10, _state.TileSize - 10); + + CenterOnTile(tx, ty); + } + + _oldMouseState = mouseState; } - foreach (var guid in guids) + + + if (newState.IsKeyDown(Keys.Delete)) + switch (_state.InsertMode) + { + case InsertMode.Tile: + case InsertMode.NewRoom: + case InsertMode.NewLine: + case InsertMode.NewDelete: + _state.SelectedTile.X = _state.HoveredTile.X; + _state.SelectedTile.Y = _state.HoveredTile.Y; + _sessionData.DeleteTile(_state.SelectedTile); + break; + case InsertMode.Wall: + _sessionData.DeleteWall(_state.SelectedWall); + break; + case InsertMode.Overlay: + _sessionData.DeleteOverlay(_state.SelectedOverlay); + break; + } + + if (_oldState.IsKeyDown(Keys.P) && newState.IsKeyUp(Keys.P)) + _communicationManager.Ping(_state.HoveredTile).SafeFireAndForget(); + + foreach (var key in newState.GetPressedKeys()) + switch (key) + { + case Keys.Left: + if (_oldState.IsKeyUp(Keys.Left) && newState.IsKeyDown(Keys.Left)) + { + _state.SelectedTile.X--; + _communicationManager.Connection?.SendAsync("UpdatePosition", State.Instance.MapId, + _state.SelectedTile); + } + + break; + case Keys.Right: + if (_oldState.IsKeyUp(Keys.Right) && newState.IsKeyDown(Keys.Right)) + { + _state.SelectedTile.X++; + _communicationManager.Connection?.SendAsync("UpdatePosition", State.Instance.MapId, + _state.SelectedTile); + } + + break; + case Keys.Up: + if (_oldState.IsKeyUp(Keys.Up) && newState.IsKeyDown(Keys.Up)) + { + _state.SelectedTile.Y--; + _communicationManager.Connection?.SendAsync("UpdatePosition", State.Instance.MapId, + _state.SelectedTile); + } + + break; + case Keys.Down: + if (_oldState.IsKeyUp(Keys.Down) && newState.IsKeyDown(Keys.Down)) + { + _state.SelectedTile.Y++; + _communicationManager.Connection?.SendAsync("UpdatePosition", State.Instance.MapId, + _state.SelectedTile); + } + + break; + } + + _oldState = newState; + + base.Update(gameTime); + } + + private void AddItemToToolGrid(Grid grid, EventHandler eventAction, Dictionary tilesFolderContent) + { + var indexX = 0; + var indexY = 0; + foreach (var item in tilesFolderContent) { - var pingFound = _sessionData.Pings.TryGetValue(guid, out var ping); - if (!pingFound) + var tileButton = new ImageButton { - continue; - } - - if ((gameTime.TotalGameTime.TotalMilliseconds - ping.StartTime) > _settings.PingDuration) + Image = new TextureRegion(item.Value), GridColumn = indexY, GridRow = indexX, Id = item.Key, + Width = 40, Height = 40 + }; + tileButton.Click += eventAction; + grid.Widgets.Add(tileButton); + indexY++; + if (indexY == 4) { - _sessionData.Pings.TryRemove(guid, out var _); + indexY = 0; + indexX++; } } + } + private void AddItemToToolGrid(Grid grid, EventHandler eventAction, SpriteSheet spriteSheet, string e = "") + { + var indexX = 0; + var indexY = 0; + grid.Widgets.Clear(); + _mainWidget.ScrOverlay.ResetScroll(); + foreach (var item in spriteSheet.index.Where(t => + string.IsNullOrWhiteSpace(e) || t.Key.ToLower().Contains(e.ToLower()))) + { + var tileButton = new ImageButton + { + Image = new TextureRegion(spriteSheet.Texture, item.Value), GridColumn = indexY, GridRow = indexX, + Id = item.Key, Width = 40, Height = 40 + }; + tileButton.Click += eventAction; + tileButton.MouseMoved += OnTileButtonTouchEntered; + tileButton.MouseLeft += OnTileButtonTouchLeft; + grid.Widgets.Add(tileButton); + indexY++; + if (indexY == 4) + { + indexY = 0; + indexX++; + } + } + } + private void ApplyShaderToMap() + { + var texelSize = new Vector2(_renderTarget.Width, _renderTarget.Height); + _outlineShader.Parameters["ImageSize"].SetValue(texelSize); + _outlineShader.Parameters["BorderSize"].SetValue((int)(_state.TileSize / 100f * 10f)); + + _outlineShader.Parameters["R"].SetValue(Settings.Instance.OverlayTintColor.R / 255.0f); + _outlineShader.Parameters["G"].SetValue(Settings.Instance.OverlayTintColor.G / 255.0f); + _outlineShader.Parameters["B"].SetValue(Settings.Instance.OverlayTintColor.B / 255.0f); + + GraphicsDevice.Clear(Settings.Instance.BackgroundColor); + + _spriteBatch.Begin( + effect: _outlineShader, + sortMode: SpriteSortMode.Immediate); + _spriteBatch.Draw(_renderTarget, Vector2.Zero, null, Color.White); _spriteBatch.End(); } - private void DrawRoomPreview() + private void CenterOnTile(int x, int y) { - if ((_state.InsertMode == InsertMode.NewRoom || _state.InsertMode == InsertMode.NewDelete) && _state.SelectedSnapPoint != null) + var center = new Point((Window.ClientBounds.Width + 200) / 2 - _state.TileSize / 2, + Window.ClientBounds.Height / 2 - _state.TileSize / 2); + var dx = center.X - x * _state.TileSize - _state.ViewportCenter.X; + var dy = center.Y - y * _state.TileSize - _state.ViewportCenter.Y; + _state.ViewportCenter = new Vector3(_state.ViewportCenter.X + dx, _state.ViewportCenter.Y + dy, + _state.ViewportCenter.Z); + } + + private void DrawDelete(Room tile) + { + var posX = tile.Start.X * _state.TileSize; + var posY = tile.Start.Y * _state.TileSize; + + var endposX = tile.End.X * _state.TileSize; + var endposY = tile.End.Y * _state.TileSize; + + + var ww = _state.TileSize / Settings.Instance.TileDeleteDivider; + if (posX == endposX) { - var snapPoint = new Vector2(_state.SelectedSnapPoint.X * _state.TileSize, _state.SelectedSnapPoint.Y * _state.TileSize); + endposX += ww; + posX -= ww; + } - switch (_state.SelectedSnapPoint.Index) + if (posY == endposY) + { + endposY += ww; + posY -= ww; + } + + switch (tile.Start.Index) + { + case 1: + break; + case 2: + posX += _state.TileSize / 2; + break; + case 3: + posY += _state.TileSize / 2; + + break; + case 4: + posX += _state.TileSize / 2; + posY += _state.TileSize / 2; + break; + } + + switch (tile.End.Index) + { + case 1: + break; + case 2: + endposX += _state.TileSize / 2; + break; + case 3: + endposY += _state.TileSize / 2; + + break; + case 4: + endposX += _state.TileSize / 2; + endposY += _state.TileSize / 2; + break; + } + + if (posX != endposX && posY != endposY) + { + var r = new Rectangle(); + + if (posX < endposX && posY < endposY) { - case 1: - break; - case 2: - snapPoint.X += _state.TileSize / 2; - break; - case 3: - snapPoint.Y += _state.TileSize / 2; - break; - case 4: - snapPoint.Y += _state.TileSize / 2; - snapPoint.X += _state.TileSize / 2; - break; + r = new Rectangle(posX, posY, endposX - posX, endposY - posY); + } + else if (posX > endposX && posY > endposY) + { + r = new Rectangle(posX, posY, endposX - posX, endposY - posY); + } + else + { + if (endposY < posY) r = new Rectangle(posX, endposY, endposX - posX, posY - endposY); + if (endposX < posX) r = new Rectangle(endposX, posY, posX - endposX, endposY - posY); } - _spriteBatch.DrawCircle(snapPoint, _state.TileSize / 6f, 50, Color.Red, 2); + _spriteBatch.Draw(_whiteRectangle, r, null, Color.Black, 0, Vector2.Zero, SpriteEffects.None, 1); + } + } - if (_state.LineStart != null) + private void DrawGrid(int visibleTilesX, int visibleTilesY) + { + for (var i = -1; i < visibleTilesX + 3; i++) + { + var posX1 = i * _state.TileSize - _state.ViewportCenter.X; + var posY1 = -_state.ViewportCenter.Y; + posX1 -= posX1 % _state.TileSize; + posY1 -= posY1 % _state.TileSize; + var posX2 = i * _state.TileSize - _state.ViewportCenter.X; + var posY2 = GraphicsDevice.Viewport.Height - _state.ViewportCenter.Y; + posX2 -= posX2 % _state.TileSize; + posY2 -= posY2 % _state.TileSize; + + _spriteBatch.DrawLine( + posX1, posY1, + posX2, + posY2+ _state.TileSize, + Settings.Instance.GridColor); + } + + for (var i = -1; i < visibleTilesY + 2; i++) + { + var posX1 = -_state.ViewportCenter.X; + var posY1 = i * _state.TileSize - _state.ViewportCenter.Y; + posX1 -= posX1 % _state.TileSize; + posY1 -= posY1 % _state.TileSize; + var posX2 = GraphicsDevice.Viewport.Width - _state.ViewportCenter.X; + var posY2 = i * _state.TileSize - _state.ViewportCenter.Y; + posX2 -= posX2 % _state.TileSize; + posY2 -= posY2 % _state.TileSize; + + _spriteBatch.DrawLine(posX1, posY1, + posX2 + _state.TileSize, + posY2, + Settings.Instance.GridColor); + } + + + if (_state.ShowCellNumbers && _state.TileSize >= 30) + { + var ffont = + _fonts.FirstOrDefault(m => int.Parse(m.Key.Replace("font", "")) > _state.TileSize / 8).Value ?? + _fonts.Last().Value; + var fscale = 1f; + + for (var i = -1; i < visibleTilesX + 2; i++) + for (var j = -1; j < visibleTilesY + 2; j++) { - var posX = _state.LineStart.X * _state.TileSize; - var posY = _state.LineStart.Y * _state.TileSize; + var screenPosition = new Point(i * _state.TileSize - (int)_state.ViewportCenter.X, + j * _state.TileSize - (int)_state.ViewportCenter.Y); - var endposX = _state.SelectedSnapPoint.X * _state.TileSize; - var endposY = _state.SelectedSnapPoint.Y * _state.TileSize; - if (_state.InsertMode == InsertMode.NewDelete) - { - var ww = _state.TileSize / _settings.TileDeleteDivider; - if (posX == endposX) { endposX += ww; posX -= ww; } - if (posY == endposY) { endposY += ww; posY -= ww; } - } - switch (_state.LineStart.Index) - { - case 1: - break; - case 2: - posX += _state.TileSize / 2; - break; - case 3: - posY += _state.TileSize / 2; + var x = screenPosition.X / _state.TileSize; + var y = screenPosition.Y / _state.TileSize; - break; - case 4: - posX += _state.TileSize / 2; - posY += _state.TileSize / 2; - break; - } - - switch (_state.SelectedSnapPoint.Index) - { - case 1: - break; - case 2: - endposX += _state.TileSize / 2; - break; - case 3: - endposY += _state.TileSize / 2; - - break; - case 4: - endposX += _state.TileSize / 2; - endposY += _state.TileSize / 2; - break; - } - - var ffont = _fonts.FirstOrDefault(m => int.Parse(m.Key.Replace("font", "")) > _state.TileSize / 3).Value ?? _fonts.Last().Value; - var fscale = 1.2f; - var width = Math.Abs((endposX - posX)); - var height = Math.Abs((posY - endposY)); - var tilesWidth = width / (double)_state.TileSize; - var tilesHeight = height / (double)_state.TileSize; - tilesWidth = Math.Round(tilesWidth * 2, MidpointRounding.AwayFromZero) / 2; - tilesHeight = Math.Round(tilesHeight * 2, MidpointRounding.AwayFromZero) / 2; - var xmeasure = ffont.MeasureString($"{tilesWidth}"); - var ymeasure = ffont.MeasureString($"{tilesHeight}"); - float widthX = 0, widthY = 0, heightX = 0, heightY = 0; - - Rectangle area = new Rectangle(); - if (posX != endposX && posY != endposY) - { - if ((posX > endposX && posY > endposY) || (posX < endposX && posY < endposY)) - { - area = new Rectangle(posX, posY, endposX - posX, endposY - posY); - - if (posX > endposX && posY > endposY) - { - widthX = endposX + (width / 2) - xmeasure.X / 2; - widthY = endposY - ymeasure.Y * 1.2f; - - heightX = posX + xmeasure.X / 2; - heightY = endposY + (height / 2) - ymeasure.Y / 2; - } - else if (posX < endposX && posY < endposY) - { - widthX = posX + (width / 2) - xmeasure.X / 2; - widthY = posY - ymeasure.Y * 1.2f; - - heightX = endposX + xmeasure.X / 2; - heightY = posY + (height / 2) - ymeasure.Y / 2; - } - } - else - { - if (endposY < posY) - { - area = new Rectangle(posX, endposY, endposX - posX, posY - endposY); - - widthX = posX + (width / 2) - xmeasure.X / 2; - widthY = endposY - ymeasure.Y * 1.2f; - - heightX = endposX + xmeasure.X / 2; - heightY = endposY + (height / 2) - ymeasure.Y / 2; - } - - if (endposX < posX) - { - area = new Rectangle(endposX, posY, posX - endposX, endposY - posY); - - widthX = endposX + (width / 2) - xmeasure.X / 2; - widthY = posY - ymeasure.Y * 1.2f; - - heightX = posX + xmeasure.X / 2; - heightY = posY + (height / 2) - ymeasure.Y / 2; - } - } - - _spriteBatch.Draw(_transparentRedRectangle, area, null, Color.White, 0, new Vector2(0, 0), SpriteEffects.None, 1); - - _spriteBatch.DrawString(ffont, - $"{tilesWidth}", - new Vector2( - widthX, - widthY - ), - Color.Red, - 0, - Vector2.Zero, - fscale, - SpriteEffects.None, - 0); - - _spriteBatch.DrawString(ffont, - $"{tilesHeight}", - new Vector2( - heightX, heightY - ), - Color.Red, - 0, - Vector2.Zero, - fscale, - SpriteEffects.None, - 0); - - } + _spriteBatch.DrawString(ffont, + $"{x}:{y}", + new Vector2( + x * _state.TileSize + 2, + y * _state.TileSize + 2 + ), + Color.Black, + 0, + Vector2.Zero, + fscale, + SpriteEffects.None, + 0); } } } + private void DrawLine(Line tile) + { + var posX = tile.Start.X * _state.TileSize; + var posY = tile.Start.Y * _state.TileSize; + + var endposX = tile.End.X * _state.TileSize; + var endposY = tile.End.Y * _state.TileSize; + + switch (tile.Start.Index) + { + case 1: + break; + case 2: + posX += _state.TileSize / 2; + break; + case 3: + posY += _state.TileSize / 2; + + break; + case 4: + posX += _state.TileSize / 2; + posY += _state.TileSize / 2; + break; + } + + switch (tile.End.Index) + { + case 1: + break; + case 2: + endposX += _state.TileSize / 2; + break; + case 3: + endposY += _state.TileSize / 2; + + break; + case 4: + endposX += _state.TileSize / 2; + endposY += _state.TileSize / 2; + break; + } + + var length = (int)Math.Sqrt(Math.Pow(posX - endposX, 2) + Math.Pow(posY - endposY, 2)); + var height = (int)(_state.TileSize * tile.Width); + if (length > 0) + { + var angle = Math.Atan2(posY - endposY, endposX - posX); + var angleRad = -(float)angle; + _spriteBatch.Draw(_whiteRectangle, new Rectangle(posX, posY, length, height), null, Color.White, + angleRad, new Vector2(0, 0), SpriteEffects.None, 1); + } + } + private void DrawLinePreview() { if (_state.InsertMode == InsertMode.NewLine && _state.SelectedSnapPoint != null) { - var snapPoint = new Vector2(_state.SelectedSnapPoint.X * _state.TileSize, _state.SelectedSnapPoint.Y * _state.TileSize); + var snapPoint = new Vector2(_state.SelectedSnapPoint.X * _state.TileSize, + _state.SelectedSnapPoint.Y * _state.TileSize); switch (_state.SelectedSnapPoint.Index) { @@ -1047,89 +859,30 @@ namespace Sledgemapper var angle = Math.Atan2(posY - endposY, endposX - posX); var angleRad = -(float)angle; if (l > 0) - { - _spriteBatch.Draw(_transparentRedRectangle, new Rectangle(posX, posY, (int)l, (int)(_state.TileSize * _state.LineWidth)), null, Color.White, angleRad, new Vector2(0, 0), SpriteEffects.None, 1); - } + _spriteBatch.Draw(_transparentRedRectangle, + new Rectangle(posX, posY, (int)l, (int)(_state.TileSize * _state.LineWidth)), null, + Color.White, angleRad, new Vector2(0, 0), SpriteEffects.None, 1); } } } - private void DrawSelectedIntersection() - { - if (_state.InsertMode == InsertMode.Overlay && _state.SelectedOverlay.Intersection) - { - var overlay = new Vector2(_state.SelectedOverlay.X * _state.TileSize, _state.SelectedOverlay.Y * _state.TileSize); - _spriteBatch.DrawCircle(overlay, _state.TileSize / 3f, 100, Color.Red, 2); - } - } - - private void DrawSelectedWall() - { - if (_state.InsertMode == InsertMode.Wall) - { - var startWall = new Vector2(_state.SelectedWall.X * _state.TileSize, _state.SelectedWall.Y * _state.TileSize); - _spriteBatch.DrawLine(startWall, _state.TileSize, MathHelper.ToRadians(90 * _state.SelectedWall.Rotation), Color.Red, 2); - } - } - - private void DrawPlayerOffline() - { - if (string.IsNullOrWhiteSpace(_sessionData.SessionName)) - { - var isoffscreen = IsOffscreen(_state.SelectedTile); - if (isoffscreen) - { - var validPointer = GetPointerVector(new Point(_state.SelectedTile.X, _state.SelectedTile.Y), out var points); - if (validPointer) - { - _spriteBatch.DrawPolygon(Vector2.Zero, points, Color.Red, 2); - } - } - else - { - _spriteBatch.DrawRectangle(new Rectangle((_state.SelectedTile.X * _state.TileSize) - 2, (_state.SelectedTile.Y * _state.TileSize) - 2, _state.TileSize + 3, _state.TileSize + 3), Color.Red, 2); - } - } - } - - private void ApplyShaderToMap() - { - Vector2 texelSize = new Vector2((float)rendertarget.Width, (float)rendertarget.Height); - outlineShader.Parameters["ImageSize"].SetValue(texelSize); - outlineShader.Parameters["BorderSize"].SetValue((int)(_state.TileSize / 100f * 10f)); - - outlineShader.Parameters["R"].SetValue(_settings.OverlayTintColor.R / 255.0f); - outlineShader.Parameters["G"].SetValue(_settings.OverlayTintColor.G / 255.0f); - outlineShader.Parameters["B"].SetValue(_settings.OverlayTintColor.B / 255.0f); - - GraphicsDevice.Clear(_settings.BackgroundColor); - - _spriteBatch.Begin( - effect: outlineShader, - sortMode: SpriteSortMode.Immediate); - _spriteBatch.Draw(rendertarget, Vector2.Zero, null, Color.White); - _spriteBatch.End(); - } - private void DrawMap() { - GraphicsDevice.SetRenderTarget(rendertarget); + GraphicsDevice.SetRenderTarget(_renderTarget); GraphicsDevice.Clear(Color.Transparent); _spriteBatch.Begin( - transformMatrix: Matrix.CreateTranslation(_viewportCenter), - samplerState: SamplerState.PointClamp - ); + transformMatrix: Matrix.CreateTranslation(_state.ViewportCenter), + samplerState: SamplerState.PointClamp + ); - var items = _sessionData.Lines.Values.Union(_sessionData.Rooms.Values).OrderBy(t => t.Timestamp).ToArray(); + var items = _sessionData.Lines.Values.Union(_sessionData.Rooms.Values) + .OrderBy(t => t.Timestamp).ToArray(); for (var i = 0; i < items.Count(); i++) { var item = items.ElementAt(i); - if (IsMapElementOffscreen(item)) - { - continue; - } + if (IsMapElementOffscreen(item)) continue; switch (item) { case Line l: @@ -1138,153 +891,42 @@ namespace Sledgemapper case Room room: if (room.Delete) - { DrawDelete(room); - } else - { DrawRoom(room); - } break; } } + _spriteBatch.End(); GraphicsDevice.SetRenderTarget(null); } - private bool IsMapElementOffscreen(BaseMapEntity item) - { - SnapPoint start, end; - - switch (item) - { - case Line l: - start = l.Start; - end = l.End; - break; - - case Room room: - start = room.Start; - end = room.End; - break; - default: - return true; - } - - var visibleTilesX = GraphicsDevice.Viewport.Width / _state.TileSize + 1; - var visibleTilesY = GraphicsDevice.Viewport.Height / _state.TileSize + 1; - - var screenPositionTopLeft = new Point(200 - _state.TileSize + 0 * _state.TileSize - (int)_viewportCenter.X, 0 * _state.TileSize + _state.TileSize - (int)_viewportCenter.Y); - var screenPositionBottomRight = new Point(visibleTilesX * _state.TileSize - (int)_viewportCenter.X, visibleTilesY * _state.TileSize - 20 - (int)_viewportCenter.Y); - var tileTopLeft = new Point(screenPositionTopLeft.X / _state.TileSize, screenPositionTopLeft.Y / _state.TileSize); - var tileBottomRight = new Point(screenPositionBottomRight.X / _state.TileSize, screenPositionBottomRight.Y / _state.TileSize); - - if (start.X < tileTopLeft.X && start.Y < tileTopLeft.Y && start.X > tileBottomRight.X && start.Y > tileBottomRight.Y && - end.X < tileTopLeft.X && end.Y < tileTopLeft.Y && end.X > tileBottomRight.X && end.Y > tileBottomRight.Y - ) - { - return true; - } - return false; - } - - private void DrawGrid(int visibleTilesX, int visibleTilesY) - { - for (var i = -1; i < visibleTilesX + 2; i++) - { - var posX1 = i * _state.TileSize - _viewportCenter.X; - var posY1 = -_viewportCenter.Y; - posX1 -= posX1 % _state.TileSize; - posY1 -= posY1 % _state.TileSize; - var posX2 = i * _state.TileSize - _viewportCenter.X; - var posY2 = GraphicsDevice.Viewport.Height - _viewportCenter.Y; - posX2 -= posX2 % _state.TileSize; - posY2 -= posY2 % _state.TileSize; - - _spriteBatch.DrawLine( - posX1, posY1, - posX2, - posY2, - _settings.GridColor); - } - - for (var i = -1; i < visibleTilesY + 2; i++) - { - var posX1 = -_viewportCenter.X; - var posY1 = i * _state.TileSize - _viewportCenter.Y; - posX1 -= posX1 % _state.TileSize; - posY1 -= posY1 % _state.TileSize; - var posX2 = GraphicsDevice.Viewport.Width - _viewportCenter.X; - var posY2 = i * _state.TileSize - _viewportCenter.Y; - posX2 -= posX2 % _state.TileSize; - posY2 -= posY2 % _state.TileSize; - - _spriteBatch.DrawLine(posX1, posY1, - posX2, - posY2, - _settings.GridColor); - } - - - if (_showCellNumbers && _state.TileSize >= 30) - { - var ffont = _fonts.FirstOrDefault(m => int.Parse(m.Key.Replace("font", "")) > _state.TileSize / 8).Value ?? _fonts.Last().Value; - var fscale = 1f; - - for (var i = -1; i < visibleTilesX + 2; i++) - { - for (var j = -1; j < visibleTilesY + 2; j++) - { - var screenPosition = new Point(i * _state.TileSize - (int)_viewportCenter.X, j * _state.TileSize - (int)_viewportCenter.Y); - - var x = screenPosition.X / _state.TileSize; - var y = screenPosition.Y / _state.TileSize; - - _spriteBatch.DrawString(ffont, - $"{x}:{y}", - new Vector2( - x * _state.TileSize + 2, - y * _state.TileSize + 2 - ), - Color.Black, - 0, - Vector2.Zero, - fscale, - SpriteEffects.None, - 0); - } - } - } - } - private void DrawNotes() { - if (_state.TileSize < 30) - { - return; - } + if (_state.TileSize < 30) return; for (var i = 0; i < _sessionData.Notes.Values.Count; i++) { var note = _sessionData.Notes.Values.ElementAt(i); _spriteBatch.Draw( - _comment, - new Rectangle( - note.X * _state.TileSize + _state.TileSize - (int)(_state.TileSize / 2) + _state.TileSize / 25, - note.Y * _state.TileSize + _state.TileSize / 8 + _state.TileSize / 25, - (int)(_state.TileSize / 2.5), (int)(_state.TileSize / 2.5 / 1.136) - ), Color.Black * .2f - ); + _comment, + new Rectangle( + note.X * _state.TileSize + _state.TileSize - _state.TileSize / 2 + _state.TileSize / 25, + note.Y * _state.TileSize + _state.TileSize / 8 + _state.TileSize / 25, + (int)(_state.TileSize / 2.5), (int)(_state.TileSize / 2.5 / 1.136) + ), Color.Black * .2f + ); _spriteBatch.Draw( _comment, new Rectangle( - note.X * _state.TileSize + _state.TileSize - (int)(_state.TileSize / 2), - note.Y * _state.TileSize + _state.TileSize / 8, - (int)(_state.TileSize / 2.5), (int)(_state.TileSize / 2.5 / 1.136) - ), _settings.NoteColor - ); + note.X * _state.TileSize + _state.TileSize - _state.TileSize / 2, + note.Y * _state.TileSize + _state.TileSize / 8, + (int)(_state.TileSize / 2.5), (int)(_state.TileSize / 2.5 / 1.136) + ), Settings.Instance.NoteColor + ); } } @@ -1303,8 +945,15 @@ namespace Sledgemapper posX = tile.X * _state.TileSize; posY = tile.Y * _state.TileSize; - _spriteBatch.Draw(_spriteSheet.Texture, new Vector2(posX + _state.TileSize / 25, posY + _state.TileSize / 25), spriteRec, Color.Black * .2f, MathHelper.ToRadians(90 * tile.Rotation), new Vector2(spriteRec.Value.Width / 2, spriteRec.Value.Height / 2), ((float)_state.TileSize - 10) / spriteRec.Value.Width, SpriteEffects.None, 0); - _spriteBatch.Draw(_spriteSheet.Texture, new Vector2(posX, posY), spriteRec, _settings.OverlayTintColor, MathHelper.ToRadians(90 * tile.Rotation), new Vector2(spriteRec.Value.Width / 2, spriteRec.Value.Height / 2), ((float)_state.TileSize - 10) / spriteRec.Value.Width, SpriteEffects.None, 0); + _spriteBatch.Draw(_spriteSheet.Texture, + new Vector2(posX + _state.TileSize / 25, posY + _state.TileSize / 25), spriteRec, + Color.Black * .2f, MathHelper.ToRadians(90 * tile.Rotation), + new Vector2(spriteRec.Value.Width / 2, spriteRec.Value.Height / 2), + ((float)_state.TileSize - 10) / spriteRec.Value.Width, SpriteEffects.None, 0); + _spriteBatch.Draw(_spriteSheet.Texture, new Vector2(posX, posY), spriteRec, + Settings.Instance.OverlayTintColor, MathHelper.ToRadians(90 * tile.Rotation), + new Vector2(spriteRec.Value.Width / 2, spriteRec.Value.Height / 2), + ((float)_state.TileSize - 10) / spriteRec.Value.Width, SpriteEffects.None, 0); } else { @@ -1312,15 +961,91 @@ namespace Sledgemapper posY = tile.Y * _state.TileSize + _state.TileSize / 2f; } - _spriteBatch.Draw(_spriteSheet.Texture, new Vector2(posX + _state.TileSize / 25, posY + _state.TileSize / 25), spriteRec, Color.Black * .2f, MathHelper.ToRadians(90 * tile.Rotation), new Vector2(spriteRec.Value.Width / 2, spriteRec.Value.Height / 2), ((float)_state.TileSize - 10) / spriteRec.Value.Width, SpriteEffects.None, 0); - _spriteBatch.Draw(_spriteSheet.Texture, new Vector2(posX, posY), spriteRec, _settings.OverlayTintColor, MathHelper.ToRadians(90 * tile.Rotation), new Vector2(spriteRec.Value.Width / 2, spriteRec.Value.Height / 2), ((float)_state.TileSize - 10) / spriteRec.Value.Width, SpriteEffects.None, 0); + _spriteBatch.Draw(_spriteSheet.Texture, + new Vector2(posX + _state.TileSize / 25, posY + _state.TileSize / 25), spriteRec, Color.Black * .2f, + MathHelper.ToRadians(90 * tile.Rotation), + new Vector2(spriteRec.Value.Width / 2, spriteRec.Value.Height / 2), + ((float)_state.TileSize - 10) / spriteRec.Value.Width, SpriteEffects.None, 0); + _spriteBatch.Draw(_spriteSheet.Texture, new Vector2(posX, posY), spriteRec, + Settings.Instance.OverlayTintColor, MathHelper.ToRadians(90 * tile.Rotation), + new Vector2(spriteRec.Value.Width / 2, spriteRec.Value.Height / 2), + ((float)_state.TileSize - 10) / spriteRec.Value.Width, SpriteEffects.None, 0); } } + private void DrawPingPointer(Ping ping, GameTime gameTime) + { + var durationMs = 2000f; + var baseRadius = _state.TileSize / 4f; + var baseOuterRadius = (float)_state.TileSize; + var iterations = 3f; + var validPointer = GetPointerVector(new Point(ping.X, ping.Y), out var points); + + if (validPointer) + { + _spriteBatch.DrawPolygon(Vector2.Zero, points, ping.Player.Color.ToColor(), 4); + + + for (var j = 0; j < iterations; j++) + { + var cycleTime = ((float)gameTime.TotalGameTime.TotalMilliseconds + j * durationMs / iterations) % + durationMs / durationMs; + var easing = Easings.Interpolate(cycleTime, Easings.Functions.SineEaseInOut); + var v2 = new Vector2[points.Length]; + + + var tCenter = new Vector2((points[0].X + points[1].X + points[2].X) / 3f, + (points[0].Y + points[1].Y + points[2].Y) / 3f); + + + for (var i1 = 0; i1 < v2.Length; i1++) + { + var svx = (points[i1].X - tCenter.X) * (1 + 2 * easing) + tCenter.X; + var svy = (points[i1].Y - tCenter.Y) * (1 + 2 * easing) + tCenter.Y; + v2[i1] = new Vector2(svx, svy); + } + + _spriteBatch.DrawPolygon( + Vector2.Zero, + v2, + new Color(ping.Player.Color.ToColor(), 1f - easing), + 2 + 2 * (1 - easing)); + } + } + } + + private void DrawPlayerOffline() + { + if (string.IsNullOrWhiteSpace(_sessionData.SessionName)) + { + var isoffscreen = IsOffscreen(_state.SelectedTile); + if (isoffscreen) + { + var validPointer = GetPointerVector(new Point(_state.SelectedTile.X, _state.SelectedTile.Y), + out var points); + if (validPointer) _spriteBatch.DrawPolygon(Vector2.Zero, points, Color.Red, 2); + } + else + { + _spriteBatch.DrawRectangle( + new Rectangle(_state.SelectedTile.X * _state.TileSize - 2, + _state.SelectedTile.Y * _state.TileSize - 2, _state.TileSize + 3, _state.TileSize + 3), + Color.Red, 2); + } + } + } + + private void DrawPlayerPointer(Player player) + { + var validPointer = GetPointerVector(new Point(player.Position.X, player.Position.Y), out var points); + if (validPointer) _spriteBatch.DrawPolygon(Vector2.Zero, points, player.Color.ToColor(), 2); + } + private void DrawPlayers() { - var ffont = _fonts.FirstOrDefault(m => int.Parse(m.Key.Replace("font", "")) > _state.TileSize).Value ?? _fonts.Last().Value; - var fscale = _state.TileSize / ((float)ffont.LineSpacing * 3f); + var ffont = _fonts.FirstOrDefault(m => int.Parse(m.Key.Replace("font", "")) > _state.TileSize).Value ?? + _fonts.Last().Value; + var fscale = _state.TileSize / (ffont.LineSpacing * 3f); var playerCells = _sessionData.Players.Select(m => m.Position).Distinct().ToList(); @@ -1376,6 +1101,7 @@ namespace Sledgemapper player.Position.X * _state.TileSize + _state.TileSize / 2 + 1, player.Position.Y * _state.TileSize + _state.TileSize - measure.Y * fscale); } + i++; } else if (playersInCell.Count >= 3) @@ -1429,246 +1155,94 @@ namespace Sledgemapper break; } + i++; } _spriteBatch.DrawRectangle(rectangle, color, 2); _spriteBatch.DrawString(ffont, - player.Initials, - stringPosition, - color, - 0, - Vector2.Zero, - fscale, - SpriteEffects.None, - 0); + player.Initials, + stringPosition, + color, + 0, + Vector2.Zero, + fscale, + SpriteEffects.None, + 0); } - } foreach (var player in _sessionData.Players) { var isOffscreen = IsOffscreen(player.Position); - if (isOffscreen) - { - DrawPlayerPointer(player); - } + if (isOffscreen) DrawPlayerPointer(player); } } - private void DrawPingPointer(Ping ping, GameTime gameTime) + private void DrawRipple(GameTime gameTime) { - var durationMs = 2000f; + _spriteBatch.Begin( + blendState: BlendState.NonPremultiplied, + transformMatrix: Matrix.CreateTranslation(_state.ViewportCenter)); + + var durationMs = 2000; var baseRadius = _state.TileSize / 4f; var baseOuterRadius = (float)_state.TileSize; var iterations = 3f; - var validPointer = GetPointerVector(new Point(ping.X, ping.Y), out var points); + var guids = _sessionData.Pings.Keys.ToArray(); - if (validPointer) + foreach (var guid in guids) { - _spriteBatch.DrawPolygon(Vector2.Zero, points, ping.Player.Color.ToColor(), 4); + var pingFound = _sessionData.Pings.TryGetValue(guid, out var ping); + if (!pingFound) continue; + if (ping.StartTime == 0) ping.StartTime = gameTime.TotalGameTime.TotalMilliseconds; - for (var j = 0; j < iterations; j++) + var x = ping.X * _state.TileSize + _state.TileSize / 2f; + var y = ping.Y * _state.TileSize + _state.TileSize / 2f; + + if (IsOffscreen(new Tile { X = ping.X, Y = ping.Y })) { - var cycleTime = (((float)gameTime.TotalGameTime.TotalMilliseconds + (float)j * durationMs / iterations) % durationMs) / durationMs; - var easing = Easings.Interpolate(cycleTime, Easings.Functions.SineEaseInOut); - var v2 = new Vector2[points.Length]; + DrawPingPointer(ping, gameTime); + } + else + { + _spriteBatch.DrawCircle( + new Vector2(x, y), + baseRadius, + 20, + ping.Player.Color.ToColor(), + baseRadius); - - var tCenter = new Vector2((points[0].X + points[1].X + points[2].X) / 3f, (points[0].Y + points[1].Y + points[2].Y) / 3f); - - - for (int i1 = 0; i1 < v2.Length; i1++) + for (var i = 0; i < iterations; i++) { - - var svx = ((points[i1].X - tCenter.X) * (1 + (2 * easing))) + tCenter.X; - var svy = ((points[i1].Y - tCenter.Y) * (1 + (2 * easing))) + tCenter.Y; - v2[i1] = new Vector2(svx, svy); + var cycleTime = + ((float)gameTime.TotalGameTime.TotalMilliseconds + (float)i * durationMs / iterations) % + durationMs / durationMs; + var easing = Easings.Interpolate(cycleTime, Easings.Functions.SineEaseInOut); + _spriteBatch.DrawCircle( + new Vector2(x, y), + baseRadius + baseOuterRadius * easing, + 20, + new Color(ping.Player.Color.ToColor(), 1 - easing), + 2 + 5 * (1 - easing)); } - - _spriteBatch.DrawPolygon( - offset: Vector2.Zero, - points: v2, - color: new Color(ping.Player.Color.ToColor(), 1f - easing), - thickness: 2 + 2 * (1 - easing)); - } - } + + foreach (var guid in guids) + { + var pingFound = _sessionData.Pings.TryGetValue(guid, out var ping); + if (!pingFound) continue; + + if (gameTime.TotalGameTime.TotalMilliseconds - ping.StartTime > Settings.Instance.PingDuration) + _sessionData.Pings.TryRemove(guid, out var _); + } + + + _spriteBatch.End(); } - private bool GetPointerVector(Point target, out Vector2[] points) - { - var offset = _state.TileSize / 2; - var leftBound = 200 + offset; - var topBound = 75 + offset; - var bottomBound = 25 + offset; - var rightBound = offset; - points = new Vector2[0]; - var center = new Point((Window.ClientBounds.Width + leftBound) / 2 - (int)_viewportCenter.X, Window.ClientBounds.Height / 2 - (int)_viewportCenter.Y); - - // center - var p1 = new Vector2(center.X, center.Y); - - // point - var p2 = new Vector2( - target.X * _state.TileSize + offset, - target.Y * _state.TileSize + offset); - - // top right - var p3 = new Vector2( - Window.ClientBounds.Width - _viewportCenter.X - rightBound, - topBound - _viewportCenter.Y); - - //bottom right - var p4 = new Vector2( - Window.ClientBounds.Width - _viewportCenter.X - rightBound, - Window.ClientBounds.Height - _viewportCenter.Y - bottomBound); - - var ua1 = ((p4.X - p3.X) * (p1.Y - p3.Y) - (p4.Y - p3.Y) * (p1.X - p3.X)) / ((p4.Y - p3.Y) * (p2.X - p1.X) - (p4.X - p3.X) * (p2.Y - p1.Y)); - - p3 = new Vector2(leftBound - _viewportCenter.X, topBound - _viewportCenter.Y); - p4 = new Vector2(Window.ClientBounds.Width - _viewportCenter.X, topBound - _viewportCenter.Y); - var ua2 = ((p4.X - p3.X) * (p1.Y - p3.Y) - (p4.Y - p3.Y) * (p1.X - p3.X)) / ((p4.Y - p3.Y) * (p2.X - p1.X) - (p4.X - p3.X) * (p2.Y - p1.Y)); - - p3 = new Vector2(leftBound - _viewportCenter.X, topBound - _viewportCenter.Y); - p4 = new Vector2(leftBound - _viewportCenter.X, Window.ClientBounds.Height - _viewportCenter.Y - bottomBound); - var ua3 = ((p4.X - p3.X) * (p1.Y - p3.Y) - (p4.Y - p3.Y) * (p1.X - p3.X)) / ((p4.Y - p3.Y) * (p2.X - p1.X) - (p4.X - p3.X) * (p2.Y - p1.Y)); - - p3 = new Vector2(leftBound - _viewportCenter.X, Window.ClientBounds.Height - _viewportCenter.Y - bottomBound); - p4 = new Vector2(Window.ClientBounds.Width - _viewportCenter.X, Window.ClientBounds.Height - _viewportCenter.Y - bottomBound); - var ua4 = ((p4.X - p3.X) * (p1.Y - p3.Y) - (p4.Y - p3.Y) * (p1.X - p3.X)) / ((p4.Y - p3.Y) * (p2.X - p1.X) - (p4.X - p3.X) * (p2.Y - p1.Y)); - - var uas = new List { ua1, ua2, ua3, ua4 }; - if (uas.Any(u => u > 0 && u < 1)) - { - var ua = uas.Where(u => u > 0 && u < 1).Min(); - var i = uas.IndexOf(ua); - var x = (p1.X + ua * (p2.X - p1.X)); - var y = (p1.Y + ua * (p2.Y - p1.Y)); - - switch (i) - { - case 0: - x += offset; - points = new Vector2[] { new Vector2(x, y), new Vector2(x - 20, y - 10), new Vector2(x - 20, y + 10), new Vector2(x, y) }; - break; - case 1: - y -= offset; - points = new Vector2[] { new Vector2(x, y), new Vector2(x - 10, y + 20), new Vector2(x + 10, y + 20), new Vector2(x, y) }; - break; - case 2: - x -= offset; - points = new Vector2[] { new Vector2(x, y), new Vector2(x + 20, y + 10), new Vector2(x + 20, y - 10), new Vector2(x, y) }; - break; - case 3: - y += offset; - points = new Vector2[] { new Vector2(x, y), new Vector2(x + 10, y - 20), new Vector2(x - 10, y - 20), new Vector2(x, y) }; - break; - } - return true; - } - return false; - } - - private void DrawPlayerPointer(Player player) - { - var validPointer = GetPointerVector(new Point(player.Position.X, player.Position.Y), out var points); - if (validPointer) - { - _spriteBatch.DrawPolygon(Vector2.Zero, points, player.Color.ToColor(), 2); - } - } - - ArrayPool _vector2Pool; - - private bool IsOffscreen(Tile position) - { - var boxTL = new Point(200 - _state.TileSize / 2, 75 - _state.TileSize / 2); - var boxBR = new Point(GraphicsDevice.Viewport.Width + _state.TileSize / 2, GraphicsDevice.Viewport.Height - 25 + _state.TileSize / 2); - - var tileTL = new Point(position.X * _state.TileSize + (int)_viewportCenter.X, position.Y * _state.TileSize + (int)_viewportCenter.Y); - var tileBR = new Point(position.X * _state.TileSize + (int)_viewportCenter.X + _state.TileSize, position.Y * _state.TileSize + (int)_viewportCenter.Y + _state.TileSize); - - if (tileTL.X <= boxTL.X || tileTL.Y <= boxTL.Y || tileBR.X >= boxBR.X || tileBR.Y >= boxBR.Y) - { - return true; - } - - return false; - } - - private int _borderWidth => (_state.TileSize / 6) % 2 == 0 ? (_state.TileSize / 6) : (_state.TileSize / 6) + 1; - - private void DrawTiles() - { - for (var i = 0; i < _sessionData.Map.Values.Count; i++) - { - var tile = _sessionData.Map.Values.ElementAt(i); - var content = Content.Load($"tiles/{tile.ID}"); - - var posX = tile.X * _state.TileSize + _state.TileSize / 2f; - var posY = tile.Y * _state.TileSize + _state.TileSize / 2f; - - _spriteBatch.Draw(content, new Vector2(posX, posY), - null, Color.White, MathHelper.ToRadians(90 * tile.Rotation), new Vector2(content.Width / 2, content.Height / 2), ((float)_state.TileSize) / content.Width, SpriteEffects.None, 0); - } - } - - private void DrawLine(Line tile) - { - var posX = tile.Start.X * _state.TileSize; - var posY = tile.Start.Y * _state.TileSize; - - var endposX = tile.End.X * _state.TileSize; - var endposY = tile.End.Y * _state.TileSize; - - switch (tile.Start.Index) - { - case 1: - break; - case 2: - posX += _state.TileSize / 2; - break; - case 3: - posY += _state.TileSize / 2; - - break; - case 4: - posX += _state.TileSize / 2; - posY += _state.TileSize / 2; - break; - } - - switch (tile.End.Index) - { - case 1: - break; - case 2: - endposX += _state.TileSize / 2; - break; - case 3: - endposY += _state.TileSize / 2; - - break; - case 4: - endposX += _state.TileSize / 2; - endposY += _state.TileSize / 2; - break; - } - - var length = (int)Math.Sqrt(Math.Pow(posX - endposX, 2) + Math.Pow(posY - endposY, 2)); - var height = (int)(_state.TileSize * tile.Width); - if (length > 0) - { - var angle = Math.Atan2(posY - endposY, endposX - posX); - var angleRad = -(float)angle; - _spriteBatch.Draw(_whiteRectangle, new Rectangle(posX, posY, length, height), null, Color.White, angleRad, new Vector2(0, 0), SpriteEffects.None, 1); - } - } - - private void DrawRoom(Room tile) { var posX = tile.Start.X * _state.TileSize; @@ -1713,112 +1287,243 @@ namespace Sledgemapper if (posX != endposX && posY != endposY) { - - - if ((posX < endposX && posY < endposY)) + if (posX < endposX && posY < endposY) { - _spriteBatch.Draw(_whiteRectangle, new Rectangle(posX, posY, endposX - posX, endposY - posY), null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 1); + _spriteBatch.Draw(_whiteRectangle, new Rectangle(posX, posY, endposX - posX, endposY - posY), null, + Color.White, 0, Vector2.Zero, SpriteEffects.None, 1); } - else if ((posX > endposX && posY > endposY)) + else if (posX > endposX && posY > endposY) { - _spriteBatch.Draw(_whiteRectangle, new Rectangle(posX, posY, endposX - posX, endposY - posY), null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 1); + _spriteBatch.Draw(_whiteRectangle, new Rectangle(posX, posY, endposX - posX, endposY - posY), null, + Color.White, 0, Vector2.Zero, SpriteEffects.None, 1); } else { if (endposY < posY) - { - _spriteBatch.Draw(_whiteRectangle, new Rectangle(posX, endposY, endposX - posX, posY - endposY), null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 1); - } + _spriteBatch.Draw(_whiteRectangle, new Rectangle(posX, endposY, endposX - posX, posY - endposY), + null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 1); if (endposX < posX) + _spriteBatch.Draw(_whiteRectangle, new Rectangle(endposX, posY, posX - endposX, endposY - posY), + null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 1); + } + } + } + + private void DrawRoomPreview() + { + if ((_state.InsertMode == InsertMode.NewRoom || _state.InsertMode == InsertMode.NewDelete) && + _state.SelectedSnapPoint != null) + { + var snapPoint = new Vector2(_state.SelectedSnapPoint.X * _state.TileSize, + _state.SelectedSnapPoint.Y * _state.TileSize); + + switch (_state.SelectedSnapPoint.Index) + { + case 1: + break; + case 2: + snapPoint.X += _state.TileSize / 2; + break; + case 3: + snapPoint.Y += _state.TileSize / 2; + break; + case 4: + snapPoint.Y += _state.TileSize / 2; + snapPoint.X += _state.TileSize / 2; + break; + } + + _spriteBatch.DrawCircle(snapPoint, _state.TileSize / 6f, 50, Color.Red, 2); + + if (_state.LineStart != null) + { + var posX = _state.LineStart.X * _state.TileSize; + var posY = _state.LineStart.Y * _state.TileSize; + + var endposX = _state.SelectedSnapPoint.X * _state.TileSize; + var endposY = _state.SelectedSnapPoint.Y * _state.TileSize; + if (_state.InsertMode == InsertMode.NewDelete) { - _spriteBatch.Draw(_whiteRectangle, new Rectangle(endposX, posY, posX - endposX, endposY - posY), null, Color.White, 0, Vector2.Zero, SpriteEffects.None, 1); + var ww = _state.TileSize / Settings.Instance.TileDeleteDivider; + if (posX == endposX) + { + endposX += ww; + posX -= ww; + } + + if (posY == endposY) + { + endposY += ww; + posY -= ww; + } + } + + switch (_state.LineStart.Index) + { + case 1: + break; + case 2: + posX += _state.TileSize / 2; + break; + case 3: + posY += _state.TileSize / 2; + + break; + case 4: + posX += _state.TileSize / 2; + posY += _state.TileSize / 2; + break; + } + + switch (_state.SelectedSnapPoint.Index) + { + case 1: + break; + case 2: + endposX += _state.TileSize / 2; + break; + case 3: + endposY += _state.TileSize / 2; + + break; + case 4: + endposX += _state.TileSize / 2; + endposY += _state.TileSize / 2; + break; + } + + var ffont = _fonts.FirstOrDefault(m => int.Parse(m.Key.Replace("font", "")) > _state.TileSize / 3) + .Value ?? _fonts.Last().Value; + var fscale = 1.2f; + var width = Math.Abs(endposX - posX); + var height = Math.Abs(posY - endposY); + var tilesWidth = width / (double)_state.TileSize; + var tilesHeight = height / (double)_state.TileSize; + tilesWidth = Math.Round(tilesWidth * 2, MidpointRounding.AwayFromZero) / 2; + tilesHeight = Math.Round(tilesHeight * 2, MidpointRounding.AwayFromZero) / 2; + var xmeasure = ffont.MeasureString($"{tilesWidth}"); + var ymeasure = ffont.MeasureString($"{tilesHeight}"); + float widthX = 0, widthY = 0, heightX = 0, heightY = 0; + + var area = new Rectangle(); + if (posX != endposX && posY != endposY) + { + if (posX > endposX && posY > endposY || posX < endposX && posY < endposY) + { + area = new Rectangle(posX, posY, endposX - posX, endposY - posY); + + if (posX > endposX && posY > endposY) + { + widthX = endposX + width / 2 - xmeasure.X / 2; + widthY = endposY - ymeasure.Y * 1.2f; + + heightX = posX + xmeasure.X / 2; + heightY = endposY + height / 2 - ymeasure.Y / 2; + } + else if (posX < endposX && posY < endposY) + { + widthX = posX + width / 2 - xmeasure.X / 2; + widthY = posY - ymeasure.Y * 1.2f; + + heightX = endposX + xmeasure.X / 2; + heightY = posY + height / 2 - ymeasure.Y / 2; + } + } + else + { + if (endposY < posY) + { + area = new Rectangle(posX, endposY, endposX - posX, posY - endposY); + + widthX = posX + width / 2 - xmeasure.X / 2; + widthY = endposY - ymeasure.Y * 1.2f; + + heightX = endposX + xmeasure.X / 2; + heightY = endposY + height / 2 - ymeasure.Y / 2; + } + + if (endposX < posX) + { + area = new Rectangle(endposX, posY, posX - endposX, endposY - posY); + + widthX = endposX + width / 2 - xmeasure.X / 2; + widthY = posY - ymeasure.Y * 1.2f; + + heightX = posX + xmeasure.X / 2; + heightY = posY + height / 2 - ymeasure.Y / 2; + } + } + + _spriteBatch.Draw(_transparentRedRectangle, area, null, Color.White, 0, new Vector2(0, 0), + SpriteEffects.None, 1); + + _spriteBatch.DrawString(ffont, + $"{tilesWidth}", + new Vector2( + widthX, + widthY + ), + Color.Red, + 0, + Vector2.Zero, + fscale, + SpriteEffects.None, + 0); + + _spriteBatch.DrawString(ffont, + $"{tilesHeight}", + new Vector2( + heightX, heightY + ), + Color.Red, + 0, + Vector2.Zero, + fscale, + SpriteEffects.None, + 0); } } } } - Effect outlineShader; - private Texture2D _transparentRedRectangle; - private Texture2D _whiteRectangle; - private Dictionary _wallsContent; - private SpriteSheet _spriteSheet; - - private void DrawDelete(Room tile) + private void DrawSelectedIntersection() { - var posX = tile.Start.X * _state.TileSize; - var posY = tile.Start.Y * _state.TileSize; - - var endposX = tile.End.X * _state.TileSize; - var endposY = tile.End.Y * _state.TileSize; - - - var ww = _state.TileSize / _settings.TileDeleteDivider; - if (posX == endposX) { endposX += ww; posX -= ww; } - if (posY == endposY) { endposY += ww; posY -= ww; } - switch (tile.Start.Index) + if (_state.InsertMode == InsertMode.Overlay && _state.SelectedOverlay.Intersection) { - case 1: - break; - case 2: - posX += _state.TileSize / 2; - break; - case 3: - posY += _state.TileSize / 2; - - break; - case 4: - posX += _state.TileSize / 2; - posY += _state.TileSize / 2; - break; + var overlay = new Vector2(_state.SelectedOverlay.X * _state.TileSize, + _state.SelectedOverlay.Y * _state.TileSize); + _spriteBatch.DrawCircle(overlay, _state.TileSize / 3f, 100, Color.Red, 2); } + } - switch (tile.End.Index) + private void DrawSelectedWall() + { + if (_state.InsertMode == InsertMode.Wall) { - case 1: - break; - case 2: - endposX += _state.TileSize / 2; - break; - case 3: - endposY += _state.TileSize / 2; - - break; - case 4: - endposX += _state.TileSize / 2; - endposY += _state.TileSize / 2; - break; + var startWall = new Vector2(_state.SelectedWall.X * _state.TileSize, + _state.SelectedWall.Y * _state.TileSize); + _spriteBatch.DrawLine(startWall, _state.TileSize, + MathHelper.ToRadians(90 * _state.SelectedWall.Rotation), Color.Red, 2); } + } - if (posX != endposX && posY != endposY) + private void DrawTiles() + { + for (var i = 0; i < _sessionData.Map.Values.Count; i++) { - Rectangle r = new Rectangle(); + var tile = _sessionData.Map.Values.ElementAt(i); + var content = Content.Load($"tiles/{tile.ID}"); - if ((posX < endposX && posY < endposY)) - { - - r = new Rectangle(posX, posY, endposX - posX, endposY - posY); - } - else if ((posX > endposX && posY > endposY)) - { - r = new Rectangle(posX, posY, endposX - posX, endposY - posY); - } - else - { - if (endposY < posY) - { - r = new Rectangle(posX, endposY, endposX - posX, posY - endposY); - } - if (endposX < posX) - { - r = new Rectangle(endposX, posY, posX - endposX, endposY - posY); - } - } - - _spriteBatch.Draw(_whiteRectangle, r, null, Color.Black, 0, Vector2.Zero, SpriteEffects.None, 1); + var posX = tile.X * _state.TileSize + _state.TileSize / 2f; + var posY = tile.Y * _state.TileSize + _state.TileSize / 2f; + _spriteBatch.Draw(content, new Vector2(posX, posY), + null, Color.White, MathHelper.ToRadians(90 * tile.Rotation), + new Vector2(content.Width / 2, content.Height / 2), (float)_state.TileSize / content.Width, + SpriteEffects.None, 0); } } @@ -1833,607 +1538,269 @@ namespace Sledgemapper var posX = wall.X * _state.TileSize; var posY = wall.Y * _state.TileSize; if (wall.Rotation == 1) - { posX -= (int)offset; - } - else if (wall.Rotation == 0) - { - posY += (int)offset; - } - _spriteBatch.Draw(content, new Vector2(posX, posY), null, Color.White, MathHelper.ToRadians(90 * (wall.Rotation - 1)), new Vector2(0, 0), scale, SpriteEffects.None, 0); + else if (wall.Rotation == 0) posY += (int)offset; + _spriteBatch.Draw(content, new Vector2(posX, posY), null, Color.White, + MathHelper.ToRadians(90 * (wall.Rotation - 1)), new Vector2(0, 0), scale, SpriteEffects.None, 0); } } - private async void OnButtonJoinSessionClicked(object sender, EventArgs e) + private void EditNote(Note note) { - Container container = ((TextButton)sender).Parent; - while (!(container is Window)) + _state.SelectedNote = new Note { X = note.X, Y = note.Y, Text = note.Text }; + new NoteWindow(_communicationManager, note).ShowInModalWindow(_desktop, $" Note on {note.X}:{note.Y}"); + } + + private bool GetPointerVector(Point target, out Vector2[] points) + { + var offset = _state.TileSize / 2; + var leftBound = 200 + offset; + var topBound = 75 + offset; + var bottomBound = 25 + offset; + var rightBound = offset; + points = Array.Empty(); + var center = new Point((Window.ClientBounds.Width + leftBound) / 2 - (int)_state.ViewportCenter.X, + Window.ClientBounds.Height / 2 - (int)_state.ViewportCenter.Y); + + // center + var p1 = new Vector2(center.X, center.Y); + + // point + var p2 = new Vector2( + target.X * _state.TileSize + offset, + target.Y * _state.TileSize + offset); + + // top right + var p3 = new Vector2( + Window.ClientBounds.Width - _state.ViewportCenter.X - rightBound, + topBound - _state.ViewportCenter.Y); + + //bottom right + var p4 = new Vector2( + Window.ClientBounds.Width - _state.ViewportCenter.X - rightBound, + Window.ClientBounds.Height - _state.ViewportCenter.Y - bottomBound); + + var ua1 = ((p4.X - p3.X) * (p1.Y - p3.Y) - (p4.Y - p3.Y) * (p1.X - p3.X)) / + ((p4.Y - p3.Y) * (p2.X - p1.X) - (p4.X - p3.X) * (p2.Y - p1.Y)); + + p3 = new Vector2(leftBound - _state.ViewportCenter.X, topBound - _state.ViewportCenter.Y); + p4 = new Vector2(Window.ClientBounds.Width - _state.ViewportCenter.X, topBound - _state.ViewportCenter.Y); + var ua2 = ((p4.X - p3.X) * (p1.Y - p3.Y) - (p4.Y - p3.Y) * (p1.X - p3.X)) / + ((p4.Y - p3.Y) * (p2.X - p1.X) - (p4.X - p3.X) * (p2.Y - p1.Y)); + + p3 = new Vector2(leftBound - _state.ViewportCenter.X, topBound - _state.ViewportCenter.Y); + p4 = new Vector2(leftBound - _state.ViewportCenter.X, + Window.ClientBounds.Height - _state.ViewportCenter.Y - bottomBound); + var ua3 = ((p4.X - p3.X) * (p1.Y - p3.Y) - (p4.Y - p3.Y) * (p1.X - p3.X)) / + ((p4.Y - p3.Y) * (p2.X - p1.X) - (p4.X - p3.X) * (p2.Y - p1.Y)); + + p3 = new Vector2(leftBound - _state.ViewportCenter.X, + Window.ClientBounds.Height - _state.ViewportCenter.Y - bottomBound); + p4 = new Vector2(Window.ClientBounds.Width - _state.ViewportCenter.X, + Window.ClientBounds.Height - _state.ViewportCenter.Y - bottomBound); + var ua4 = ((p4.X - p3.X) * (p1.Y - p3.Y) - (p4.Y - p3.Y) * (p1.X - p3.X)) / + ((p4.Y - p3.Y) * (p2.X - p1.X) - (p4.X - p3.X) * (p2.Y - p1.Y)); + + var uas = new List { ua1, ua2, ua3, ua4 }; + if (uas.Any(u => u > 0 && u < 1)) { - container = container.Parent; - } - var localWindow = (Window)container; - var localContent = localWindow.Content as SessionWindow; - var isValid = ValidateTextbox(localContent.TxtSession); - if (!isValid) - { - return; + var ua = uas.Where(u => u > 0 && u < 1).Min(); + var i = uas.IndexOf(ua); + var x = p1.X + ua * (p2.X - p1.X); + var y = p1.Y + ua * (p2.Y - p1.Y); + + switch (i) + { + case 0: + x += offset; + points = new[] + { new(x, y), new Vector2(x - 20, y - 10), new Vector2(x - 20, y + 10), new Vector2(x, y) }; + break; + case 1: + y -= offset; + points = new[] + { new(x, y), new Vector2(x - 10, y + 20), new Vector2(x + 10, y + 20), new Vector2(x, y) }; + break; + case 2: + x -= offset; + points = new[] + { new(x, y), new Vector2(x + 20, y + 10), new Vector2(x + 20, y - 10), new Vector2(x, y) }; + break; + case 3: + y += offset; + points = new[] + { new(x, y), new Vector2(x + 10, y - 20), new Vector2(x - 10, y - 20), new Vector2(x, y) }; + break; + } + + return true; } - if (_communicationManager.Connection.State != HubConnectionState.Connected) + return false; + } + + private bool IsMapElementOffscreen(BaseMapEntity item) + { + SnapPoint start, end; + + switch (item) { - _mainWidget.lblConnectionStatus.Text = "Connecting"; - await _communicationManager.Connection.StartAsync(); - UpdateConnectionState(_communicationManager.Connection); + case Line l: + start = l.Start; + end = l.End; + break; + + case Room room: + start = room.Start; + end = room.End; + break; + default: + return true; } - var successful = false; + var visibleTilesX = GraphicsDevice.Viewport.Width / _state.TileSize + 1; + var visibleTilesY = GraphicsDevice.Viewport.Height / _state.TileSize + 1; + + var screenPositionTopLeft = + new Point(200 - _state.TileSize + 0 * _state.TileSize - (int)_state.ViewportCenter.X, + 0 * _state.TileSize + _state.TileSize - (int)_state.ViewportCenter.Y); + var screenPositionBottomRight = new Point(visibleTilesX * _state.TileSize - (int)_state.ViewportCenter.X, + visibleTilesY * _state.TileSize - 20 - (int)_state.ViewportCenter.Y); + var tileTopLeft = new Point(screenPositionTopLeft.X / _state.TileSize, + screenPositionTopLeft.Y / _state.TileSize); + var tileBottomRight = new Point(screenPositionBottomRight.X / _state.TileSize, + screenPositionBottomRight.Y / _state.TileSize); + + if (start.X < tileTopLeft.X && start.Y < tileTopLeft.Y && start.X > tileBottomRight.X && + start.Y > tileBottomRight.Y && + end.X < tileTopLeft.X && end.Y < tileTopLeft.Y && end.X > tileBottomRight.X && end.Y > tileBottomRight.Y + ) + return true; + return false; + } + + private bool IsOffscreen(Tile position) + { + var boxTL = new Point(200 - _state.TileSize / 2, 75 - _state.TileSize / 2); + var boxBR = new Point(GraphicsDevice.Viewport.Width + _state.TileSize / 2, + GraphicsDevice.Viewport.Height - 25 + _state.TileSize / 2); + + var tileTL = new Point(position.X * _state.TileSize + (int)_state.ViewportCenter.X, + position.Y * _state.TileSize + (int)_state.ViewportCenter.Y); + var tileBR = new Point(position.X * _state.TileSize + (int)_state.ViewportCenter.X + _state.TileSize, + position.Y * _state.TileSize + (int)_state.ViewportCenter.Y + _state.TileSize); + + return tileTL.X <= boxTL.X || tileTL.Y <= boxTL.Y || tileBR.X >= boxBR.X || tileBR.Y >= boxBR.Y; + } + + private void OnClientSizeChanged(object sender, EventArgs e) + { + _renderTarget?.Dispose(); try { - var result = await _communicationManager.Connection?.InvokeAsync("JoinSession", localContent.TxtSession.Text); - if (result != null) - { - _sessionData.Map = result.Map; - _sessionData.Walls = result.Walls; - _sessionData.Overlays = result.Overlays; - - _sessionData.MapEntityAdded -= OnMapEntityAdded; - _sessionData.MapEntityDeleted -= OnMapEntityDeleted; - _sessionData.MapEntityAdded += OnMapEntityAdded; - _sessionData.MapEntityDeleted += OnMapEntityDeleted; - _sessionData.SessionId = result.SessionId; - _sessionData.SessionName = result.SessionName; - } - successful = result != null; + ResetRenderTarget(); } - catch (Exception ex) + catch { - Console.WriteLine(ex.Message); - } - - if (successful) - { - _sessionData.SessionName = localContent.TxtSession.Text; - _mainWidget.lblSessionName.Text = _sessionData.SessionName; - _mainWidget.MenuConnectSync.Enabled = true; - _mainWidget.MenuConnectUpload.Enabled = true; - localWindow.Close(); + Console.WriteLine("rendertarget dispose exception"); } } - private async void OnButtonNewSessionClicked(object sender, EventArgs e) - { - Container container = ((TextButton)sender).Parent; - while (!(container is Window)) - { - container = container.Parent; - } - var localWindow = (Window)container; - var localContent = localWindow.Content as SessionWindow; - var isValid = ValidateTextbox(localContent.TxtSession); - if (!isValid) - { - return; - } - - if (_communicationManager.Connection.State != HubConnectionState.Connected) - { - _mainWidget.lblConnectionStatus.Text = "Connecting"; - await _communicationManager.Connection.StartAsync(); - UpdateConnectionState(_communicationManager.Connection); - } - - var successful = false; - try - { - var result = await _communicationManager.Api.NewSession(localContent.TxtSession.Text); - - if (result) - { - _sessionData.SessionName = localContent.TxtSession.Text; - _sessionData.MapEntityAdded -= OnMapEntityAdded; - _sessionData.MapEntityDeleted -= OnMapEntityDeleted; - _sessionData.MapEntityAdded += OnMapEntityAdded; - _sessionData.MapEntityDeleted += OnMapEntityDeleted; - } - successful = result; - var result2 = await _communicationManager.Connection?.InvokeAsync("JoinSession", localContent.TxtSession.Text); - _sessionData.SessionId = result2.SessionId; - _sessionData.SessionName = localContent.TxtSession.Text; - } - catch (Exception ex) - { - ExceptionlessClient.Default.SubmitException(ex); - } - - if (successful) - { - _sessionData.SessionName = localContent.TxtSession.Text; - _communicationManager.SessionData.Map = _sessionData.Map; - _communicationManager.SessionData.Overlays = _sessionData.Overlays; - _communicationManager.SessionData.Walls = _sessionData.Walls; - _mainWidget.lblSessionName.Text = _sessionData.SessionName; - _mainWidget.MenuConnectSync.Enabled = true; - _mainWidget.MenuConnectUpload.Enabled = true; - localWindow.Close(); - } - } - - private void UpdateConnectionState(HubConnection connection) - { - switch (connection.State) - { - case HubConnectionState.Connected: - _mainWidget.lblConnectionStatus.Text = "Connected"; - break; - case HubConnectionState.Connecting: - _mainWidget.lblConnectionStatus.Text = "Connecting"; - break; - case HubConnectionState.Disconnected: - _mainWidget.lblConnectionStatus.Text = "Disconnected"; - - break; - case HubConnectionState.Reconnecting: - _mainWidget.lblConnectionStatus.Text = "Reconnecting"; - - break; - } - } - - private void OnButtonNoteOkClick(object sender, EventArgs e) - { - var button = ((TextButton)sender); - Container container = button.Parent; - while (!(container is Window)) - { - container = container.Parent; - } - - var localWindow = (Window)container; - var localContent = localWindow.Content as NoteWindow; - var note = new Note - { - X = _state.SelectedNote.X, - Y = _state.SelectedNote.Y, - Text = localContent.NoteText.Text - }; - _sessionData.NewNote(note); - localWindow.Close(); - } - - private void OnButtonNoteCancelClick(object sender, EventArgs e) - { - var button = ((TextButton)sender); - Container container = button.Parent; - while (!(container is Window)) - { - container = container.Parent; - } - - var localWindow = (Window)container; - - localWindow.Close(); - } - private async void OnButtonLoginClick(object sender, EventArgs e) - { - var button = ((TextButton)sender); - Container container = button.Parent; - while (!(container is Window)) - { - container = container.Parent; - } - - var localWindow = (Window)container; - var localContent = localWindow.Content as LoginRegisterWindow; - - if (!button.Enabled) - { - return; - } - - var isValid = true; - isValid &= ValidateTextbox(localContent.TxtEmail); - isValid &= ValidateTextbox(localContent.TxtPassword); - - if (!isValid) - { - localContent.LblLoginError.Text = "Username or password is not valid"; - localContent.LblLoginError.Visible = true; - - return; - } - - var successful = false; - try - { - button.Text = "Wait..."; - localContent.LblLoginError.Text = ""; - localContent.LblLoginError.Visible = false; - _authResponse = await _communicationManager.Login(new AuthenticateModel - { - Username = localContent.TxtEmail.Text, - Password = localContent.TxtPassword.Text - }); - successful = _authResponse != null; - } - catch (Refit.ApiException refitException) - { - ExceptionlessClient.Default.SubmitException(refitException); - localContent.LblLoginError.Text = refitException.Content; - localContent.LblLoginError.Visible = true; - } - catch (Exception ex) - { - ExceptionlessClient.Default.SubmitException(ex); - localContent.LblLoginError.Text = "Can't connect to the server"; - localContent.LblLoginError.Visible = true; - Debug.Write(ex); - } - finally - { - button.Enabled = true; - button.Text = "Login"; - } - - if (successful) - { - _mainWidget.MenuConnectNew.Enabled = true; - _mainWidget.MenuConnectJoin.Enabled = true; - _mainWidget.lblUsername.Text = $"{_authResponse.Username} - {_authResponse.Initials}"; - localWindow.Close(); - } - } - - private async void OnButtonRegisterClick(object sender, EventArgs e) - { - var button = ((TextButton)sender); - Container container = button.Parent; - while (!(container is Window)) - { - container = container.Parent; - } - - var localWindow = (Window)container; - var localContent = localWindow.Content as LoginRegisterWindow; - - if (!button.Enabled) - { - return; - } - - var isValid = true; - isValid &= ValidateTextbox(localContent.TxtEmail); - isValid &= ValidateTextbox(localContent.TxtPassword); - isValid &= ValidateTextbox(localContent.TxtFirstname); - isValid &= ValidateTextbox(localContent.TxtLastname); - isValid &= ValidateTextbox(localContent.TxtInitials); - - if (!isValid) - { - localContent.LblLoginError.Text = "Please complete all the fields"; - localContent.LblLoginError.Visible = true; - return; - } - - var successful = false; - try - { - button.Text = "Wait..."; - localContent.LblLoginError.Text = ""; - localContent.LblLoginError.Visible = false; - - var result = await _communicationManager.Register(new RegisterModel - { - Username = localContent.TxtEmail.Text, - Password = localContent.TxtPassword.Text, - FirstName = localContent.TxtFirstname.Text, - LastName = localContent.TxtLastname.Text, - Initials = localContent.TxtInitials.Text - }); - if (result.IsSuccessStatusCode) - { - _authResponse = await _communicationManager.Login(new AuthenticateModel - { - Username = localContent.TxtEmail.Text, - Password = localContent.TxtPassword.Text - }); - successful = true; - } - else - { - localContent.LblLoginError.Text = result.ReasonPhrase; - localContent.LblLoginError.Visible = true; - } - } - catch (Refit.ApiException refitException) - { - ExceptionlessClient.Default.SubmitException(refitException); - localContent.LblLoginError.Text = refitException.Content; - localContent.LblLoginError.Visible = true; - } - catch (Exception ex) - { - ExceptionlessClient.Default.SubmitException(ex); - localContent.LblLoginError.Text = "Can't connect to the server"; - localContent.LblLoginError.Visible = true; - Debug.Write(ex); - } - finally - { - button.Enabled = true; - button.Text = "Register"; - } - if (successful) - { - _mainWidget.MenuConnectNew.Enabled = true; - _mainWidget.MenuConnectJoin.Enabled = true; - - _mainWidget.lblUsername.Text = $"{_authResponse.Username} - {_authResponse.Initials}"; - - localWindow.Close(); - } - } - - private void OnContextMenuNewNoteClick(object sender, EventArgs e) - { - _desktop.HideContextMenu(); - var noteWindow = new NoteWindow(); - - Window window = new() - { - Title = $" Note on {_state.SelectedTile.X}:{_state.SelectedTile.Y}" - }; - - noteWindow.BtnOk.Click += OnButtonNoteOkClick; - noteWindow.BtnCancel.Click += OnButtonNoteCancelClick; - window.Content = noteWindow; - window.ShowModal(_desktop); - noteWindow.NoteText.SetKeyboardFocus(); - } - - - private void OnContextMenuDeleteNoteClick(object sender, EventArgs e) { _desktop.HideContextMenu(); _sessionData.DeleteNote(_state.SelectedNote); } + private void OnContextMenuNewNoteClick(object sender, EventArgs e) + { + _desktop.HideContextMenu(); + new NoteWindow(_communicationManager, new Note()).ShowInModalWindow(_desktop, + $" Note on {_state.HoveredTile.X}:{_state.HoveredTile.Y}"); + } + + private void OnContextMenuPingClick(object sender, EventArgs e, Tile location) + { + _desktop.HideContextMenu(); + _communicationManager.Ping(location).SafeFireAndForget(); + } + private void OnContextMenuViewNoteClick(object sender, EventArgs e) { _desktop.HideContextMenu(); EditNote(_state.SelectedNote); } + private async Task OnHubDisconnected(Exception arg) + { + // ExceptionlessClient.Default.SubmitEvent(new Event { Message = "Hub disconnected", Type = "SignalR Client Events", Source = _settings.MachineName }); + _mainWidget.lblConnectionStatus.Text = "Disconnected"; + await Task.Yield(); + } + + private async Task OnHubReconnected(string arg) + { + // ExceptionlessClient.Default.SubmitEvent(new Event { Message = "Hub reconnected", Type = "SignalR Client Events", Source = _settings.MachineName }); + _mainWidget.lblConnectionStatus.Text = "Connected"; + await Task.Yield(); + } + + private async Task OnHubReconnecting(Exception arg) + { + // ExceptionlessClient.Default.SubmitEvent(new Event { Message = "Reconnecting Hub", Type = "SignalR Client Events", Source = _settings.MachineName }); + _mainWidget.lblConnectionStatus.Text = "Reconnecting"; + await Task.Yield(); + } + private void OnOverlayButtonClicked(object sender, EventArgs e) { _state.CurrentOverlayId = ((ImageButton)sender).Id; _mainWidget.ClearSelection(); ((ImageButton)sender).Border = new SolidBrush(Color.Red); - ((ImageButton)sender).BorderThickness = new Myra.Graphics2D.Thickness(2); + ((ImageButton)sender).BorderThickness = new Thickness(2); _state.InsertMode = InsertMode.Overlay; } + private void OnTileButtonTouchEntered(object sender, EventArgs e) + { + var mouseState = Mouse.GetState().Position; + mouseState.X += 10; + mouseState.Y += 10; + _lblOverlayName.Visible = true; + _lblOverlayName.Text = ((ImageButton)sender).Id; + _desktop.ShowContextMenu(_lblOverlayName, mouseState); + } + + private void OnTileButtonTouchLeft(object sender, EventArgs e) + { + _desktop.HideContextMenu(); + _lblOverlayName.Visible = false; + } + + private void OnTxtOverlaySearchChange(object sender, ValueChangedEventArgs e) + { + AddItemToToolGrid(_mainWidget.GridOverlays, OnOverlayButtonClicked, _spriteSheet, e.NewValue); + } + private void OnWallButtonClicked(object sender, EventArgs e) { _state.CurrentWallId = ((ImageButton)sender).Id; _mainWidget.ClearSelection(); ((ImageButton)sender).Border = new SolidBrush(Color.Red); - ((ImageButton)sender).BorderThickness = new Myra.Graphics2D.Thickness(2); + ((ImageButton)sender).BorderThickness = new Thickness(2); _state.InsertMode = InsertMode.Wall; } - private void OnMenuConnectJoinSelected(object sender, EventArgs e) + private void ResetRenderTarget() { - if (!((MenuItem)sender).Enabled) - { - return; - } - - Window window = new() - { - Title = "Join mapping session" - }; - - var content = new SessionWindow(); - content.BtnLogin.Text = "Join"; - content.BtnLogin.Click += OnButtonJoinSessionClicked; - - window.Content = content; - - window.ShowModal(_desktop); - content.TxtSession.SetKeyboardFocus(); - } - - private void OnMenuConnectLoginSelected(object sender, EventArgs e) - { - Window window = new() - { - Title = "Login" - }; - - var content = new LoginRegisterWindow(); - content.RdoLogin.IsPressed = true; - content.RdoLogin.Click += (s, e) => - { - content.TxtFirstname.Visible = false; - content.TxtLastname.Visible = false; - content.TxtInitials.Visible = false; - content.LblFirstname.Visible = false; - content.LblLastname.Visible = false; - content.LblInitials.Visible = false; - content.BtnLogin.Visible = true; - content.BtnRegister.Visible = false; - window.Title = "Login"; - }; - - content.RdoRegister.Click += (s, e) => - { - content.TxtFirstname.Visible = true; - content.TxtLastname.Visible = true; - content.TxtInitials.Visible = true; - content.LblFirstname.Visible = true; - content.LblLastname.Visible = true; - content.LblInitials.Visible = true; - content.BtnLogin.Visible = false; - content.BtnRegister.Visible = true; - window.Title = "Register"; - }; - - content.BtnRegister.Click += OnButtonRegisterClick; - content.BtnLogin.Click += OnButtonLoginClick; - - window.Content = content; - window.ShowModal(_desktop); - content.TxtEmail.SetKeyboardFocus(); - } - - private async void OnMenuConnectSyncSelected(object sender, EventArgs e) - { - if (!((MenuItem)sender).Enabled) - { - return; - } - - var serverMap = await _communicationManager.Api.Session(_sessionData.SessionName); - _sessionData.Overlays = serverMap.Overlays; - _sessionData.Map = serverMap.Map; - _sessionData.Walls = serverMap.Walls; - _sessionData.Notes = serverMap.Notes; - _sessionData.Lines = serverMap.Lines; - _sessionData.Rooms = serverMap.Rooms; - } - - private async void OnMenuConnectUploadSelected(object sender, EventArgs e) - { - if (!((MenuItem)sender).Enabled) - { - return; - } - - await _communicationManager.Api.SaveSnapshot(_sessionData, _sessionData.SessionName); - } - - private void OnMenuConnectNewSelected(object sender, EventArgs e) - { - if (!((MenuItem)sender).Enabled) - { - return; - } - - Window window = new() - { - Title = "New mapping session" - }; - - var content = new SessionWindow(); - content.BtnLogin.Text = "Join"; - content.BtnLogin.Click += OnButtonNewSessionClicked; - window.Content = content; - - window.ShowModal(_desktop); - content.TxtSession.SetKeyboardFocus(); - } - - private void OnMenuFileSaveSelected(object sender, EventArgs e) - { - FileDialog dialog = new(FileDialogMode.SaveFile) - { - Filter = "*.map" - }; - - dialog.Closed += (s, a) => - { - if (!dialog.Result) - { - return; - } - - using StreamWriter file = File.CreateText(dialog.FilePath); - JsonSerializer serializer = new(); - serializer.Serialize(file, _sessionData); - }; - - dialog.ShowModal(_desktop); - } - - private void OnMenuFileLoadSelected(object sender, EventArgs e) - { - var dialog = new FileDialog(FileDialogMode.OpenFile) - { - Filter = "*.map" - }; - - dialog.Closed += (s, a) => - { - if (!dialog.Result) - { - return; - } - using StreamReader file = File.OpenText(dialog.FilePath); - JsonSerializer serializer = new(); - var loadData = (Session)serializer.Deserialize(file, typeof(Session)); - _sessionData.Map = loadData.Map; - _sessionData.Overlays = loadData.Overlays; - _sessionData.Walls = loadData.Walls; - _sessionData.Rooms = loadData.Rooms; - _sessionData.Lines = loadData.Lines; - }; - - dialog.ShowModal(_desktop); - } - - private void OnMapEntityAdded(object sender, MapEntityAddedEventArgs e) - { - _communicationManager.Enqueue(e.MapEntity, TileAction.Add); - } - - private void OnMapEntityDeleted(object sender, MapEntityDeletedEventArgs e) - { - _communicationManager.Enqueue(e.MapEntity, TileAction.Delete); - } - - private bool ValidateTextbox(TextBox textBox) - { - var valid = !string.IsNullOrWhiteSpace(textBox.Text); - if (!valid) - { - textBox.Background = new SolidBrush(Color.Red); - } - else - { - textBox.Background = new SolidBrush(new Color(51, 51, 51)); ; - } - return valid; - + _renderTarget = new RenderTarget2D(GraphicsDevice, + GraphicsDevice.Viewport.Width, + GraphicsDevice.Viewport.Height, + false, + SurfaceFormat.Color, + DepthFormat.None, + 0, + RenderTargetUsage.DiscardContents); } } - - internal class SpriteSheet - { - internal Texture2D Texture; - internal Dictionary index; - - public void LoadContent(ContentManager content, string spriteIndex, string texture) - { - index = content.Load>(spriteIndex); - Texture = content.Load(texture); - } - - internal Rectangle? SourceRectangle(string spriteName) - { - Rectangle r; - bool hasValue = index.TryGetValue(spriteName, out r); - - if (hasValue) - { - return r; - } - else - { - throw new Exception("value doesn't exist"); - } - } - } - - -} +} \ No newline at end of file diff --git a/Sledgemapper/Sledgemapper.csproj b/Sledgemapper/Sledgemapper.csproj index f46b757..4789d7e 100644 --- a/Sledgemapper/Sledgemapper.csproj +++ b/Sledgemapper/Sledgemapper.csproj @@ -1,14 +1,14 @@ - - Exe - net5.0 - false - false - false - - <_ExtraTrimmerArgs>$(_ExtraTrimmerArgs) --verbose - - + <_ExtraTrimmerArgs>$(_ExtraTrimmerArgs) --verbose + + - - app.manifest - Icon.ico - - - DEBUG;TRACE - - - TRACE - - - - - - - - - - - - - - - - - - - - - - 5.0.0 - - - - - - + + + + + + + + + + + + 6.0.0-preview.7.21378.6 + + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + PreserveNewest + + - - - - PreserveNewest - - - - - + + + + + + $([System.String]::Copy(%(Filename)).Replace(".Custom",".cs")) + + + $([System.String]::Copy(%(Filename)).Replace(".Generated",".cs")) + + + $([System.String]::Concat(%(Filename), ".cs")) + + + + + $([System.String]::Copy(%(Filename)).Replace(".Generated",".cs")) + + + + + PreserveNewest + + + + \ No newline at end of file diff --git a/Sledgemapper/SpriteSheet.cs b/Sledgemapper/SpriteSheet.cs new file mode 100644 index 0000000..00bc421 --- /dev/null +++ b/Sledgemapper/SpriteSheet.cs @@ -0,0 +1,37 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; + +namespace Sledgemapper +{ + internal class SpriteSheet + { + internal Texture2D Texture; + internal Dictionary index; + + public void LoadContent(ContentManager content, string spriteIndex, string texture) + { + index = content.Load>(spriteIndex); + Texture = content.Load(texture); + } + + internal Rectangle? SourceRectangle(string spriteName) + { + Rectangle r; + bool hasValue = index.TryGetValue(spriteName, out r); + + if (hasValue) + { + return r; + } + else + { + throw new Exception("value doesn't exist"); + } + } + } + + +} diff --git a/Sledgemapper/State.cs b/Sledgemapper/State.cs index d03d93b..c5aa3ac 100644 --- a/Sledgemapper/State.cs +++ b/Sledgemapper/State.cs @@ -1,12 +1,13 @@ using Microsoft.Xna.Framework; using System; using Sledgemapper.Shared.Entities; -using System.Collections.Generic; namespace Sledgemapper { - public class State + public sealed class State { + private static readonly State instance = new (); + public Tile SelectedTile { get; set; } public Tile HoveredTile { get; set; } public Wall SelectedWall { get; set; } @@ -19,10 +20,21 @@ namespace Sledgemapper public string CurrentOverlayId { get; set; } public SnapPoint LineStart { get; internal set; } public float LineWidth { get; internal set; } + public Vector3 ViewportCenter { get; set; } + public InsertMode InsertMode { get; set; } + public bool ShowCellNumbers { get; set; } + public string CampaignName { get; set; } + public Guid CampaignId { get; internal set; } + public string MapName { get; internal set; } + public Guid MapId { get; internal set; } - public InsertMode InsertMode; + // Explicit static constructor to tell C# compiler + // not to mark type as beforefieldinit + static State() + { + } - public State() + private State() { CurrentTileId = ""; CurrentWallId = ""; @@ -33,9 +45,20 @@ namespace Sledgemapper SelectedOverlay = new() { X = 1, Y = 1 }; SelectedNote = new() { X = 1, Y = 1 }; TileSize = 30; - LineWidth=1; + LineWidth = 1; + ViewportCenter = new(0, 0, 0); } + public static State Instance + { + get + { + return instance; + } + } + + public Guid SessionId { get; internal set; } + public void SelectClosestWall(Point mousePosition) { var topLeft = new Point(HoveredTile.X * TileSize, HoveredTile.Y * TileSize); @@ -75,7 +98,6 @@ namespace Sledgemapper return ((p1.X - p2.X) * (p1.X - p2.X) + (p1.Y - p2.Y) * (p1.Y - p2.Y)) < d * d; } - public void SelectClosestSnapPoint(Point mousePosition) { var distance = TileSize / 4; @@ -116,9 +138,8 @@ namespace Sledgemapper { SelectedSnapPoint = new SnapPoint { X = HoveredTile.X, Y = HoveredTile.Y+1, Index = 2 }; } - - } + public void SelectOverlay(Point mousePosition) { SelectedOverlay.X = HoveredTile.X; diff --git a/Sledgemapper/UI/CampaignList.Custom.cs b/Sledgemapper/UI/CampaignList.Custom.cs new file mode 100644 index 0000000..ed6e1dd --- /dev/null +++ b/Sledgemapper/UI/CampaignList.Custom.cs @@ -0,0 +1,97 @@ +using Myra.Graphics2D.Brushes; +using Myra.Graphics2D.UI; +using Sledgemapper.Messages; +using System; +using System.Threading.Tasks; +using TinyMessenger; + +namespace Sledgemapper.UI +{ + public partial class CampaignList + { + private CommunicationManager CommunicationManager { get; } + private TinyMessengerHub Messenger { get; } + + private bool _campaignSelected; + + public CampaignList(CommunicationManager communicationManager, TinyMessengerHub messenger) + { + BuildUI(); + CommunicationManager = communicationManager; + Messenger = messenger; + + BtnNewCampaign.Click += (s, e) => + { + OnMenuCampaignNew(s, e); + this.GetContainingWindow().Close(); + }; + + BtnLoadCampaign.Click += (s, e) => + { + if (_campaignSelected) + { + _campaignSelected = false; + Messenger.Publish(new CampaignSelectedMessage(this)); + this.GetContainingWindow().Close(); + } + }; + + BtnCancelCampaign.Click += (s, e) => + { + this.GetContainingWindow().Close(); + }; + } + + private void OnMenuCampaignNew(object sender, EventArgs e) + { + if (sender is MenuItem { Enabled: false }) + { + return; + } + + new CampaignWindow(CommunicationManager, Messenger).ShowInModalWindow(Desktop, "New campaign"); + } + + private void OnCampaignSelected(object sender, EventArgs e) + { + var item = sender as ListItem; + + State.Instance.CampaignName = item.ItemName.Text; + State.Instance.CampaignId = (Guid)item.Tag; + var list = item.Parent as Grid; + for (var i = 0; i < list.ChildrenCount; i++) + { + if (list.GetChild(i) is HorizontalStackPanel currentItem) currentItem.Background = new SolidBrush("#D9D9D9FF"); + } + item.Background = new SolidBrush(Settings.Instance.OverlayTintColor); + _campaignSelected = true; + } + + public async Task LoadCampaigns() + { + var campaigns = await CommunicationManager.GetCampaigns(); + + if (campaigns is null) + { + + return false; + } + + foreach (var campaign in campaigns) + { + var item = new ListItem + { + ItemName = + { + Text = campaign.Name + }, + Tag = campaign.Id + }; + item.TouchUp += OnCampaignSelected; + StackCampaignsList.AddChild(item); + } + + return true; + } + } +} \ No newline at end of file diff --git a/Sledgemapper/UI/CampaignList.Generated.cs b/Sledgemapper/UI/CampaignList.Generated.cs new file mode 100644 index 0000000..d4aea85 --- /dev/null +++ b/Sledgemapper/UI/CampaignList.Generated.cs @@ -0,0 +1,86 @@ +/* Generated by MyraPad at 02/09/2021 23:40:23 */ +using Myra; +using Myra.Graphics2D; +using Myra.Graphics2D.TextureAtlases; +using Myra.Graphics2D.UI; +using Myra.Graphics2D.Brushes; +using Myra.Graphics2D.UI.Properties; + +#if MONOGAME || FNA +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +#elif STRIDE +using Stride.Core.Mathematics; +#else +using System.Drawing; +using System.Numerics; +#endif + +namespace Sledgemapper.UI +{ + partial class CampaignList: VerticalStackPanel + { + private void BuildUI() + { + var label1 = new Label(); + label1.Text = "Campaigns"; + label1.HorizontalAlignment = Myra.Graphics2D.UI.HorizontalAlignment.Center; + + StackCampaignsList = new VerticalStackPanel(); + StackCampaignsList.DefaultProportion = new Proportion + { + Type = Myra.Graphics2D.UI.ProportionType.Auto, + }; + StackCampaignsList.Id = "StackCampaignsList"; + + var scrollViewer1 = new ScrollViewer(); + scrollViewer1.Height = 250; + scrollViewer1.Content = StackCampaignsList; + + BtnNewCampaign = new TextButton(); + BtnNewCampaign.Text = "New"; + BtnNewCampaign.Width = 70; + BtnNewCampaign.Height = 20; + BtnNewCampaign.Padding = new Thickness(5); + BtnNewCampaign.HorizontalAlignment = Myra.Graphics2D.UI.HorizontalAlignment.Center; + BtnNewCampaign.Id = "BtnNewCampaign"; + + BtnLoadCampaign = new TextButton(); + BtnLoadCampaign.Text = "Load"; + BtnLoadCampaign.Width = 70; + BtnLoadCampaign.Height = 20; + BtnLoadCampaign.Padding = new Thickness(5); + BtnLoadCampaign.HorizontalAlignment = Myra.Graphics2D.UI.HorizontalAlignment.Center; + BtnLoadCampaign.Id = "BtnLoadCampaign"; + + BtnCancelCampaign = new TextButton(); + BtnCancelCampaign.Text = "Cancel"; + BtnCancelCampaign.Width = 70; + BtnCancelCampaign.Height = 20; + BtnCancelCampaign.Padding = new Thickness(5); + BtnCancelCampaign.HorizontalAlignment = Myra.Graphics2D.UI.HorizontalAlignment.Center; + BtnCancelCampaign.Id = "BtnCancelCampaign"; + + var horizontalStackPanel1 = new HorizontalStackPanel(); + horizontalStackPanel1.Spacing = 15; + horizontalStackPanel1.HorizontalAlignment = Myra.Graphics2D.UI.HorizontalAlignment.Right; + horizontalStackPanel1.Widgets.Add(BtnNewCampaign); + horizontalStackPanel1.Widgets.Add(BtnLoadCampaign); + horizontalStackPanel1.Widgets.Add(BtnCancelCampaign); + + + Spacing = 13; + Width = 400; + Padding = new Thickness(10); + Widgets.Add(label1); + Widgets.Add(scrollViewer1); + Widgets.Add(horizontalStackPanel1); + } + + + public VerticalStackPanel StackCampaignsList; + public TextButton BtnNewCampaign; + public TextButton BtnLoadCampaign; + public TextButton BtnCancelCampaign; + } +} diff --git a/Sledgemapper/UI/CampaignList.cs b/Sledgemapper/UI/CampaignList.cs new file mode 100644 index 0000000..a22afef --- /dev/null +++ b/Sledgemapper/UI/CampaignList.cs @@ -0,0 +1,11 @@ +/* Generated by MyraPad at 01/06/2021 12:43:27 */ +namespace Sledgemapper.UI +{ + public partial class CampaignList + { + public CampaignList() + { + BuildUI(); + } + } +} \ No newline at end of file diff --git a/Sledgemapper/UI/CampaignList.xmmp b/Sledgemapper/UI/CampaignList.xmmp new file mode 100644 index 0000000..f56979c --- /dev/null +++ b/Sledgemapper/UI/CampaignList.xmmp @@ -0,0 +1,16 @@ + + + + + \ No newline at end of file diff --git a/Sledgemapper/UI/CampaignWindow.Custom.cs b/Sledgemapper/UI/CampaignWindow.Custom.cs new file mode 100644 index 0000000..0689349 --- /dev/null +++ b/Sledgemapper/UI/CampaignWindow.Custom.cs @@ -0,0 +1,77 @@ +using Sentry; +using System; +using TinyMessenger; + +namespace Sledgemapper.UI +{ + public partial class CampaignWindow + { + private readonly CommunicationManager CommunicationManager; + private readonly TinyMessengerHub Messenger; + + public CampaignWindow(CommunicationManager communicationManager, TinyMessengerHub messenger) + { + BuildUI(); + CommunicationManager = communicationManager; + Messenger = messenger; + BtnNewCampaign.Click += OnButtonNewCampaignClicked; + } + + private async void OnButtonNewCampaignClicked(object sender, EventArgs e) + { + //var localContent = ((TextButton)sender).GetParentContentInWindow();// localWindow.Content as PlayerWindow; + + var isValid = TxtCampaign.ValidateTextbox(); + if (!isValid) + { + return; + } + + //if (CommunicationManager.Connection.State != HubConnectionState.Connected) + //{ + // lblConnectionStatus.Text = "Connecting"; + // await CommunicationManager.Connection.StartAsync(); + // UpdateConnectionState(CommunicationManager.Connection); + //} + + var successful = false; + try + { + await CommunicationManager.Api.NewCampaign(TxtCampaign.Text); + + //if (result) + //{ + // CommunicationManager.SessionData.SessionName = localContent.TxtSession.Text; + // CommunicationManager.SessionData.MapEntityAdded -= OnMapEntityAdded; + // CommunicationManager.SessionData.MapEntityDeleted -= OnMapEntityDeleted; + // CommunicationManager.SessionData.MapEntityAdded += OnMapEntityAdded; + // CommunicationManager.SessionData.MapEntityDeleted += OnMapEntityDeleted; + //} + //successful = result; + //var result2 = await CommunicationManager.Connection?.InvokeAsync("JoinSession", localContent.TxtSession.Text); + //CommunicationManager.SessionData.SessionId = result2.SessionId; + //CommunicationManager.SessionData.SessionName = localContent.TxtSession.Text; + } + catch (Exception ex) + { + SentrySdk.CaptureException(ex); + //ExceptionlessClient.Default.SubmitException(ex); + } + + //if (successful) + //{ + // //CommunicationManager.SessionData.SessionName = localContent.TxtSession.Text; + // //CommunicationManager.SessionData.Map = CommunicationManager.SessionData.Map; + // //CommunicationManager.SessionData.Overlays = CommunicationManager.SessionData.Overlays; + // //CommunicationManager.SessionData.Walls = CommunicationManager.SessionData.Walls; + // //lblSessionName.Text = CommunicationManager.SessionData.SessionName; + // //MenuConnectSync.Enabled = true; + // //MenuConnectUpload.Enabled = true; + // localWindow.Close(); + //} + + this.GetContainingWindow().Close(); + + } + } +} \ No newline at end of file diff --git a/Sledgemapper/UI/CampaignWindow.Generated.cs b/Sledgemapper/UI/CampaignWindow.Generated.cs new file mode 100644 index 0000000..e913b0e --- /dev/null +++ b/Sledgemapper/UI/CampaignWindow.Generated.cs @@ -0,0 +1,67 @@ +/* Generated by MyraPad at 28/05/2021 22:36:14 */ +using Myra; +using Myra.Graphics2D; +using Myra.Graphics2D.TextureAtlases; +using Myra.Graphics2D.UI; +using Myra.Graphics2D.Brushes; +using Myra.Graphics2D.UI.Properties; + +#if MONOGAME || FNA +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +#elif STRIDE +using Stride.Core.Mathematics; +#else +using System.Drawing; +using System.Numerics; +#endif + +namespace Sledgemapper.UI +{ + partial class CampaignWindow: VerticalStackPanel + { + private void BuildUI() + { + var label1 = new Label(); + label1.Text = "Campaign"; + + TxtCampaign = new TextBox(); + TxtCampaign.GridColumn = 1; + TxtCampaign.Id = "TxtCampaign"; + + var grid1 = new Grid(); + grid1.ColumnSpacing = 25; + grid1.RowSpacing = 10; + grid1.ColumnsProportions.Add(new Proportion + { + Type = Myra.Graphics2D.UI.ProportionType.Pixels, + Value = 60, + }); + grid1.ColumnsProportions.Add(new Proportion + { + Type = Myra.Graphics2D.UI.ProportionType.Fill, + }); + grid1.Widgets.Add(label1); + grid1.Widgets.Add(TxtCampaign); + + BtnNewCampaign = new TextButton(); + BtnNewCampaign.Text = "New"; + BtnNewCampaign.Padding = new Thickness(10, 5); + BtnNewCampaign.HorizontalAlignment = Myra.Graphics2D.UI.HorizontalAlignment.Center; + BtnNewCampaign.Id = "BtnNewCampaign"; + + + Spacing = 16; + HorizontalAlignment = Myra.Graphics2D.UI.HorizontalAlignment.Center; + VerticalAlignment = Myra.Graphics2D.UI.VerticalAlignment.Center; + Width = 300; + Padding = new Thickness(10); + Widgets.Add(grid1); + Widgets.Add(BtnNewCampaign); + } + + + public TextBox TxtCampaign; + public TextButton BtnNewCampaign; + } +} diff --git a/Sledgemapper/UI/CampaignWindow.cs b/Sledgemapper/UI/CampaignWindow.cs new file mode 100644 index 0000000..24447b9 --- /dev/null +++ b/Sledgemapper/UI/CampaignWindow.cs @@ -0,0 +1,11 @@ +/* Generated by MyraPad at 28/05/2021 22:36:14 */ +namespace Sledgemapper.UI +{ + public partial class CampaignWindow + { + public CampaignWindow() + { + BuildUI(); + } + } +} \ No newline at end of file diff --git a/Sledgemapper/UI/ErrorWindow.Custom.cs b/Sledgemapper/UI/ErrorWindow.Custom.cs new file mode 100644 index 0000000..93036d9 --- /dev/null +++ b/Sledgemapper/UI/ErrorWindow.Custom.cs @@ -0,0 +1,17 @@ + + +using Myra.Graphics2D.Brushes; +using Myra.Graphics2D.UI; + +namespace Sledgemapper.UI +{ + partial class ErrorWindow : VerticalStackPanel + { + + public ErrorWindow(string message) + { + BuildUI(); + TxtError.Text = message; + } + } +} diff --git a/Sledgemapper/UI/ErrorWindow.Generated.cs b/Sledgemapper/UI/ErrorWindow.Generated.cs new file mode 100644 index 0000000..f90037d --- /dev/null +++ b/Sledgemapper/UI/ErrorWindow.Generated.cs @@ -0,0 +1,42 @@ +/* Generated by MyraPad at 21/09/2021 16:37:58 */ +using Myra; +using Myra.Graphics2D; +using Myra.Graphics2D.TextureAtlases; +using Myra.Graphics2D.UI; +using Myra.Graphics2D.Brushes; +using Myra.Graphics2D.UI.Properties; + +#if MONOGAME || FNA +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +#elif STRIDE +using Stride.Core.Mathematics; +#else +using System.Drawing; +using System.Numerics; +#endif + +namespace Sledgemapper.UI +{ + partial class ErrorWindow: VerticalStackPanel + { + private void BuildUI() + { + TxtError = new Label(); + TxtError.Text = "Error Message"; + TxtError.HorizontalAlignment = Myra.Graphics2D.UI.HorizontalAlignment.Center; + TxtError.VerticalAlignment = Myra.Graphics2D.UI.VerticalAlignment.Center; + TxtError.Id = "TxtError"; + + + Width = 400; + Height = 40; + Padding = new Thickness(10); + Background = new SolidBrush("#FE3930FF"); + Widgets.Add(TxtError); + } + + + public Label TxtError; + } +} diff --git a/Sledgemapper/UI/ErrorWindow.cs b/Sledgemapper/UI/ErrorWindow.cs new file mode 100644 index 0000000..2fdcb86 --- /dev/null +++ b/Sledgemapper/UI/ErrorWindow.cs @@ -0,0 +1,11 @@ +/* Generated by MyraPad at 21/09/2021 16:37:58 */ +namespace Sledgemapper.UI +{ + public partial class ErrorWindow + { + public ErrorWindow() + { + BuildUI(); + } + } +} \ No newline at end of file diff --git a/Sledgemapper/UI/ErrorWindow.xmmp b/Sledgemapper/UI/ErrorWindow.xmmp new file mode 100644 index 0000000..3ea8486 --- /dev/null +++ b/Sledgemapper/UI/ErrorWindow.xmmp @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/Sledgemapper/UI/ListItem.Custom.cs b/Sledgemapper/UI/ListItem.Custom.cs new file mode 100644 index 0000000..34ead63 --- /dev/null +++ b/Sledgemapper/UI/ListItem.Custom.cs @@ -0,0 +1,8 @@ +/* Generated by MyraPad at 03/09/2021 16:19:13 */ +namespace Sledgemapper.UI +{ + public partial class ListItem + { + + } +} \ No newline at end of file diff --git a/Sledgemapper/UI/ListItem.Generated.cs b/Sledgemapper/UI/ListItem.Generated.cs new file mode 100644 index 0000000..aadd154 --- /dev/null +++ b/Sledgemapper/UI/ListItem.Generated.cs @@ -0,0 +1,45 @@ +/* Generated by MyraPad at 03/09/2021 16:50:20 */ +using Myra; +using Myra.Graphics2D; +using Myra.Graphics2D.TextureAtlases; +using Myra.Graphics2D.UI; +using Myra.Graphics2D.Brushes; +using Myra.Graphics2D.UI.Properties; + +#if MONOGAME || FNA +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +#elif STRIDE +using Stride.Core.Mathematics; +#else +using System.Drawing; +using System.Numerics; +#endif + +namespace Sledgemapper.UI +{ + partial class ListItem: HorizontalStackPanel + { + private void BuildUI() + { + ItemName = new Label(); + ItemName.Text = "Highfell"; + ItemName.TextColor = ColorStorage.CreateColor(32, 32, 32, 255); + ItemName.Margin = new Thickness(10, 0, 0, 0); + ItemName.VerticalAlignment = Myra.Graphics2D.UI.VerticalAlignment.Center; + ItemName.Id = "ItemName"; + + + VerticalAlignment = Myra.Graphics2D.UI.VerticalAlignment.Center; + Height = 30; + BorderThickness = new Thickness(2); + Padding = new Thickness(5); + Background = new SolidBrush("#D9D9D9FF"); + Id = "PnlListItem"; + Widgets.Add(ItemName); + } + + + public Label ItemName; + } +} diff --git a/Sledgemapper/UI/ListItem.cs b/Sledgemapper/UI/ListItem.cs new file mode 100644 index 0000000..7a8e401 --- /dev/null +++ b/Sledgemapper/UI/ListItem.cs @@ -0,0 +1,12 @@ +/* Generated by MyraPad at 03/09/2021 16:19:13 */ +namespace Sledgemapper.UI +{ + public partial class ListItem + { + public ListItem() + { + BuildUI(); + + } + } +} \ No newline at end of file diff --git a/Sledgemapper/UI/LoginRegisterWindow.Custom.cs b/Sledgemapper/UI/LoginRegisterWindow.Custom.cs new file mode 100644 index 0000000..f565e68 --- /dev/null +++ b/Sledgemapper/UI/LoginRegisterWindow.Custom.cs @@ -0,0 +1,211 @@ +using System; +using System.Diagnostics; +using System.Linq; +using Myra.Graphics2D.UI; +using Sledgemapper.Messages; +using Sledgemapper.Shared.Entities; +using TinyMessenger; + +namespace Sledgemapper.UI +{ + public partial class LoginRegisterWindow + { + private AuthenticateResponse _authResponse; + private readonly CommunicationManager CommunicationManager; + private readonly TinyMessengerHub _messenger; + + public LoginRegisterWindow(CommunicationManager communicationManager, TinyMessengerHub messenger) + { + BuildUI(); + CommunicationManager = communicationManager; + _messenger = messenger; + +#if DEBUG + TxtEmail.Text = "michele.scandura@outlook.com"; + TxtPassword.Text = "slePharland!79"; +#endif + + RdoLogin.IsPressed = true; + RdoLogin.Click += (s, e) => + { + TxtFirstname.Visible = false; + TxtLastname.Visible = false; + TxtInitials.Visible = false; + LblFirstname.Visible = false; + LblLastname.Visible = false; + LblInitials.Visible = false; + BtnLogin.Visible = true; + BtnRegister.Visible = false; + this.GetContainingWindow().Title = "Login"; + }; + + RdoRegister.Click += (s, e) => + { + TxtFirstname.Visible = true; + TxtLastname.Visible = true; + TxtInitials.Visible = true; + LblFirstname.Visible = true; + LblLastname.Visible = true; + LblInitials.Visible = true; + BtnLogin.Visible = false; + BtnRegister.Visible = true; + this.GetContainingWindow().Title = "Register"; + }; + + BtnRegister.Click += OnButtonRegisterClick; + BtnLogin.Click += OnButtonLoginClick; + } + + private async void OnButtonRegisterClick(object sender, EventArgs e) + { + var button = ((TextButton)sender); + + if (!button.Enabled) + { + return; + } + + var isValid = true; + isValid &= TxtEmail.ValidateTextbox(); + isValid &= TxtPassword.ValidateTextbox(); + isValid &= TxtFirstname.ValidateTextbox(); + isValid &= TxtLastname.ValidateTextbox(); + isValid &= TxtInitials.ValidateTextbox(); + + if (!isValid) + { + LblLoginError.Text = "Please complete all the fields"; + LblLoginError.Visible = true; + return; + } + + var successful = false; + try + { + button.Text = "Wait..."; + LblLoginError.Text = ""; + LblLoginError.Visible = false; + + var result = await CommunicationManager.Register(new RegisterModel + { + Username = TxtEmail.Text, + Email = TxtEmail.Text, + Password = TxtPassword.Text, + FirstName = TxtFirstname.Text, + LastName = TxtLastname.Text, + Initials = TxtInitials.Text + }); + if (result.Result) + { + _authResponse = await CommunicationManager.Login(new AuthenticateModel + { + Username = TxtEmail.Text, + Email = TxtEmail.Text, + Password = TxtPassword.Text + }); + successful = true; + } + else + { + LblLoginError.Text = result.Errors.FirstOrDefault(); + LblLoginError.Visible = true; + } + } + catch (Refit.ApiException refitException) + { + //ExceptionlessClient.Default.SubmitException(refitException); + LblLoginError.Text = refitException.Content; + LblLoginError.Visible = true; + } + catch (Exception ex) + { + //ExceptionlessClient.Default.SubmitException(ex); + LblLoginError.Text = "Can't connect to the server"; + LblLoginError.Visible = true; + Debug.Write(ex); + } + finally + { + button.Enabled = true; + button.Text = "Register"; + } + if (successful) + { + _messenger.Publish(new LoginSuccesfulMessage(this) { UserName = _authResponse.Username, Initials = _authResponse.Initials }); + this.GetContainingWindow().Close(); + } + } + + private async void OnButtonLoginClick(object sender, EventArgs e) + { + var button = ((TextButton)sender); + Container container = button.Parent; + while (!(container is Window)) + { + container = container.Parent; + } + + var localWindow = (Window)container; + var localContent = localWindow.Content as LoginRegisterWindow; + + if (!button.Enabled) + { + return; + } + + var isValid = true; + isValid &= localContent.TxtEmail.ValidateTextbox(); + isValid &= localContent.TxtPassword.ValidateTextbox(); + + if (!isValid) + { + localContent.LblLoginError.Text = "Username or password is not valid"; + localContent.LblLoginError.Visible = true; + + return; + } + + var successful = false; + try + { + button.Text = "Wait..."; + localContent.LblLoginError.Text = ""; + localContent.LblLoginError.Visible = false; + _authResponse = await CommunicationManager.Login(new AuthenticateModel + { + Username = localContent.TxtEmail.Text, + Email = localContent.TxtEmail.Text, + Password = localContent.TxtPassword.Text + }); + successful = _authResponse != null; + } + catch (Refit.ApiException refitException) + { + //ExceptionlessClient.Default.SubmitException(refitException); + localContent.LblLoginError.Text = refitException.Content; + localContent.LblLoginError.Visible = true; + } + catch (Exception ex) + { + //ExceptionlessClient.Default.SubmitException(ex); + localContent.LblLoginError.Text = "Can't connect to the server"; + localContent.LblLoginError.Visible = true; + Debug.Write(ex); + } + finally + { + button.Enabled = true; + button.Text = "Login"; + } + + if (successful) + { + _messenger.Publish(new LoginSuccesfulMessage(this) { UserName = _authResponse.Username, Initials = _authResponse.Initials }); + localWindow.Close(); + } + } + } + + + +} \ No newline at end of file diff --git a/Sledgemapper/UI/loginwindow.xml b/Sledgemapper/UI/LoginRegisterWindow.xmmp similarity index 100% rename from Sledgemapper/UI/loginwindow.xml rename to Sledgemapper/UI/LoginRegisterWindow.xmmp diff --git a/Sledgemapper/UI/MainWidget.Custom.cs b/Sledgemapper/UI/MainWidget.Custom.cs index 1067a3a..c2b6686 100644 --- a/Sledgemapper/UI/MainWidget.Custom.cs +++ b/Sledgemapper/UI/MainWidget.Custom.cs @@ -1,30 +1,450 @@ +using System; +using System.IO; +using Microsoft.AspNetCore.SignalR.Client; +using Microsoft.Xna.Framework; +using Myra.Graphics2D; +using Myra.Graphics2D.Brushes; using Myra.Graphics2D.UI; +using Myra.Graphics2D.UI.File; +using Myra.Graphics2D.UI.Properties; +using Newtonsoft.Json; +using Sledgemapper.Messages; +using Sledgemapper.Shared.Entities; +using TinyMessenger; namespace Sledgemapper.UI { - public partial class MainWidget - { - public void ClearSelection() - { + public partial class MainWidget + { + private CommunicationManager CommunicationManager { get; } + + private TinyMessengerHub Messenger { get; } + + private GameWindow Window { get; } + + public MainWidget(CommunicationManager communicationManager, TinyMessengerHub messenger, GameWindow window) + { + BuildUI(); + CommunicationManager = communicationManager; + Window = window; + Messenger = messenger; + + Messenger.Subscribe(OnLoginSuccesfulMessage); + Messenger.Subscribe(OnSignalrConnectionUpdateMessage); + Messenger.Subscribe(OnMapOpenedMessage); + Messenger.Subscribe(OnCenterOnTileMessage); + Messenger.Subscribe(OnCampaignSelectedMessage); + Messenger.Subscribe(OnErrorMessage); + + + MenuConnectLogin.Selected += OnMenuConnectLoginSelected; + MenuConnectSync.Selected += OnMenuConnectSyncSelected; + MenuFileLoad.Selected += OnMenuFileLoadSelected; + MenuFileSave.Selected += OnMenuFileSaveSelected; + MenuFileSettings.Selected += OneMenuFileSettingsSelected; + //MenuConnectLogin.Selected += OnMenuConnectLoginSelected; + //MenuConnectNew.Selected += OnMenuConnectNewSelected; + //MenuConnectJoin.Selected += OnMenuConnectJoinSelected; + MenuConnectUpload.Selected += OnMenuConnectUploadSelected; + MenuViewCenterOnSelection.Selected += OnMenuViewCenterOnSelectionSelected; + MenuViewShowCellNUmbers.Selected += OnMenuViewShowCellNUmbersSelected; + MenuViewShowNotes.Selected += OnMenuViewNotesSelected; + + MenuCampaingNew.Selected += OnMenuCampaignNew; + MenuCampaignOpen.Selected += OnMenuCampaignOpen; + MenuCampaignPlayers.Selected += OnMenuCampaignPlayersSelected; + + MenuMapOpen.Selected += OnMenuMapOpen; + MenuMapNew.Selected += OnMenuMapNew; + + //MenuConnectNew.Enabled = false; + //MenuConnectJoin.Enabled = false; + MenuConnectSync.Enabled = false; + MenuConnectUpload.Enabled = false; + MenuCampaignOpen.Enabled = false; + MenuCampaignPlayers.Enabled = false; + MenuCampaingNew.Enabled = false; + MenuMapNew.Enabled = false; + MenuMapOpen.Enabled = false; + BtnToolbarLine.Click += OnBtnToolbarLinClicked; + BtnToolbarRoom.Click += OnBtnToolbarRoomClicked; + BtnToolbarDelete.Click += OnBtnToolbarDeleteClicked; + + + } + + private void CenterOnSelectedTile() + { + CenterOnTile(State.Instance.SelectedTile.X, State.Instance.SelectedTile.Y); + } + + private void CenterOnTile(int x, int y) + { + var center = new Point((Window.ClientBounds.Width + 200) / 2 - State.Instance.TileSize / 2, + Window.ClientBounds.Height / 2 - State.Instance.TileSize / 2); + var dx = center.X - x * State.Instance.TileSize - State.Instance.ViewportCenter.X; + var dy = center.Y - y * State.Instance.TileSize - State.Instance.ViewportCenter.Y; + State.Instance.ViewportCenter = new Vector3(State.Instance.ViewportCenter.X + dx, + State.Instance.ViewportCenter.Y + dy, State.Instance.ViewportCenter.Z); + } + + public void ClearSelection() + { ClearSelection(GridWalls); ClearSelection(GridOverlays); ClearSelection(Toolbar); - } + } private void ClearSelection(Grid grid) { - foreach (var widget in grid.Widgets) + foreach (var widget in grid.Widgets) widget.Border = null; + } + + private void ClearSelection(HorizontalStackPanel grid) + { + foreach (var widget in grid.Widgets) widget.Border = null; + } + + //TODO Refactor + private void EditNote(Note note) + { + State.Instance.SelectedNote = new Note { X = note.X, Y = note.Y, Text = note.Text }; + new NoteWindow(CommunicationManager, note).ShowInModalWindow(Desktop, $" Note on {note.X}:{note.Y}"); + } + + private void OnBtnToolbarDeleteClicked(object sender, EventArgs e) + { + State.Instance.InsertMode = InsertMode.NewDelete; + + ClearSelection(); + ((ImageTextButton)sender).Border = new SolidBrush(Color.Red); + ((ImageTextButton)sender).BorderThickness = new Thickness(2); + } + + private void OnBtnToolbarLinClicked(object sender, EventArgs e) + { + State.Instance.InsertMode = InsertMode.NewLine; + ClearSelection(); + ((ImageTextButton)sender).Border = new SolidBrush(Color.Red); + ((ImageTextButton)sender).BorderThickness = new Thickness(2); + } + + //private async void OnButtonJoinSessionClicked(object sender, EventArgs e) + //{ + // var localContent = ((TextButton)sender).GetParentContentInWindow(); + + // var isValid = localContent.Content.TxtSession.ValidateTextbox(); + // if (!isValid) + // { + // return; + // } + + // if (CommunicationManager.Connection.State != HubConnectionState.Connected) + // { + // lblConnectionStatus.Text = "Connecting"; + // await CommunicationManager.Connection.StartAsync(); + // UpdateConnectionState(CommunicationManager.Connection); + // } + + // var successful = false; + // try + // { + // var result = await CommunicationManager.Connection?.InvokeAsync("JoinSession", localContent.Content.TxtSession.Text); + // if (result != null) + // { + // CommunicationManager.SessionData.Map = result.Map; + // CommunicationManager.SessionData.Walls = result.Walls; + // CommunicationManager.SessionData.Overlays = result.Overlays; + + // CommunicationManager.SessionData.MapEntityAdded -= OnMapEntityAdded; + // CommunicationManager.SessionData.MapEntityDeleted -= OnMapEntityDeleted; + // CommunicationManager.SessionData.MapEntityAdded += OnMapEntityAdded; + // CommunicationManager.SessionData.MapEntityDeleted += OnMapEntityDeleted; + // //CommunicationManager.SessionData.SessionId = result.SessionId; + // //CommunicationManager.SessionData.SessionName = result.SessionName; + // } + // successful = result != null; + // } + // catch (Exception ex) + // { + // Console.WriteLine(ex.Message); + // } + + // if (successful) + // { + // CommunicationManager.SessionData.SessionName = localContent.Content.TxtSession.Text; + // lblMap.Text = CommunicationManager.SessionData.SessionName; + // MenuConnectSync.Enabled = true; + // MenuConnectUpload.Enabled = true; + // localContent.Window.Close(); + // } + //} + private void OnBtnToolbarRoomClicked(object sender, EventArgs e) + { + State.Instance.InsertMode = InsertMode.NewRoom; + ClearSelection(); + ((ImageTextButton)sender).Border = new SolidBrush(Color.Red); + ((ImageTextButton)sender).BorderThickness = new Thickness(2); + } + + private void OnCampaignSelectedMessage(CampaignSelectedMessage obj) + { + lblCampaign.Text = State.Instance.CampaignName; + + MenuMapNew.Enabled = true; + MenuMapOpen.Enabled = true; + MenuCampaignPlayers.Enabled = true; + } + + private void OnCenterOnTileMessage(CenterOnTileMessage obj) + { + CenterOnTile(obj.X, obj.Y); + } + + private void OnErrorMessage(ErrorMessage obj) + { + new ErrorWindow(obj.Message).Toast(Desktop); + } + + private void OneMenuFileSettingsSelected(object sender, EventArgs e) + { + var propertyGrid = new PropertyGrid { - widget.Border = null; + Object = Settings.Instance, + Width = 350 + }; + + var _windowEditor = new Window + { + Title = "Object Editor", + Content = propertyGrid + }; + _windowEditor.ShowModal(Desktop); + } + + private void OnLoginSuccesfulMessage(LoginSuccesfulMessage obj) + { + //MenuConnectNew.Enabled = true; + //MenuConnectJoin.Enabled = true; + MenuCampaignOpen.Enabled = true; + MenuCampaingNew.Enabled = true; + MenuMapNew.Enabled = false; + MenuMapOpen.Enabled = false; + MenuConnectSync.Enabled = false; + MenuConnectUpload.Enabled = false; + MenuCampaignPlayers.Enabled = false; + lblCampaign.Text = "n/a"; + lblMap.Text = "n/a"; + CommunicationManager.SessionData.MapEntityAdded -= OnMapEntityAdded; + CommunicationManager.SessionData.MapEntityDeleted -= OnMapEntityDeleted; + lblUsername.Text = $"{obj.Initials}"; + } + + private void OnMapEntityAdded(object sender, MapEntityAddedEventArgs e) + { + CommunicationManager.Enqueue(e.MapEntity, TileAction.Add); + } + + private void OnMapEntityDeleted(object sender, MapEntityDeletedEventArgs e) + { + CommunicationManager.Enqueue(e.MapEntity, TileAction.Delete); + } + + private async void OnMapOpenedMessage(MapOpenedMessage obj) + { + lblMap.Text = obj.MapName; + State.Instance.MapId = obj.MapId; + State.Instance.MapName = obj.MapName; + CommunicationManager.SessionData.SessionName = obj.MapName; + CommunicationManager.SessionData.SessionId = obj.MapId; + + MenuConnectSync.Enabled = true; + MenuConnectUpload.Enabled = true; + CommunicationManager.SessionData.MapEntityAdded -= OnMapEntityAdded; + CommunicationManager.SessionData.MapEntityDeleted -= OnMapEntityDeleted; + CommunicationManager.SessionData.MapEntityAdded += OnMapEntityAdded; + CommunicationManager.SessionData.MapEntityDeleted += OnMapEntityDeleted; + var serverMap = await CommunicationManager.Api.GetMap(State.Instance.CampaignId, State.Instance.MapId); + if (CommunicationManager.Connection.State != HubConnectionState.Connected) + { + await CommunicationManager.Connection.StartAsync(); + UpdateConnectionState(CommunicationManager.Connection); + } + + var result = await CommunicationManager.Connection?.InvokeAsync("JoinSession", State.Instance.MapId); + + CommunicationManager.SessionData.Overlays = serverMap.Overlays; + CommunicationManager.SessionData.Map = serverMap.Map; + CommunicationManager.SessionData.Walls = serverMap.Walls; + CommunicationManager.SessionData.Notes = serverMap.Notes; + CommunicationManager.SessionData.Lines = serverMap.Lines; + CommunicationManager.SessionData.Rooms = serverMap.Rooms; + } + + private void OnMenuCampaignNew(object sender, EventArgs e) + { + if (sender is MenuItem { Enabled: false }) return; + + new CampaignWindow(CommunicationManager, Messenger).ShowInModalWindow(Desktop, "New campaign"); + ; + } + + private async void OnMenuCampaignOpen(object sender, EventArgs e) + { + if (!((MenuItem)sender).Enabled) return; + + var content = new CampaignList(CommunicationManager, Messenger); + if (await content.LoadCampaigns()) + { + content.ShowInModalWindow(Desktop, "Campaigns"); } } - private void ClearSelection(HorizontalStackPanel grid) + private async void OnMenuCampaignPlayersSelected(object sender, EventArgs e) { - foreach (var widget in grid.Widgets) + if (!((MenuItem)sender).Enabled) return; + + var content = new PlayerList(CommunicationManager, Messenger); + if (await content.LoadPlayers()) { - widget.Border = null; + content.ShowInModalWindow(Desktop, "Players"); } } - } + + private void OnMenuConnectLoginSelected(object sender, EventArgs e) + { + Window window = new() + { + Title = "Login" + }; + + var content = new LoginRegisterWindow(CommunicationManager, Messenger); + window.Content = content; + window.ShowModal(Desktop); + } + + private async void OnMenuConnectSyncSelected(object sender, EventArgs e) + { + if (!((MenuItem)sender).Enabled) return; + + var serverMap = await CommunicationManager.Api.GetMap(State.Instance.CampaignId, State.Instance.MapId); + CommunicationManager.SessionData.Overlays = serverMap.Overlays; + CommunicationManager.SessionData.Map = serverMap.Map; + CommunicationManager.SessionData.Walls = serverMap.Walls; + CommunicationManager.SessionData.Notes = serverMap.Notes; + CommunicationManager.SessionData.Lines = serverMap.Lines; + CommunicationManager.SessionData.Rooms = serverMap.Rooms; + } + + private async void OnMenuConnectUploadSelected(object sender, EventArgs e) + { + if (!((MenuItem)sender).Enabled) return; + + await CommunicationManager.Api.SaveSnapshot(CommunicationManager.SessionData, State.Instance.MapId); + } + + private void OnMenuFileLoadSelected(object sender, EventArgs e) + { + var dialog = new FileDialog(FileDialogMode.OpenFile) + { + Filter = "*.map" + }; + + dialog.Closed += (s, a) => + { + if (!dialog.Result) return; + using var file = File.OpenText(dialog.FilePath); + JsonSerializer serializer = new(); + var loadData = (Session)serializer.Deserialize(file, typeof(Session)); + CommunicationManager.SessionData.Map = loadData.Map; + CommunicationManager.SessionData.Overlays = loadData.Overlays; + CommunicationManager.SessionData.Walls = loadData.Walls; + CommunicationManager.SessionData.Rooms = loadData.Rooms; + CommunicationManager.SessionData.Lines = loadData.Lines; + }; + + dialog.ShowModal(Desktop); + } + + private void OnMenuFileSaveSelected(object sender, EventArgs e) + { + FileDialog dialog = new(FileDialogMode.SaveFile) + { + Filter = "*.map" + }; + + dialog.Closed += (s, a) => + { + if (!dialog.Result) return; + + using var file = File.CreateText(dialog.FilePath); + JsonSerializer serializer = new(); + serializer.Serialize(file, CommunicationManager.SessionData); + }; + + dialog.ShowModal(Desktop); + } + + private void OnMenuMapNew(object sender, EventArgs e) + { + if (sender is MenuItem { Enabled: false }) return; + + new MapWindow(CommunicationManager, Messenger).ShowInModalWindow(Desktop, "New map"); + } + + private async void OnMenuMapOpen(object sender, EventArgs e) + { + if (!((MenuItem)sender).Enabled) return; + + var content = new MapList(CommunicationManager, Messenger); + if (await content.LoadMaps()) + { + content.ShowInModalWindow(Desktop, "Maps"); + } + } + + private void OnMenuViewCenterOnSelectionSelected(object sender, EventArgs e) + { + CenterOnSelectedTile(); + } + + private void OnMenuViewNotesSelected(object sender, EventArgs e) + { + new NoteList(CommunicationManager, Messenger).ShowInModalWindow(Desktop, "Notes"); + } + + private void OnMenuViewShowCellNUmbersSelected(object sender, EventArgs e) + { + State.Instance.ShowCellNumbers = !State.Instance.ShowCellNumbers; + } + + private async void OnSignalrConnectionUpdateMessage(SignalrConnectionUpdateMessage obj) + { + lblConnectionStatus.Text = "Connecting"; + await CommunicationManager.Connection.StartAsync(); + UpdateConnectionState(CommunicationManager.Connection); + } + + + private void UpdateConnectionState(HubConnection connection) + { + switch (connection.State) + { + case HubConnectionState.Connected: + lblConnectionStatus.Text = "Connected"; + break; + case HubConnectionState.Connecting: + lblConnectionStatus.Text = "Connecting"; + break; + case HubConnectionState.Disconnected: + lblConnectionStatus.Text = "Disconnected"; + + break; + case HubConnectionState.Reconnecting: + lblConnectionStatus.Text = "Reconnecting"; + + break; + } + } + } } \ No newline at end of file diff --git a/Sledgemapper/UI/MainWidget.Generated.cs b/Sledgemapper/UI/MainWidget.Generated.cs index 321f7d2..50223dd 100644 --- a/Sledgemapper/UI/MainWidget.Generated.cs +++ b/Sledgemapper/UI/MainWidget.Generated.cs @@ -1,9 +1,10 @@ -/* Generated by MyraPad at 04/02/2021 10:36:48 */ +/* Generated by MyraPad at 20/09/2021 14:15:54 */ using Myra; using Myra.Graphics2D; using Myra.Graphics2D.TextureAtlases; using Myra.Graphics2D.UI; using Myra.Graphics2D.Brushes; +using Myra.Graphics2D.UI.Properties; #if MONOGAME || FNA using Microsoft.Xna.Framework; @@ -60,17 +61,43 @@ namespace Sledgemapper.UI MenuConnectLogin.ShortcutText = "Ctrl+O"; MenuConnectLogin.Id = "MenuConnectLogin"; + var menuItem1 = new MenuItem(); + menuItem1.Text = "&Connect"; + menuItem1.Items.Add(MenuConnectLogin); + + MenuCampaingNew = new MenuItem(); + MenuCampaingNew.Text = "&New"; + MenuCampaingNew.ShortcutText = "Ctrl+N"; + MenuCampaingNew.Id = "MenuCampaingNew"; + + MenuCampaignOpen = new MenuItem(); + MenuCampaignOpen.Text = "&Open"; + MenuCampaignOpen.ShortcutText = "Ctrl+O"; + MenuCampaignOpen.Id = "MenuCampaignOpen"; + var menuSeparator3 = new MenuSeparator(); - MenuConnectNew = new MenuItem(); - MenuConnectNew.Text = "&New"; - MenuConnectNew.ShortcutText = "Ctrl+N"; - MenuConnectNew.Id = "MenuConnectNew"; + MenuCampaignPlayers = new MenuItem(); + MenuCampaignPlayers.Text = "&Players"; + MenuCampaignPlayers.ShortcutText = "CtrI+P"; + MenuCampaignPlayers.Id = "MenuCampaignPlayers"; - MenuConnectJoin = new MenuItem(); - MenuConnectJoin.Text = "&Join"; - MenuConnectJoin.ShortcutText = "Ctrl+J"; - MenuConnectJoin.Id = "MenuConnectJoin"; + var menuItem2 = new MenuItem(); + menuItem2.Text = "C&aign"; + menuItem2.Items.Add(MenuCampaingNew); + menuItem2.Items.Add(MenuCampaignOpen); + menuItem2.Items.Add(menuSeparator3); + menuItem2.Items.Add(MenuCampaignPlayers); + + MenuMapNew = new MenuItem(); + MenuMapNew.Text = "&New"; + MenuMapNew.ShortcutText = "Ctrl+N"; + MenuMapNew.Id = "MenuMapNew"; + + MenuMapOpen = new MenuItem(); + MenuMapOpen.Text = "&Open"; + MenuMapOpen.ShortcutText = "Ctrl+O"; + MenuMapOpen.Id = "MenuMapOpen"; MenuConnectSync = new MenuItem(); MenuConnectSync.Text = "S&ync"; @@ -82,14 +109,13 @@ namespace Sledgemapper.UI MenuConnectUpload.ShortcutText = "Ctrl+U"; MenuConnectUpload.Id = "MenuConnectUpload"; - var menuItem1 = new MenuItem(); - menuItem1.Text = "&Connect"; - menuItem1.Items.Add(MenuConnectLogin); - menuItem1.Items.Add(menuSeparator3); - menuItem1.Items.Add(MenuConnectNew); - menuItem1.Items.Add(MenuConnectJoin); - menuItem1.Items.Add(MenuConnectSync); - menuItem1.Items.Add(MenuConnectUpload); + var menuItem3 = new MenuItem(); + menuItem3.Text = "&Map"; + menuItem3.ShortcutText = "Ctrl+M"; + menuItem3.Items.Add(MenuMapNew); + menuItem3.Items.Add(MenuMapOpen); + menuItem3.Items.Add(MenuConnectSync); + menuItem3.Items.Add(MenuConnectUpload); MenuViewShowNotes = new MenuItem(); MenuViewShowNotes.Text = "N&otes"; @@ -106,19 +132,19 @@ namespace Sledgemapper.UI MenuViewCenterOnSelection.ShortcutText = "Ctrl+E"; MenuViewCenterOnSelection.Id = "MenuViewCenterOnSelection"; - var menuItem2 = new MenuItem(); - menuItem2.Text = "&View"; - menuItem2.Items.Add(MenuViewShowNotes); - menuItem2.Items.Add(MenuViewShowCellNUmbers); - menuItem2.Items.Add(MenuViewCenterOnSelection); + var menuItem4 = new MenuItem(); + menuItem4.Text = "&View"; + menuItem4.Items.Add(MenuViewShowNotes); + menuItem4.Items.Add(MenuViewShowCellNUmbers); + menuItem4.Items.Add(MenuViewCenterOnSelection); MenuHelpAbout = new MenuItem(); MenuHelpAbout.Text = "&About"; MenuHelpAbout.Id = "MenuHelpAbout"; - var menuItem3 = new MenuItem(); - menuItem3.Text = "&Help"; - menuItem3.Items.Add(MenuHelpAbout); + var menuItem5 = new MenuItem(); + menuItem5.Text = "&Help"; + menuItem5.Items.Add(MenuHelpAbout); _mainMenu = new HorizontalMenu(); _mainMenu.Id = "_mainMenu"; @@ -126,6 +152,8 @@ namespace Sledgemapper.UI _mainMenu.Items.Add(menuItem1); _mainMenu.Items.Add(menuItem2); _mainMenu.Items.Add(menuItem3); + _mainMenu.Items.Add(menuItem4); + _mainMenu.Items.Add(menuItem5); BtnToolbarLine = new ImageTextButton(); BtnToolbarLine.Text = " C"; @@ -211,8 +239,9 @@ namespace Sledgemapper.UI ScrOverlay.Content = GridOverlays; TxtOverlaySearch = new TextBox(); - TxtOverlaySearch.Height = 40; - TxtOverlaySearch.Margin = new Thickness(0, 4); + TxtOverlaySearch.Height = 25; + TxtOverlaySearch.BorderThickness = new Thickness(1); + TxtOverlaySearch.Border = new SolidBrush("#000000FF"); TxtOverlaySearch.Id = "TxtOverlaySearch"; var verticalStackPanel2 = new VerticalStackPanel(); @@ -230,32 +259,42 @@ namespace Sledgemapper.UI verticalSplitPane1.Widgets.Add(verticalStackPanel2); var label1 = new Label(); - label1.Text = "Connection status:"; + label1.Text = "Connection:"; lblConnectionStatus = new Label(); lblConnectionStatus.Text = "Disconnected"; - lblConnectionStatus.MinWidth = 100; + lblConnectionStatus.MinWidth = 50; lblConnectionStatus.Id = "lblConnectionStatus"; var verticalSeparator1 = new VerticalSeparator(); var label2 = new Label(); - label2.Text = "Username:"; + label2.Text = "Initials:"; lblUsername = new Label(); lblUsername.Text = "n/a"; - lblUsername.MinWidth = 100; + lblUsername.MinWidth = 50; lblUsername.Id = "lblUsername"; var verticalSeparator2 = new VerticalSeparator(); var label3 = new Label(); - label3.Text = "Session name:"; + label3.Text = "Campaign:"; - lblSessionName = new Label(); - lblSessionName.Text = "n/a"; - lblSessionName.MinWidth = 100; - lblSessionName.Id = "lblSessionName"; + lblCampaign = new Label(); + lblCampaign.Text = "n/a"; + lblCampaign.MinWidth = 50; + lblCampaign.Id = "lblCampaign"; + + var verticalSeparator3 = new VerticalSeparator(); + + var label4 = new Label(); + label4.Text = "Map:"; + + lblMap = new Label(); + lblMap.Text = "n/a"; + lblMap.MinWidth = 50; + lblMap.Id = "lblMap"; var horizontalStackPanel1 = new HorizontalStackPanel(); horizontalStackPanel1.Spacing = 10; @@ -272,7 +311,10 @@ namespace Sledgemapper.UI horizontalStackPanel1.Widgets.Add(lblUsername); horizontalStackPanel1.Widgets.Add(verticalSeparator2); horizontalStackPanel1.Widgets.Add(label3); - horizontalStackPanel1.Widgets.Add(lblSessionName); + horizontalStackPanel1.Widgets.Add(lblCampaign); + horizontalStackPanel1.Widgets.Add(verticalSeparator3); + horizontalStackPanel1.Widgets.Add(label4); + horizontalStackPanel1.Widgets.Add(lblMap); Proportions.Add(new Proportion @@ -300,8 +342,11 @@ namespace Sledgemapper.UI public MenuItem MenuFileQuit; public MenuItem MenuFile; public MenuItem MenuConnectLogin; - public MenuItem MenuConnectNew; - public MenuItem MenuConnectJoin; + public MenuItem MenuCampaingNew; + public MenuItem MenuCampaignOpen; + public MenuItem MenuCampaignPlayers; + public MenuItem MenuMapNew; + public MenuItem MenuMapOpen; public MenuItem MenuConnectSync; public MenuItem MenuConnectUpload; public MenuItem MenuViewShowNotes; @@ -319,6 +364,7 @@ namespace Sledgemapper.UI public TextBox TxtOverlaySearch; public Label lblConnectionStatus; public Label lblUsername; - public Label lblSessionName; + public Label lblCampaign; + public Label lblMap; } } diff --git a/Sledgemapper/UI/mainwidget.xml.xmmp b/Sledgemapper/UI/MainWidget.xmmp similarity index 77% rename from Sledgemapper/UI/mainwidget.xml.xmmp rename to Sledgemapper/UI/MainWidget.xmmp index aca05ef..cc322cc 100644 --- a/Sledgemapper/UI/mainwidget.xml.xmmp +++ b/Sledgemapper/UI/MainWidget.xmmp @@ -1,5 +1,5 @@ - + @@ -17,9 +17,16 @@ + + + + - - + + + + + @@ -62,21 +69,24 @@ - + - \ No newline at end of file diff --git a/Sledgemapper/UI/MapList.Custom.cs b/Sledgemapper/UI/MapList.Custom.cs new file mode 100644 index 0000000..e779da8 --- /dev/null +++ b/Sledgemapper/UI/MapList.Custom.cs @@ -0,0 +1,85 @@ +/* Generated by MyraPad at 03/09/2021 17:13:57 */ +using Myra.Graphics2D.Brushes; +using Myra.Graphics2D.UI; +using Sledgemapper.Messages; +using System; +using System.Threading.Tasks; +using TinyMessenger; + +namespace Sledgemapper.UI +{ + public partial class MapList + { + private CommunicationManager CommunicationManager { get; } + private TinyMessengerHub Messenger { get; } + + private string _selectedMap; + private Guid _selectedMapId; + public MapList(CommunicationManager communicationManager, TinyMessengerHub messenger) + { + CommunicationManager = communicationManager; + Messenger = messenger; + + BuildUI(); + BtnNewCampaign.Click += (s, e) => + { + OnMenuMapNew(s, e); + this.GetContainingWindow().Close(); + }; + + BtnLoadCampaign.Click += BtnLoadCampaign_Click; + } + + private void BtnLoadCampaign_Click(object sender, EventArgs e) + { + if (!string.IsNullOrWhiteSpace(_selectedMap) && _selectedMapId!=Guid.Empty) + { + State.Instance.MapName = _selectedMap; + State.Instance.MapId = _selectedMapId; + Messenger.Publish(new MapOpenedMessage(this, _selectedMap, _selectedMapId)); + this.GetContainingWindow().Close(); + } + } + + public async Task LoadMaps() + { + var campaigns = await CommunicationManager.GetMaps(State.Instance.CampaignId); + if (campaigns is null) + { + return false; + } + + foreach (var campaign in campaigns) + { + var item = new ListItem(); + item.ItemName.Text = campaign.SessionName; + item.Tag = campaign.SessionId; + item.TouchUp += OnMapSelected; + StackCampaignsList.AddChild(item); + } + + return true; + } + + private void OnMapSelected(object sender, EventArgs e) + { + var item = sender as ListItem; + var localContent = item.GetParentContentInWindow(); + + var list = item.Parent as Grid; + for (var i = 0; i < list.ChildrenCount; i++) + { + var currentItem = list.GetChild(i) as HorizontalStackPanel;// UI.ListItem; + currentItem.Background = new SolidBrush("#D9D9D9FF"); + } + item.Background = new SolidBrush(Settings.Instance.OverlayTintColor); + _selectedMap = item.ItemName.Text; + _selectedMapId = (Guid)item.Tag; + } + + private void OnMenuMapNew(object sender, EventArgs e) + { + new MapWindow(CommunicationManager, Messenger).ShowInModalWindow(Desktop, "New map"); + } + } +} \ No newline at end of file diff --git a/Sledgemapper/UI/MapList.Custom.xmmp b/Sledgemapper/UI/MapList.Custom.xmmp new file mode 100644 index 0000000..1e6fef5 --- /dev/null +++ b/Sledgemapper/UI/MapList.Custom.xmmp @@ -0,0 +1,16 @@ + + + + + \ No newline at end of file diff --git a/Sledgemapper/UI/MapList.Generated.cs b/Sledgemapper/UI/MapList.Generated.cs new file mode 100644 index 0000000..d2d02b8 --- /dev/null +++ b/Sledgemapper/UI/MapList.Generated.cs @@ -0,0 +1,86 @@ +/* Generated by MyraPad at 03/09/2021 17:16:12 */ +using Myra; +using Myra.Graphics2D; +using Myra.Graphics2D.TextureAtlases; +using Myra.Graphics2D.UI; +using Myra.Graphics2D.Brushes; +using Myra.Graphics2D.UI.Properties; + +#if MONOGAME || FNA +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +#elif STRIDE +using Stride.Core.Mathematics; +#else +using System.Drawing; +using System.Numerics; +#endif + +namespace Sledgemapper.UI +{ + partial class MapList: VerticalStackPanel + { + private void BuildUI() + { + var label1 = new Label(); + label1.Text = "Maps"; + label1.HorizontalAlignment = Myra.Graphics2D.UI.HorizontalAlignment.Center; + + StackCampaignsList = new VerticalStackPanel(); + StackCampaignsList.DefaultProportion = new Proportion + { + Type = Myra.Graphics2D.UI.ProportionType.Auto, + }; + StackCampaignsList.Id = "StackCampaignsList"; + + var scrollViewer1 = new ScrollViewer(); + scrollViewer1.Height = 250; + scrollViewer1.Content = StackCampaignsList; + + BtnNewCampaign = new TextButton(); + BtnNewCampaign.Text = "New"; + BtnNewCampaign.Width = 70; + BtnNewCampaign.Height = 20; + BtnNewCampaign.Padding = new Thickness(5); + BtnNewCampaign.HorizontalAlignment = Myra.Graphics2D.UI.HorizontalAlignment.Center; + BtnNewCampaign.Id = "BtnNewCampaign"; + + BtnLoadCampaign = new TextButton(); + BtnLoadCampaign.Text = "Load"; + BtnLoadCampaign.Width = 70; + BtnLoadCampaign.Height = 20; + BtnLoadCampaign.Padding = new Thickness(5); + BtnLoadCampaign.HorizontalAlignment = Myra.Graphics2D.UI.HorizontalAlignment.Center; + BtnLoadCampaign.Id = "BtnLoadCampaign"; + + BtnCancelCampaign = new TextButton(); + BtnCancelCampaign.Text = "Cancel"; + BtnCancelCampaign.Width = 70; + BtnCancelCampaign.Height = 20; + BtnCancelCampaign.Padding = new Thickness(5); + BtnCancelCampaign.HorizontalAlignment = Myra.Graphics2D.UI.HorizontalAlignment.Center; + BtnCancelCampaign.Id = "BtnCancelCampaign"; + + var horizontalStackPanel1 = new HorizontalStackPanel(); + horizontalStackPanel1.Spacing = 15; + horizontalStackPanel1.HorizontalAlignment = Myra.Graphics2D.UI.HorizontalAlignment.Right; + horizontalStackPanel1.Widgets.Add(BtnNewCampaign); + horizontalStackPanel1.Widgets.Add(BtnLoadCampaign); + horizontalStackPanel1.Widgets.Add(BtnCancelCampaign); + + + Spacing = 13; + Width = 400; + Padding = new Thickness(10); + Widgets.Add(label1); + Widgets.Add(scrollViewer1); + Widgets.Add(horizontalStackPanel1); + } + + + public VerticalStackPanel StackCampaignsList; + public TextButton BtnNewCampaign; + public TextButton BtnLoadCampaign; + public TextButton BtnCancelCampaign; + } +} diff --git a/Sledgemapper/UI/MapList.cs b/Sledgemapper/UI/MapList.cs new file mode 100644 index 0000000..85108ee --- /dev/null +++ b/Sledgemapper/UI/MapList.cs @@ -0,0 +1,11 @@ +/* Generated by MyraPad at 03/09/2021 17:13:57 */ +namespace Sledgemapper.UI +{ + public partial class MapList + { + public MapList() + { + BuildUI(); + } + } +} \ No newline at end of file diff --git a/Sledgemapper/UI/MapList.xmmp b/Sledgemapper/UI/MapList.xmmp new file mode 100644 index 0000000..1e6fef5 --- /dev/null +++ b/Sledgemapper/UI/MapList.xmmp @@ -0,0 +1,16 @@ + + + + + \ No newline at end of file diff --git a/Sledgemapper/UI/MapWindow.Custom.cs b/Sledgemapper/UI/MapWindow.Custom.cs new file mode 100644 index 0000000..dbfe340 --- /dev/null +++ b/Sledgemapper/UI/MapWindow.Custom.cs @@ -0,0 +1,66 @@ +/* Generated by MyraPad at 02/09/2021 16:26:04 */ +using Microsoft.AspNetCore.SignalR.Client; +using Myra.Graphics2D.UI; +using Sentry; +using Sledgemapper.Messages; +using System; +using TinyMessenger; + +namespace Sledgemapper.UI +{ + public partial class MapWindow + { + public CommunicationManager CommunicationManager { get; } + public TinyMessengerHub Messenger { get; } + + public MapWindow(CommunicationManager communicationManager, TinyMessengerHub messenger) + { + CommunicationManager= communicationManager; + Messenger = messenger; + BuildUI(); + BtnNewCampaign.Click += OnButtonNewMapClicked; + } + + private async void OnButtonNewMapClicked(object sender, EventArgs e) + { + Container container = ((TextButton)sender).Parent; + while (!(container is Window)) + { + container = container.Parent; + } + + var localContent = ((TextButton)sender).GetParentContentInWindow();// localWindow.Content as PlayerWindow; + + var isValid = localContent.Content.TxtCampaign.ValidateTextbox(); + if (!isValid) + { + return; + } + + if (CommunicationManager.Connection.State != HubConnectionState.Connected) + { + Messenger.Publish(new SignalrConnectionUpdateMessage(this)); + } + + var successful = false; + Guid sessionGuid = Guid.Empty; + try + { + sessionGuid = await CommunicationManager.Api.NewSession(State.Instance.CampaignId, localContent.Content.TxtCampaign.Text); + + successful = sessionGuid != Guid.Empty; + + } + catch (Exception ex) + { + SentrySdk.CaptureException(ex); + } + + if (successful) + { + Messenger.Publish(new MapOpenedMessage(this, localContent.Content.TxtCampaign.Text, sessionGuid)); + localContent.Window.Close(); + } + } + } +} \ No newline at end of file diff --git a/Sledgemapper/UI/SessionWindow.Generated.cs b/Sledgemapper/UI/MapWindow.Generated.cs similarity index 55% rename from Sledgemapper/UI/SessionWindow.Generated.cs rename to Sledgemapper/UI/MapWindow.Generated.cs index a0c4cef..c6ba8d0 100644 --- a/Sledgemapper/UI/SessionWindow.Generated.cs +++ b/Sledgemapper/UI/MapWindow.Generated.cs @@ -1,28 +1,33 @@ -/* Generated by MyraPad at 10/11/2020 10:59:36 */ +/* Generated by MyraPad at 02/09/2021 16:26:04 */ +using Myra; using Myra.Graphics2D; using Myra.Graphics2D.TextureAtlases; using Myra.Graphics2D.UI; using Myra.Graphics2D.Brushes; +using Myra.Graphics2D.UI.Properties; -#if !STRIDE +#if MONOGAME || FNA using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; -#else +#elif STRIDE using Stride.Core.Mathematics; +#else +using System.Drawing; +using System.Numerics; #endif namespace Sledgemapper.UI { - partial class SessionWindow: VerticalStackPanel + partial class MapWindow: VerticalStackPanel { private void BuildUI() { var label1 = new Label(); - label1.Text = "Session"; + label1.Text = "Map"; - TxtSession = new TextBox(); - TxtSession.GridColumn = 1; - TxtSession.Id = "TxtSession"; + TxtCampaign = new TextBox(); + TxtCampaign.GridColumn = 1; + TxtCampaign.Id = "TxtCampaign"; var grid1 = new Grid(); grid1.ColumnSpacing = 25; @@ -37,13 +42,13 @@ namespace Sledgemapper.UI Type = Myra.Graphics2D.UI.ProportionType.Fill, }); grid1.Widgets.Add(label1); - grid1.Widgets.Add(TxtSession); + grid1.Widgets.Add(TxtCampaign); - BtnLogin = new TextButton(); - BtnLogin.Text = "Join"; - BtnLogin.Padding = new Thickness(10, 5); - BtnLogin.HorizontalAlignment = Myra.Graphics2D.UI.HorizontalAlignment.Center; - BtnLogin.Id = "BtnLogin"; + BtnNewCampaign = new TextButton(); + BtnNewCampaign.Text = "New"; + BtnNewCampaign.Padding = new Thickness(10, 5); + BtnNewCampaign.HorizontalAlignment = Myra.Graphics2D.UI.HorizontalAlignment.Center; + BtnNewCampaign.Id = "BtnNewCampaign"; Spacing = 16; @@ -52,11 +57,11 @@ namespace Sledgemapper.UI Width = 300; Padding = new Thickness(10); Widgets.Add(grid1); - Widgets.Add(BtnLogin); + Widgets.Add(BtnNewCampaign); } - public TextBox TxtSession; - public TextButton BtnLogin; + public TextBox TxtCampaign; + public TextButton BtnNewCampaign; } -} \ No newline at end of file +} diff --git a/Sledgemapper/UI/MapWindow.cs b/Sledgemapper/UI/MapWindow.cs new file mode 100644 index 0000000..e94fa07 --- /dev/null +++ b/Sledgemapper/UI/MapWindow.cs @@ -0,0 +1,15 @@ +/* Generated by MyraPad at 02/09/2021 16:26:04 */ + +namespace Sledgemapper.UI +{ + public partial class MapWindow + { + public MapWindow() + { + BuildUI(); + + } + + + } +} \ No newline at end of file diff --git a/Sledgemapper/UI/NoteList.Custom.cs b/Sledgemapper/UI/NoteList.Custom.cs new file mode 100644 index 0000000..2905ea3 --- /dev/null +++ b/Sledgemapper/UI/NoteList.Custom.cs @@ -0,0 +1,43 @@ +/* Generated by MyraPad at 01/12/2020 11:46:54 */ +using System.Linq; +using Myra.Graphics2D.TextureAtlases; +using Sledgemapper.Messages; +using Sledgemapper.Shared.Entities; +using TinyMessenger; + +namespace Sledgemapper.UI +{ + public partial class NoteList + { + private readonly CommunicationManager CommunicationManager; + private readonly TinyMessengerHub Messenger; + + public NoteList(CommunicationManager communicationManager, TinyMessengerHub messenger) + { + BuildUI(); + CommunicationManager = communicationManager; + Messenger = messenger; + for (var i = 0; i < CommunicationManager.SessionData.Notes.Values.Count; i++) + { + var note = CommunicationManager.SessionData.Notes.Values.ElementAt(i); + var item = new NoteListItem(); + item.LblNoteText.Text = $"{note} - {note.Text}"; + item.BtnNoteCenter.Image = new TextureRegion(CachedContent.Instance.Location); + item.BtnNoteView.Image = new TextureRegion(CachedContent.Instance.Eye); + item.BtnNoteCenter.Click += (s, e) => + { + Messenger.Publish(new CenterOnTileMessage(this) { X = note.X, Y = note.Y }); + }; + + item.BtnNoteView.Click += (s, e) => { EditNote(note); this.GetContainingWindow().Close(); }; + StackNotesList.AddChild(item); + } + } + + private void EditNote(Note note) + { + State.Instance.SelectedNote = new Note { X = note.X, Y = note.Y, Text = note.Text }; + new NoteWindow(CommunicationManager, note).ShowInModalWindow(Desktop, $" Note on {note.X}:{note.Y}"); + } + } +} \ No newline at end of file diff --git a/Sledgemapper/UI/NoteListItem.Custom.cs b/Sledgemapper/UI/NoteListItem.Custom.cs new file mode 100644 index 0000000..39fe8ff --- /dev/null +++ b/Sledgemapper/UI/NoteListItem.Custom.cs @@ -0,0 +1,8 @@ +/* Generated by MyraPad at 01/12/2020 14:29:43 */ +namespace Sledgemapper.UI +{ + public partial class NoteListItem + { + + } +} \ No newline at end of file diff --git a/Sledgemapper/UI/NoteWindow.Custom.cs b/Sledgemapper/UI/NoteWindow.Custom.cs new file mode 100644 index 0000000..78b31e8 --- /dev/null +++ b/Sledgemapper/UI/NoteWindow.Custom.cs @@ -0,0 +1,44 @@ +/* Generated by MyraPad at 29/11/2020 23:50:42 */ +using System; +using Myra.Graphics2D.UI; +using Sledgemapper.Shared.Entities; + +namespace Sledgemapper.UI +{ + public partial class NoteWindow + { + private readonly CommunicationManager CommunicationManager; + private readonly Note Note; + + public NoteWindow(CommunicationManager communicationManager, Note note) + { + BuildUI(); + NoteText.Text = note.Text; + Note = note; + CommunicationManager = communicationManager; + BtnOk.Click += OnButtonNoteOkClick; + BtnCancel.Click += OnButtonNoteCancelClick; + } + + private void OnButtonNoteOkClick(object sender, EventArgs e) + { + var button = ((TextButton)sender); + var localContent = button.GetParentContentInWindow(); + var note = new Note + { + X = State.Instance.SelectedNote.X, + Y = State.Instance.SelectedNote.Y, + Text = localContent.Content.NoteText.Text + }; + CommunicationManager.SessionData.NewNote(note); + localContent.Window.Close(); + } + + private void OnButtonNoteCancelClick(object sender, EventArgs e) + { + var button = ((TextButton)sender); + var content = button.GetParentContentInWindow(); + content.Window.Close(); + } + } +} \ No newline at end of file diff --git a/Sledgemapper/UI/PlayerList.Custom.cs b/Sledgemapper/UI/PlayerList.Custom.cs new file mode 100644 index 0000000..8fcdfd5 --- /dev/null +++ b/Sledgemapper/UI/PlayerList.Custom.cs @@ -0,0 +1,49 @@ +/* Generated by MyraPad at 28/08/2021 19:49:08 */ + +using System.Threading.Tasks; +using TinyMessenger; + +namespace Sledgemapper.UI +{ + public partial class PlayerList + { + protected CommunicationManager CommunicationManager { get; } + protected TinyMessengerHub Messenger { get; } + + public PlayerList(CommunicationManager communicationManager, TinyMessenger.TinyMessengerHub messenger) + { + CommunicationManager = communicationManager; + Messenger = messenger; + + BuildUI(); + CommunicationManager = communicationManager; + BtnInvitePlayer.Click += (s, e) => + { + ShowAddPLayerWindow(); + this.GetContainingWindow().Close(); + }; + } + + public async Task LoadPlayers() + { + var players = await CommunicationManager.GetPlayers(State.Instance.CampaignId); + if (players is null) + { + return false; + } + foreach (var player in players) + { + var item = new ListItem(); + item.ItemName.Text = player.UserName; + StackCampaignsList.AddChild(item); + } + + return true; + } + + private void ShowAddPLayerWindow() + { + new PlayerWindow(CommunicationManager, Messenger).ShowInModalWindow(Desktop, "Invite player"); + } + } +} \ No newline at end of file diff --git a/Sledgemapper/UI/PlayerList.Generated.cs b/Sledgemapper/UI/PlayerList.Generated.cs new file mode 100644 index 0000000..af21ecd --- /dev/null +++ b/Sledgemapper/UI/PlayerList.Generated.cs @@ -0,0 +1,73 @@ +/* Generated by MyraPad at 16/09/2021 12:29:41 */ +using Myra; +using Myra.Graphics2D; +using Myra.Graphics2D.TextureAtlases; +using Myra.Graphics2D.UI; +using Myra.Graphics2D.Brushes; +using Myra.Graphics2D.UI.Properties; + +#if MONOGAME || FNA +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +#elif STRIDE +using Stride.Core.Mathematics; +#else +using System.Drawing; +using System.Numerics; +#endif + +namespace Sledgemapper.UI +{ + partial class PlayerList: VerticalStackPanel + { + private void BuildUI() + { + var label1 = new Label(); + label1.Text = "Players"; + label1.HorizontalAlignment = Myra.Graphics2D.UI.HorizontalAlignment.Center; + + StackCampaignsList = new VerticalStackPanel(); + StackCampaignsList.MinHeight = 350; + StackCampaignsList.MaxHeight = 350; + StackCampaignsList.Id = "StackCampaignsList"; + + var scrollViewer1 = new ScrollViewer(); + scrollViewer1.Content = StackCampaignsList; + + BtnInvitePlayer = new TextButton(); + BtnInvitePlayer.Text = "Invite"; + BtnInvitePlayer.Width = 70; + BtnInvitePlayer.Height = 20; + BtnInvitePlayer.Padding = new Thickness(5); + BtnInvitePlayer.HorizontalAlignment = Myra.Graphics2D.UI.HorizontalAlignment.Center; + BtnInvitePlayer.Id = "BtnInvitePlayer"; + + BtnCancelCampaign = new TextButton(); + BtnCancelCampaign.Text = "Cancel"; + BtnCancelCampaign.Width = 70; + BtnCancelCampaign.Height = 20; + BtnCancelCampaign.Padding = new Thickness(5); + BtnCancelCampaign.HorizontalAlignment = Myra.Graphics2D.UI.HorizontalAlignment.Center; + BtnCancelCampaign.Id = "BtnCancelCampaign"; + + var horizontalStackPanel1 = new HorizontalStackPanel(); + horizontalStackPanel1.Spacing = 15; + horizontalStackPanel1.HorizontalAlignment = Myra.Graphics2D.UI.HorizontalAlignment.Right; + horizontalStackPanel1.Widgets.Add(BtnInvitePlayer); + horizontalStackPanel1.Widgets.Add(BtnCancelCampaign); + + + Spacing = 13; + Width = 400; + Padding = new Thickness(10); + Widgets.Add(label1); + Widgets.Add(scrollViewer1); + Widgets.Add(horizontalStackPanel1); + } + + + public VerticalStackPanel StackCampaignsList; + public TextButton BtnInvitePlayer; + public TextButton BtnCancelCampaign; + } +} diff --git a/Sledgemapper/UI/PlayerList.cs b/Sledgemapper/UI/PlayerList.cs new file mode 100644 index 0000000..1da74ac --- /dev/null +++ b/Sledgemapper/UI/PlayerList.cs @@ -0,0 +1,11 @@ +/* Generated by MyraPad at 28/08/2021 19:49:08 */ +namespace Sledgemapper.UI +{ + public partial class PlayerList + { + public PlayerList() + { + BuildUI(); + } + } +} \ No newline at end of file diff --git a/Sledgemapper/UI/PlayerList.xmmp b/Sledgemapper/UI/PlayerList.xmmp new file mode 100644 index 0000000..61d6053 --- /dev/null +++ b/Sledgemapper/UI/PlayerList.xmmp @@ -0,0 +1,13 @@ + + + + + \ No newline at end of file diff --git a/Sledgemapper/UI/PlayerWindow.Custom.cs b/Sledgemapper/UI/PlayerWindow.Custom.cs new file mode 100644 index 0000000..a81a12d --- /dev/null +++ b/Sledgemapper/UI/PlayerWindow.Custom.cs @@ -0,0 +1,47 @@ +/* Generated by MyraPad at 28/08/2021 22:04:11 */ +using Myra.Graphics2D.UI; +using Sentry; +using Sledgemapper.Messages; +using System; +using TinyMessenger; + +namespace Sledgemapper.UI +{ + public partial class PlayerWindow + { + protected CommunicationManager CommunicationManager { get; } + protected TinyMessengerHub Messenger { get; } + + public PlayerWindow(CommunicationManager communicationManager, TinyMessenger.TinyMessengerHub messenger) + { + CommunicationManager = communicationManager; + Messenger = messenger; + + BuildUI(); + BtnNewCampaign.Click += OnButtonInvitePlayerClicked; + } + + private async void OnButtonInvitePlayerClicked(object sender, EventArgs e) + { + var localContent = ((TextButton)sender).GetParentContentInWindow();// localWindow.Content as PlayerWindow; + var isValid = localContent.Content.TxtCampaign.ValidateTextbox(); + if (!isValid) + { + return; + } + + var successful = false; + try + { + await CommunicationManager.Api.InvitePlayer(State.Instance.CampaignId, localContent.Content.TxtCampaign.Text); + } + catch (Exception ex) + { + Messenger.Publish(new ErrorMessage(this, "Error inviting player")); + SentrySdk.CaptureException(ex); + + } + this.GetContainingWindow().Close(); + } + } +} \ No newline at end of file diff --git a/Sledgemapper/UI/PlayerWindow.Generated.cs b/Sledgemapper/UI/PlayerWindow.Generated.cs new file mode 100644 index 0000000..509d0b8 --- /dev/null +++ b/Sledgemapper/UI/PlayerWindow.Generated.cs @@ -0,0 +1,67 @@ +/* Generated by MyraPad at 28/08/2021 22:04:37 */ +using Myra; +using Myra.Graphics2D; +using Myra.Graphics2D.TextureAtlases; +using Myra.Graphics2D.UI; +using Myra.Graphics2D.Brushes; +using Myra.Graphics2D.UI.Properties; + +#if MONOGAME || FNA +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +#elif STRIDE +using Stride.Core.Mathematics; +#else +using System.Drawing; +using System.Numerics; +#endif + +namespace Sledgemapper.UI +{ + partial class PlayerWindow: VerticalStackPanel + { + private void BuildUI() + { + var label1 = new Label(); + label1.Text = "Email"; + + TxtCampaign = new TextBox(); + TxtCampaign.GridColumn = 1; + TxtCampaign.Id = "TxtCampaign"; + + var grid1 = new Grid(); + grid1.ColumnSpacing = 25; + grid1.RowSpacing = 10; + grid1.ColumnsProportions.Add(new Proportion + { + Type = Myra.Graphics2D.UI.ProportionType.Pixels, + Value = 60, + }); + grid1.ColumnsProportions.Add(new Proportion + { + Type = Myra.Graphics2D.UI.ProportionType.Fill, + }); + grid1.Widgets.Add(label1); + grid1.Widgets.Add(TxtCampaign); + + BtnNewCampaign = new TextButton(); + BtnNewCampaign.Text = "Invite"; + BtnNewCampaign.Padding = new Thickness(10, 5); + BtnNewCampaign.HorizontalAlignment = Myra.Graphics2D.UI.HorizontalAlignment.Center; + BtnNewCampaign.Id = "BtnNewCampaign"; + + + Spacing = 16; + HorizontalAlignment = Myra.Graphics2D.UI.HorizontalAlignment.Center; + VerticalAlignment = Myra.Graphics2D.UI.VerticalAlignment.Center; + Width = 300; + Padding = new Thickness(10); + Widgets.Add(grid1); + Widgets.Add(BtnNewCampaign); + } + + + public TextBox TxtCampaign; + public TextButton BtnNewCampaign; + } +} diff --git a/Sledgemapper/UI/PlayerWindow.cs b/Sledgemapper/UI/PlayerWindow.cs new file mode 100644 index 0000000..1d5b6a9 --- /dev/null +++ b/Sledgemapper/UI/PlayerWindow.cs @@ -0,0 +1,12 @@ +/* Generated by MyraPad at 28/08/2021 22:04:11 */ +namespace Sledgemapper.UI +{ + public partial class PlayerWindow + { + + public PlayerWindow() + { + BuildUI(); + } + } +} \ No newline at end of file diff --git a/Sledgemapper/UI/PlayerWindow.xmmp b/Sledgemapper/UI/PlayerWindow.xmmp new file mode 100644 index 0000000..6344929 --- /dev/null +++ b/Sledgemapper/UI/PlayerWindow.xmmp @@ -0,0 +1,14 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/Sledgemapper/UI/SessionWindow.cs b/Sledgemapper/UI/SessionWindow.cs deleted file mode 100644 index 3c7a99a..0000000 --- a/Sledgemapper/UI/SessionWindow.cs +++ /dev/null @@ -1,11 +0,0 @@ -/* Generated by MyraPad at 10/11/2020 10:59:36 */ -namespace Sledgemapper.UI -{ - public partial class SessionWindow - { - public SessionWindow() - { - BuildUI(); - } - } -} \ No newline at end of file diff --git a/Sledgemapper/UI/sessionwindow.xml b/Sledgemapper/UI/campaignWindow.xmmp similarity index 65% rename from Sledgemapper/UI/sessionwindow.xml rename to Sledgemapper/UI/campaignWindow.xmmp index bbfd98a..a54c870 100644 --- a/Sledgemapper/UI/sessionwindow.xml +++ b/Sledgemapper/UI/campaignWindow.xmmp @@ -1,5 +1,5 @@ - + @@ -7,11 +7,11 @@ - - + \ No newline at end of file diff --git a/Sledgemapper/UI/listItem.xmmp b/Sledgemapper/UI/listItem.xmmp new file mode 100644 index 0000000..3d2aed1 --- /dev/null +++ b/Sledgemapper/UI/listItem.xmmp @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/Sledgemapper/UI/mainwidget.xml b/Sledgemapper/UI/mainwidget.xml deleted file mode 100644 index 53e84c3..0000000 --- a/Sledgemapper/UI/mainwidget.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Sledgemapper/UI/mapWindow.xmmp b/Sledgemapper/UI/mapWindow.xmmp new file mode 100644 index 0000000..f656c90 --- /dev/null +++ b/Sledgemapper/UI/mapWindow.xmmp @@ -0,0 +1,14 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/Sledgemapper/UI/noteList.xml b/Sledgemapper/UI/noteList.xmmp similarity index 100% rename from Sledgemapper/UI/noteList.xml rename to Sledgemapper/UI/noteList.xmmp diff --git a/Sledgemapper/UI/noteListItem.xml b/Sledgemapper/UI/noteListItem.xmmp similarity index 100% rename from Sledgemapper/UI/noteListItem.xml rename to Sledgemapper/UI/noteListItem.xmmp diff --git a/Sledgemapper/UI/noteWindow.xml b/Sledgemapper/UI/noteWindow.xmmp similarity index 100% rename from Sledgemapper/UI/noteWindow.xml rename to Sledgemapper/UI/noteWindow.xmmp diff --git a/Sledgemapper/appsettings.json b/Sledgemapper/appsettings.json new file mode 100644 index 0000000..544b7b4 --- /dev/null +++ b/Sledgemapper/appsettings.json @@ -0,0 +1,3 @@ +{ + +} \ No newline at end of file diff --git a/nuget.config b/nuget.config index 8f3c5fe..cd4f26c 100644 --- a/nuget.config +++ b/nuget.config @@ -1,7 +1,7 @@ - - + + \ No newline at end of file