55using Refresh . Database . Models . Photos ;
66using Refresh . Database . Query ;
77using Refresh . Database . Helpers ;
8+ using Bunkum . Core ;
89
910namespace Refresh . Database ;
1011
@@ -19,14 +20,21 @@ public partial class GameDatabaseContext // Photos
1920 . Include ( p => p . Level )
2021 . Include ( p => p . Level ! . Publisher )
2122 . Include ( p => p . Level ! . Publisher ! . Statistics )
22- . Include ( p => p . Subject1User )
23- . Include ( p => p . Subject1User ! . Statistics )
24- . Include ( p => p . Subject2User )
25- . Include ( p => p . Subject2User ! . Statistics )
26- . Include ( p => p . Subject3User )
27- . Include ( p => p . Subject3User ! . Statistics )
28- . Include ( p => p . Subject4User )
29- . Include ( p => p . Subject4User ! . Statistics ) ;
23+ . Include ( p => p . Subjects . OrderBy ( s => s . PlayerId ) ) ;
24+
25+ private IQueryable < GamePhotoSubject > GamePhotoSubjectsIncluded => this . GamePhotoSubjects
26+ . Include ( p => p . User )
27+ . Include ( p => p . User ! . Statistics )
28+ . Include ( p => p . Photo )
29+ . Include ( p => p . Photo ! . Publisher )
30+ . Include ( p => p . Photo ! . Publisher . Statistics )
31+ . Include ( p => p . Photo ! . Level )
32+ . Include ( p => p . Photo ! . Level ! . Publisher )
33+ . Include ( p => p . Photo ! . Level ! . Publisher ! . Statistics )
34+ . Include ( p => p . Photo ! . LargeAsset )
35+ . Include ( p => p . Photo ! . MediumAsset )
36+ . Include ( p => p . Photo ! . SmallAsset )
37+ . Include ( p => p . Photo ! . Subjects . OrderBy ( s => s . PlayerId ) ) ;
3038
3139 public GamePhoto UploadPhoto ( IPhotoUpload photo , IEnumerable < IPhotoUploadSubject > subjects , GameUser publisher , GameLevel ? level )
3240 {
@@ -47,29 +55,6 @@ public GamePhoto UploadPhoto(IPhotoUpload photo, IEnumerable<IPhotoUploadSubject
4755 PublishedAt = this . _time . Now ,
4856 } ;
4957
50- List < GamePhotoSubject > gameSubjects = new ( subjects . Count ( ) ) ;
51- foreach ( IPhotoUploadSubject subject in subjects )
52- {
53- GameUser ? subjectUser = null ;
54-
55- if ( ! string . IsNullOrEmpty ( subject . Username ) )
56- subjectUser = this . GetUserByUsername ( subject . Username ) ;
57-
58- float [ ] bounds = PhotoHelper . ParseBoundsList ( subject . BoundsList ) ;
59-
60- gameSubjects . Add ( new GamePhotoSubject ( subjectUser , subject . DisplayName , bounds ) ) ;
61-
62- if ( subjectUser != null )
63- {
64- this . WriteEnsuringStatistics ( subjectUser , ( ) =>
65- {
66- subjectUser . Statistics ! . PhotosWithUserCount ++ ;
67- } ) ;
68- }
69- }
70-
71- newPhoto . Subjects = gameSubjects ;
72-
7358 this . WriteEnsuringStatistics ( publisher , ( ) =>
7459 {
7560 this . GamePhotos . Add ( newPhoto ) ;
@@ -87,22 +72,124 @@ public GamePhoto UploadPhoto(IPhotoUpload photo, IEnumerable<IPhotoUploadSubject
8772 }
8873 } ) ;
8974 }
75+
76+ List < IPhotoUploadSubject > subjectsList = subjects . ToList ( ) ;
77+ List < GamePhotoSubject > finalSubjectsList = [ ] ;
78+
79+ // Take care of subjects after saving the photo itself to keep the photo, even if its subjects are malformed
80+ for ( int i = 0 ; i < subjectsList . Count ; i ++ )
81+ {
82+ IPhotoUploadSubject subject = subjectsList [ i ] ;
83+
84+ float [ ] bounds = new float [ PhotoHelper . SubjectBoundaryCount ] ;
85+ try
86+ {
87+ bounds = PhotoHelper . ParseBoundsList ( subject . BoundsList ) ;
88+ }
89+ catch ( Exception ex )
90+ {
91+ this . _logger . LogWarning ( BunkumCategory . UserPhotos , $ "Could not parse { subject . DisplayName } 's photo bounds: { ex . GetType ( ) } - { ex . Message } ") ;
92+ }
93+
94+ GameUser ? subjectUser = string . IsNullOrWhiteSpace ( subject . Username ) ? null : this . GetUserByUsername ( subject . Username ) ;
95+ finalSubjectsList . Add ( new ( )
96+ {
97+ Photo = newPhoto ,
98+ User = subjectUser ,
99+ DisplayName = subject . DisplayName ,
100+ PlayerId = i + 1 , // Player number 1 - 4
101+ Bounds = bounds
102+ } ) ;
103+
104+ if ( subjectUser != null )
105+ {
106+ this . WriteEnsuringStatistics ( subjectUser , ( ) =>
107+ {
108+ subjectUser . Statistics ! . PhotosWithUserCount ++ ;
109+ } ) ;
110+ }
111+ }
112+
113+ this . GamePhotoSubjects . AddRange ( finalSubjectsList ) ;
114+ this . SaveChanges ( ) ;
90115
91116 this . CreatePhotoUploadEvent ( publisher , newPhoto ) ;
117+
118+ newPhoto . Subjects = finalSubjectsList . ToList ( ) ;
92119 return newPhoto ;
93120 }
94121
122+ /// <remarks>
123+ /// Migration only!!
124+ /// </remarks>
125+ public void MigratePhotoSubjects ( GamePhoto photo , bool saveChanges )
126+ {
127+ List < GamePhotoSubject > subjects = [ ] ;
128+
129+ #pragma warning disable CS0618 // obsoletion
130+
131+ // If DisplayName is not null, there is a subject in that spot
132+ if ( photo . Subject1DisplayName != null )
133+ {
134+ subjects . Add ( new ( )
135+ {
136+ Photo = photo ,
137+ PlayerId = 1 ,
138+ DisplayName = photo . Subject1DisplayName ,
139+ User = photo . Subject1User ,
140+ Bounds = photo . Subject1Bounds ,
141+ } ) ;
142+ }
143+
144+ if ( photo . Subject2DisplayName != null )
145+ {
146+ subjects . Add ( new ( )
147+ {
148+ Photo = photo ,
149+ PlayerId = 2 ,
150+ DisplayName = photo . Subject2DisplayName ,
151+ User = photo . Subject2User ,
152+ Bounds = photo . Subject2Bounds ,
153+ } ) ;
154+ }
155+
156+ if ( photo . Subject3DisplayName != null )
157+ {
158+ subjects . Add ( new ( )
159+ {
160+ Photo = photo ,
161+ PlayerId = 3 ,
162+ DisplayName = photo . Subject3DisplayName ,
163+ User = photo . Subject3User ,
164+ Bounds = photo . Subject3Bounds ,
165+ } ) ;
166+ }
167+
168+ if ( photo . Subject4DisplayName != null )
169+ {
170+ subjects . Add ( new ( )
171+ {
172+ Photo = photo ,
173+ PlayerId = 4 ,
174+ DisplayName = photo . Subject4DisplayName ,
175+ User = photo . Subject4User ,
176+ Bounds = photo . Subject4Bounds ,
177+ } ) ;
178+ }
179+ #pragma warning restore CS0618
180+
181+ this . GamePhotoSubjects . AddRange ( subjects ) ;
182+ if ( saveChanges ) this . SaveChanges ( ) ;
183+ }
184+
95185 public void RemovePhoto ( GamePhoto photo )
96186 {
97- foreach ( GamePhotoSubject subject in photo . Subjects )
187+ foreach ( GameUser subjectUser in this . GetUsersInPhoto ( photo ) . ToArray ( ) )
98188 {
99- if ( subject . User != null )
189+ this . WriteEnsuringStatistics ( subjectUser , ( ) =>
100190 {
101- this . WriteEnsuringStatistics ( subject . User , ( ) =>
102- {
103- subject . User . Statistics ! . PhotosWithUserCount -- ;
104- } ) ;
105- }
191+ subjectUser . Statistics ! . PhotosWithUserCount -- ;
192+ } ) ;
106193 }
107194
108195 if ( photo . Level != null )
@@ -124,6 +211,9 @@ public void RemovePhoto(GamePhoto photo)
124211
125212 // Remove all events referencing the photo
126213 this . Events . RemoveRange ( photoEvents ) ;
214+
215+ // Remove all subjects
216+ this . GamePhotoSubjects . RemoveRange ( s => s . PhotoId == photo . PhotoId ) ;
127217
128218 // Remove the photo
129219 this . GamePhotos . Remove ( photo ) ;
@@ -132,6 +222,17 @@ public void RemovePhoto(GamePhoto photo)
132222 } ) ;
133223 }
134224
225+ public IQueryable < GamePhotoSubject > GetSubjectsInPhoto ( GamePhoto photo )
226+ => this . GamePhotoSubjectsIncluded
227+ . Where ( s => s . PhotoId == photo . PhotoId )
228+ . OrderBy ( s => s . PlayerId ) ;
229+
230+ public IQueryable < GameUser > GetUsersInPhoto ( GamePhoto photo )
231+ => this . GetSubjectsInPhoto ( photo )
232+ . Where ( s => s . User != null )
233+ . OrderBy ( s => s . PlayerId )
234+ . Select ( s => s . User ! ) ;
235+
135236 public int GetTotalPhotoCount ( ) => this . GamePhotos . Count ( ) ;
136237
137238 [ Pure ]
@@ -155,14 +256,14 @@ public int GetTotalPhotosByUser(GameUser user)
155256
156257 [ Pure ]
157258 public DatabaseList < GamePhoto > GetPhotosWithUser ( GameUser user , int count , int skip ) =>
158- new ( this . GamePhotosIncluded
159- . Where ( p => p . Subject1UserId == user . UserId || p . Subject2UserId == user . UserId || p . Subject3UserId == user . UserId || p . Subject4UserId == user . UserId )
259+ new ( this . GamePhotoSubjectsIncluded
260+ . Where ( s => s . UserId == user . UserId )
261+ . Select ( s => s . Photo )
160262 . OrderByDescending ( p => p . TakenAt ) , skip , count ) ;
161263
162264 [ Pure ]
163265 public int GetTotalPhotosWithUser ( GameUser user )
164- => this . GamePhotos
165- . Count ( p => p . Subject1UserId == user . UserId || p . Subject2UserId == user . UserId || p . Subject3UserId == user . UserId || p . Subject4UserId == user . UserId ) ;
266+ => this . GamePhotoSubjects . Count ( s => s . UserId == user . UserId ) ;
166267
167268 [ Pure ]
168269 public DatabaseList < GamePhoto > GetPhotosInLevel ( GameLevel level , int count , int skip )
0 commit comments