1
+ using System ;
1
2
using System . Collections . Generic ;
2
3
using System . Linq ;
3
4
using System . Threading . Tasks ;
@@ -10,20 +11,94 @@ namespace WDE.PacketViewer.Processing.Processors
10
11
{
11
12
public class CreatureTextDumper : PacketProcessor < bool > , ITwoStepPacketBoolProcessor , IPacketTextDumper
12
13
{
14
+ private class TextEntry : IEquatable < TextEntry >
15
+ {
16
+ public byte GroupId ;
17
+ public byte Id ;
18
+ public float Probability ;
19
+ public CreatureTextRange Range ;
20
+ public uint Duration ;
21
+ public readonly CreatureTextType Type ;
22
+ public readonly uint Language ;
23
+ public readonly uint Emote ;
24
+ public readonly uint Sound ;
25
+ public readonly string Text ;
26
+ public bool IsInSniffText { get ; set ; }
27
+ public bool IsInDatabaseText { get ; set ; }
28
+ public uint BroadcastTextId { get ; set ; }
29
+
30
+ public string ? Comment ;
31
+
32
+ public TextEntry ( string text , CreatureTextType type , uint language , uint emote , uint sound )
33
+ {
34
+ Text = text ;
35
+ Type = type ;
36
+ Language = language ;
37
+ Emote = emote ;
38
+ Sound = sound ;
39
+ Probability = 100 ;
40
+ Range = CreatureTextRange . Normal ;
41
+ IsInSniffText = true ;
42
+ IsInDatabaseText = false ;
43
+ }
44
+
45
+ public TextEntry ( ICreatureText text )
46
+ {
47
+ IsInSniffText = false ;
48
+ IsInDatabaseText = true ;
49
+ Text = text . Text ?? "" ;
50
+ Type = text . Type ;
51
+ Language = text . Language ;
52
+ Emote = text . Emote ;
53
+ Sound = text . Sound ;
54
+ GroupId = text . GroupId ;
55
+ Probability = text . Probability ;
56
+ Duration = text . Duration ;
57
+ Range = text . TextRange ;
58
+ Id = text . Id ;
59
+ BroadcastTextId = text . BroadcastTextId ;
60
+ Comment = text . Comment ;
61
+ }
62
+
63
+ public bool Equals ( TextEntry ? other )
64
+ {
65
+ if ( ReferenceEquals ( null , other ) ) return false ;
66
+ if ( ReferenceEquals ( this , other ) ) return true ;
67
+ return Type == other . Type && Language == other . Language && Emote == other . Emote && Sound == other . Sound && Text == other . Text ;
68
+ }
69
+
70
+ public override bool Equals ( object ? obj )
71
+ {
72
+ if ( ReferenceEquals ( null , obj ) ) return false ;
73
+ if ( ReferenceEquals ( this , obj ) ) return true ;
74
+ if ( obj . GetType ( ) != this . GetType ( ) ) return false ;
75
+ return Equals ( ( TextEntry ) obj ) ;
76
+ }
77
+
78
+ public override int GetHashCode ( )
79
+ {
80
+ return HashCode . Combine ( ( int ) Type , Language , Emote , Sound , Text ) ;
81
+ }
82
+ }
83
+
13
84
private class State
14
85
{
15
- public Dictionary < string , ( int groupdId , int type , int language , int emote , uint sound ) > texts = new ( ) ;
86
+ public HashSet < TextEntry > texts = new ( ) ;
16
87
}
17
88
18
89
private readonly IChatEmoteSoundProcessor chatEmoteSoundProcessor ;
19
90
private readonly IDatabaseProvider databaseProvider ;
91
+ private readonly bool asDiff ;
20
92
21
93
private readonly Dictionary < uint , State > perEntryState = new ( ) ;
22
94
23
- public CreatureTextDumper ( IChatEmoteSoundProcessor chatEmoteSoundProcessor , IDatabaseProvider databaseProvider )
95
+ public CreatureTextDumper ( IChatEmoteSoundProcessor chatEmoteSoundProcessor ,
96
+ IDatabaseProvider databaseProvider ,
97
+ bool asDiff )
24
98
{
25
99
this . chatEmoteSoundProcessor = chatEmoteSoundProcessor ;
26
100
this . databaseProvider = databaseProvider ;
101
+ this . asDiff = asDiff ;
27
102
}
28
103
29
104
private State GetState ( UniversalGuid guid )
@@ -44,20 +119,48 @@ protected override bool Process(PacketBase basePacket, PacketChat packet)
44
119
var sound = chatEmoteSoundProcessor . GetSoundForChat ( basePacket ) ;
45
120
46
121
var state = GetState ( packet . Sender ) ;
47
-
48
- if ( state . texts . ContainsKey ( packet . Text ) )
49
- return false ;
50
-
51
- state . texts [ packet . Text ] = ( state . texts . Count , packet . Type , packet . Language , emote ?? 0 , sound ?? 0 ) ;
52
- return true ;
122
+
123
+ var entry = new TextEntry ( packet . Text , ( CreatureTextType ) packet . Type , ( uint ) packet . Language , ( uint ) ( emote ?? 0 ) , sound ?? 0 )
124
+ {
125
+ GroupId = ( byte ) state . texts . Count ,
126
+ Id = 0 ,
127
+ } ;
128
+ return state . texts . Add ( entry ) ;
53
129
}
54
130
55
131
public async Task < string > Generate ( )
56
132
{
57
133
var trans = Queries . BeginTransaction ( ) ;
58
- trans . Comment ( "Warning!! This SQL will override current texts" ) ;
134
+ if ( ! asDiff )
135
+ trans . Comment ( "Warning!! This SQL will override current texts" ) ;
59
136
foreach ( var entry in perEntryState )
60
137
{
138
+ int maxId = - 1 ;
139
+ if ( asDiff )
140
+ {
141
+ var existing = await databaseProvider . GetCreatureTextsByEntry ( entry . Key ) ;
142
+ foreach ( var text in existing )
143
+ {
144
+ if ( text . Text == null )
145
+ continue ;
146
+ var databaseEntry = new TextEntry ( text ) ;
147
+ if ( entry . Value . texts . TryGetValue ( databaseEntry , out var sniffEntry ) )
148
+ {
149
+ entry . Value . texts . Remove ( sniffEntry ) ;
150
+ databaseEntry . IsInSniffText = true ;
151
+ }
152
+ entry . Value . texts . Add ( databaseEntry ) ;
153
+ maxId = Math . Max ( maxId , text . GroupId ) ;
154
+ }
155
+ }
156
+
157
+ foreach ( var sniffText in entry . Value . texts . Where ( t => t . IsInSniffText && ! t . IsInDatabaseText ) )
158
+ {
159
+ sniffText . BroadcastTextId =
160
+ ( await databaseProvider . GetBroadcastTextByTextAsync ( sniffText . Text ) ) ? . Id ?? 0 ;
161
+ sniffText . GroupId = ( byte ) ( ++ maxId ) ;
162
+ }
163
+
61
164
var template = databaseProvider . GetCreatureTemplate ( entry . Key ) ;
62
165
if ( template != null )
63
166
trans . Comment ( template . Name ) ;
@@ -66,18 +169,24 @@ public async Task<string> Generate()
66
169
. Delete ( ) ;
67
170
trans . Table ( "creature_text" )
68
171
. BulkInsert ( entry . Value . texts
172
+ . OrderBy ( t => t . GroupId )
173
+ . ThenBy ( t => t . Id )
69
174
. Select ( text => new
70
175
{
71
176
CreatureID = entry . Key ,
72
- GroupID = text . Value . groupdId ,
73
- ID = 0 ,
74
- Text = text . Key ,
75
- Type = text . Value . type ,
76
- Language = text . Value . language ,
77
- Probability = 100 ,
78
- Emote = text . Value . emote ,
79
- Sound = text . Value . sound ,
80
- BroadcastTextId = databaseProvider . GetBroadcastTextByText ( text . Key ) ? . Id ?? 0
177
+ GroupID = text . GroupId ,
178
+ ID = text . Id ,
179
+ Text = text . Text ,
180
+ Type = ( uint ) text . Type ,
181
+ Language = text . Language ,
182
+ Probability = text . Probability ,
183
+ Duration = text . Duration ,
184
+ TextRange = ( uint ) text . Range ,
185
+ Emote = text . Emote ,
186
+ Sound = text . Sound ,
187
+ BroadcastTextId = text . BroadcastTextId ,
188
+ comment = text . Comment ?? template ? . Name ?? "" ,
189
+ __comment = ! text . IsInSniffText ? "not in sniff" : null
81
190
} ) ) ;
82
191
trans . BlankLine ( ) ;
83
192
}
0 commit comments