4 \83A
\83v
\83\8a\83P
\81[
\83V
\83\87\83\93\82Ì
\83\81\83C
\83\93\83t
\83H
\81[
\83\80\81B
5 \91\97\90M
\81E
\8eó
\90M
\81E
\83{
\83g
\83\8b\94z
\91\97\8aÖ
\8cW
\82Ì
\82¢
\82ë
\82¢
\82ë
\82È
\8f\88\97\9d\82ð
\8ds
\82¤
\81B
11 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
12 Menus, StdCtrls, ComCtrls, BRegExp, BottleDef, BottleSstp,
13 DirectSstp, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
14 IdSLPP20, SsParser, ImgList, AppEvnts, TaskTray, StdActns,
15 ActnList, MPlayer, MenuBar, ToolWin,
16 IniFiles, ExtCtrls, ShellAPI, Contnrs,
17 ConstEditor, Buttons, Clipbrd, HeadValue, Logs,
18 IdException, HttpThread, IdHTTP, IdURI, LogDownload,
19 ScriptConsts, DateUtils, BottleChainRule, BottleChainEvent,
20 SakuraSeekerInstance, HEditor, HTSearch, heClasses, heFountain,
21 SakuraScriptFountain, SppTypes, SppList, SurfacePreview;
24 TSurfacePreviewType = (spHint, spEditor);
26 TfrmSender = class(TForm)
30 mnRegister: TMenuItem;
33 StatusBar: TStatusBar;
36 mnEditConst: TMenuItem;
37 ActionList: TActionList;
39 mnPopPaste: TMenuItem;
42 mnPopSelectAll: TMenuItem;
44 mnPopConst: TMenuItem;
49 mnSelectAll: TMenuItem;
51 ApplicationEvents: TApplicationEvents;
52 mnPopUpTaskTray: TPopupMenu;
53 mnTaskStart: TMenuItem;
55 mnTaskRestore: TMenuItem;
56 mnTaskNewMessage: TMenuItem;
60 mnTaskExit: TMenuItem;
68 mnPopupConst: TPopupMenu;
69 actEditConst: TAction;
71 mnShowToolBar: TMenuItem;
72 mnShowConstBar: TMenuItem;
73 ConstBarMenu: TMainMenu;
75 tbtnClear: TToolButton;
76 tbtnConfirm: TToolButton;
77 tbtnSend: TToolButton;
78 tbtnSeparator: TToolButton;
79 tbtnStart: TToolButton;
80 tbtnSeparator2: TToolButton;
81 tbtnInsertConst: TToolButton;
82 ConstMenuBar: TMenuBar;
87 actCopyAllNoReturn: TAction;
88 mnCopyAllNoReturn: TMenuItem;
89 mnPopCopyAll: TMenuItem;
90 mnPopCopyAllNoReturn: TMenuItem;
92 tbtnSetting: TToolButton;
93 mnStayOnTop: TMenuItem;
95 actExitClient: TAction;
97 tbtnEditConst: TToolButton;
98 actClearBottles: TAction;
99 mnClearBottles: TMenuItem;
100 MediaPlayer: TMediaPlayer;
101 mnGetNewId: TMenuItem;
102 actNextChannel: TAction;
103 actPrevChannel: TAction;
105 mnNextChannel: TMenuItem;
106 mnPrevChannel: TMenuItem;
109 tbtnShowLog: TToolButton;
110 tbtnSleep: TToolButton;
114 mnTaskSleep: TMenuItem;
116 tabChannel: TTabControl;
119 cbxTargetGhost: TComboBox;
120 actVoteMessage: TAction;
121 mnPopUpChannelTab: TPopupMenu;
122 mnLeaveThisChannel: TMenuItem;
124 mnGotoVote: TMenuItem;
125 mnGotoGLog: TMenuItem;
126 mnGoToHelp: TMenuItem;
130 mnExitAllChannels: TMenuItem;
131 actAgreeMessage: TAction;
134 actPrevGhost: TAction;
135 actNextGhost: TAction;
136 mnPrevGhost: TMenuItem;
137 mnNextGhost: TMenuItem;
138 actResetGhost: TAction;
139 mnResetGhost: TMenuItem;
140 timDisconnectCheckTimer: TTimer;
141 DirectSstp: TDirectSstp;
142 actDownloadLog: TAction;
143 actFMOExplorer: TAction;
144 tbtnFMOExplorer: TToolButton;
145 mnFMOExplorer: TMenuItem;
147 actInsertCue: TAction;
148 SakuraScriptFountain: TSakuraScriptFountain;
153 actSelectAll: TAction;
154 actEditCopy: TEditCopy;
155 actRecallScriptBuffer: TAction;
157 mnRecallScriptBuffer: TMenuItem;
158 tbtnEditorPreview: TToolButton;
159 actEditorPreview: TAction;
160 mnEditorPreview: TMenuItem;
161 actResetPlugins: TAction;
163 mnResetPlugins: TMenuItem;
164 ReplaceDialog: TReplaceDialog;
167 mnReplace: TMenuItem;
168 procedure actConfirmExecute(Sender: TObject);
169 procedure FormCreate(Sender: TObject);
170 procedure FormDestroy(Sender: TObject);
171 procedure actSendExecute(Sender: TObject);
172 procedure HTTPSuccess(Sender: TObject);
173 procedure HTTPFailure(Sender: TObject);
174 procedure actStartClick(Sender: TObject);
175 procedure actStopExecute(Sender: TObject);
176 procedure FormShow(Sender: TObject);
177 procedure mnAboutClick(Sender: TObject);
178 procedure actExitClientExecute(Sender: TObject);
179 procedure actClearExecute(Sender: TObject);
180 procedure memScriptChange(Sender: TObject);
181 procedure mnStayOnTopClick(Sender: TObject);
182 procedure actEditConstExecute(Sender: TObject);
183 procedure mnTaskBarClick(Sender: TObject);
184 procedure FormClose(Sender: TObject; var Action: TCloseAction);
185 procedure ApplicationEventsMinimize(Sender: TObject);
186 procedure ApplicationEventsRestore(Sender: TObject);
187 procedure mnTaskRestoreClick(Sender: TObject);
188 procedure TaskTrayDblClick(Seft: TObject; Button: TMouseButton);
189 procedure FormActivate(Sender: TObject);
190 procedure mnTaskNewMessageClick(Sender: TObject);
191 procedure ApplicationEventsHint(Sender: TObject);
192 procedure memScriptKeyDown(Sender: TObject; var Key: Word;
194 procedure mnShowToolBarClick(Sender: TObject);
195 procedure mnShowConstBarClick(Sender: TObject);
196 procedure mnGoToHPClick(Sender: TObject);
197 procedure LabelTimerTimer(Sender: TObject);
198 procedure actCopyAllExecute(Sender: TObject);
199 procedure actCopyAllNoReturnExecute(Sender: TObject);
200 procedure Slpp20SlppEvent(Sender: TObject; EventType: TIdSlppEventType;
201 const Param: String);
202 procedure actSettingExecute(Sender: TObject);
203 procedure memScriptKeyPress(Sender: TObject; var Key: Char);
204 procedure Slpp20Disconnect(Sender: TObject);
205 procedure actClearBottlesExecute(Sender: TObject);
206 procedure SakuraSeekerDetectResultChanged(Sender: TObject);
207 procedure mnGetNewIdClick(Sender: TObject);
208 procedure tabChannelChange(Sender: TObject);
209 procedure actPrevChannelExecute(Sender: TObject);
210 procedure actNextChannelExecute(Sender: TObject);
211 procedure cbxTargetGhostDropDown(Sender: TObject);
212 procedure actShowLogExecute(Sender: TObject);
213 procedure actSleepExecute(Sender: TObject);
214 procedure actVoteMessageExecute(Sender: TObject);
215 procedure tabChannelContextPopup(Sender: TObject; MousePos: TPoint;
216 var Handled: Boolean);
217 procedure mnLeaveThisChannelClick(Sender: TObject);
218 procedure mnGotoVoteClick(Sender: TObject);
219 procedure mnGotoGLogClick(Sender: TObject);
220 procedure tabChannelMouseMove(Sender: TObject; Shift: TShiftState; X,
222 procedure mnGoToHelpClick(Sender: TObject);
223 procedure tabChannelMouseDown(Sender: TObject; Button: TMouseButton;
224 Shift: TShiftState; X, Y: Integer);
225 procedure tabChannelDragOver(Sender, Source: TObject; X, Y: Integer;
226 State: TDragState; var Accept: Boolean);
227 procedure tabChannelDragDrop(Sender, Source: TObject; X, Y: Integer);
228 procedure tabChannelEndDrag(Sender, Target: TObject; X, Y: Integer);
229 procedure cbxTargetGhostDrawItem(Control: TWinControl; Index: Integer;
230 Rect: TRect; State: TOwnerDrawState);
231 procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
232 procedure actAgreeMessageExecute(Sender: TObject);
233 procedure actPrevGhostExecute(Sender: TObject);
234 procedure actNextGhostExecute(Sender: TObject);
235 procedure actResetGhostExecute(Sender: TObject);
236 procedure timDisconnectCheckTimerTimer(Sender: TObject);
237 procedure actDownloadLogExecute(Sender: TObject);
238 procedure cbxTargetGhostChange(Sender: TObject);
239 procedure actFMOExplorerExecute(Sender: TObject);
240 procedure actInsertCueExecute(Sender: TObject);
241 procedure FormResize(Sender: TObject);
242 procedure actCopyExecute(Sender: TObject);
243 procedure actPasteExecute(Sender: TObject);
244 procedure actCutExecute(Sender: TObject);
245 procedure actSelectAllExecute(Sender: TObject);
246 procedure memScriptMouseMove(Sender: TObject; Shift: TShiftState; X,
248 procedure actRecallScriptBufferExecute(Sender: TObject);
249 procedure actEditorPreviewExecute(Sender: TObject);
250 procedure actResetPluginsExecute(Sender: TObject);
251 procedure IdSLPP20Connect(Sender: TObject);
252 procedure actReplaceExecute(Sender: TObject);
253 procedure ReplaceDialogFind(Sender: TObject);
254 procedure ReplaceDialogReplace(Sender: TObject);
256 FSleeping: boolean; //
\94z
\91\97\83X
\83\8a\81[
\83v
\92\86\82©
\82Ç
\82¤
\82©
258 FConnecting: boolean;
260 FBooted: boolean; //
\8f\89\89ñ
\8bN
\93®
\92Ê
\90M
\97p
261 FOriginalCaption: String;
262 FAutoAddAfterGetChannel: boolean; //
\83`
\83\83\83\93\83l
\83\8b\8eæ
\93¾
\8cã
\82É
\83_
\83C
\83A
\83\8d\83O
\82È
\82µ
\82É
263 //
\83`
\83\83\83\93\83l
\83\8b\82É
\8eQ
\89Á
\82·
\82é
\82©
\82Ç
\82¤
\82©
267 FMutex: THandle; //Mutex
\83I
\83u
\83W
\83F
\83N
\83g
\81c
\93ñ
\8fd
\8bN
\93®
\96h
\8e~
\97p
269 FNowChannel: String; //
\8c»
\8dÝ
\91I
\91ð
\82³
\82ê
\82Ä
\82¢
\82é
\83`
\83\83\83\93\83l
\83\8b
270 JoinChannelsBackup: TStringList; //
\88ê
\8e\9e\8eg
\97p
272 FScriptModified: boolean; //
\83X
\83N
\83\8a\83v
\83g
\82ª
\95Ï
\8dX
\82³
\82ê
\82Ä
\82¢
\82é
\82©
\82Ç
\82¤
\82©
\81B
273 //
\83\8d\81[
\83J
\83\8b\8am
\94F
\8b
\90§
\97p
\83t
\83\89\83O
\81BTRichEdit.Modified
\82Í
274 //
\95Ê
\82Ì
\97p
\93r
\82Å
\8eg
\82Á
\82Ä
\82¢
\82é
\82Ì
\82Å
\8eg
\82¦
\82È
\82¢
276 FDragTabIndex: integer; //
\83^
\83u
\83h
\83\89\83b
\83O
\83h
\83\8d\83b
\83v
\8aÖ
\98A
277 FDragTabDest: integer; //
\83h
\83\8d\83b
\83v
\82·
\82é
\88Ê
\92u(
\82·
\82®
\89E
\82É
\82
\82é
\83^
\83u
\82Ì
\83C
\83\93\83f
\83b
\83N
\83X)
279 FBottleSstp: TBottleSstp; //
\8dÄ
\91\97\83v
\83\8d\83O
\83\89\83\80
281 FHttp: THTTPDownloadThread; //HTTP
\83_
\83E
\83\93\83\8d\81[
\83h
\83X
\83\8c\83b
\83h(
\83C
\83\93\83X
\83^
\83\93\83X
\82Í1
\8cÂ
\82Ì
\82Ý)
282 FBeginConnectFailCount: integer; //
\89½
\93x
\82à
\90Ú
\91±
\8e¸
\94s
\82µ
\82½
\82ç
\83\8a\83g
\83\89\83C
\92\86\8e~
284 FVisiblePreviewGhost: String;
285 FVisiblePreviewSurface: integer; //
\83T
\81[
\83t
\83B
\83X
\83v
\83\8c\83r
\83\85\81[
\82Å
\8c©
\82¦
\82Ä
\82¢
\82é
\82à
\82Ì
286 FVisibleMenuItem: TMenuItem; //
\83N
\83\8a\83b
\83N
\82³
\82ê
\82½
\83\81\83j
\83\85\81[
\83A
\83C
\83e
\83\80\81B
287 //
\83T
\81[
\83t
\83B
\83X
\83v
\83\8c\83r
\83\85\81[
\82ª
\83\81\83j
\83\85\81[
\82Ì
\89º
\82É
288 //
\89B
\82ê
\82È
\82¢
\82æ
\82¤
\82É
\95\
\8e¦
\82³
\82ê
\82Ä
\82¢
\82é
\82à
\82Ì
\82ð
\8bL
\89¯
\82µ
\82Ä
\82¨
\82
290 FTargetGhostExpand: boolean; //
\83S
\81[
\83X
\83g
\91I
\91ð
\83{
\83b
\83N
\83X
\82ª
\81A
291 //
\88ê
\8e\9e\93I
\82É
\91S
\95\94\95\
\8e¦
\82³
\82ê
\82Ä
\82¢
\82é
\82©
\82Ç
\82¤
\82©
\82Ì
\83t
\83\89\83O
293 FScriptBuffer: TObjectList; //
\83X
\83N
\83\8a\83v
\83g
\83N
\83\8a\83A
\83o
\83b
\83t
\83@
295 //
\88È
\89º
\81A
\8d\91\90¨
\92²
\8d¸
\82ð
\89ß
\93x
\82É
\91\97\90M
\82µ
\82È
\82¢
\82½
\82ß
\82Ì
\95Ï
\90\94
296 FLastGhostList: String; //
\83S
\81[
\83X
\83g
\83\8a\83X
\83g
\82Ì
\95¶
\8e\9a\97ñ
297 FLastGhostListSend: Int64; //
\8d\91\90¨
\92²
\8d¸
\82ð
\8dÅ
\8cã
\82É
\91\97\90M
\82µ
\82½
\8e\9e\8d\8f
299 FWM_TaskBarCreated: integer; //
\83^
\83X
\83N
\83o
\81[
\93o
\98^
\97p
\83E
\83B
\83\93\83h
\83E
\83\81\83b
\83Z
\81[
\83WID
301 procedure SetStatusText(const Value: String);
302 procedure SetSleeping(const Value: boolean);
304 procedure SetConnecting(const Value: boolean);
305 procedure SetAdded(const Value: boolean);
306 procedure mnConstClick(Sender: TObject);
307 procedure mnConstGroupClick(Sender: TObject);
308 property Added: boolean read FAdded write SetAdded;
309 property Sleeping: boolean read FSleeping write SetSleeping;
310 property StatusText: String read FStatusText write SetStatusText;
311 function GetScriptText: String;
312 procedure ChangeTaskIcon;
313 procedure ShowHintLabel(const Mes: String; Col: TColor = clBlue);
314 procedure UpdateLayout;
315 procedure DispatchBottle(EventType: TIdSlppEventType; Dat: THeadValue);
316 //
\83`
\83\83\83\93\83l
\83\8b\8aÖ
\8cW
317 procedure UpdateChannelInfo(Dat: THeadValue);
318 procedure UpdateJoinChannelList(Dat: THeadValue);
319 procedure NoLuidError;
320 procedure UpdateIfGhostBox;
321 function BuildMenuConditionCheck(const IfGhost, Ghost: String): boolean;
322 procedure BuildMenu(Root: TMenuItem; Simple: boolean);
323 procedure PlaySound(const FileName: String);
324 //TBottleSstp
\8aÖ
\8cW
\83C
\83x
\83\93\83g
\83n
\83\93\83h
\83\89
325 procedure BottleSstpResendCountChange(Sender: TObject);
326 procedure BottleSstpResendTrying(Sender: TObject; MID: String);
327 procedure BottleSstpResendEnd(Sender: TObject; MID: String);
328 function IsSurfaceTag(const Script: String; var ID: integer): boolean;
329 procedure DoSurfacePreview(Surface: integer; const Kind:
330 TSurfacePreviewType);
331 function GetSurfacePreviewPositionHint(w, h: integer): TPoint;
332 function GetSurfacePreviewPositionScriptPoint(w, h: integer): TPoint;
333 procedure EditorPreview;
334 //
\83^
\83O
\82Ì
\95¶
\8e\9a\97ñ
\82ð
\95Ï
\8a·
\82·
\82é
335 function TagReplace(Script: String;
336 Before, After: array of String): String; overload;
337 function TagReplace(Script: String;
338 Before, After: TStrings): String; overload;
340 procedure WndProc(var Message: TMessage); override;
342 function DoTrans(var Script: String;
343 Options: TScriptTransOptions): String; overload;
344 function DoTrans(var Script: String;
345 Options: TScriptTransOptions; out FoundURL: boolean): String; overload;
346 function ScriptTransForSSTP(const Script: String): String; overload;
347 function ScriptTransForSSTP(const Script: String;
348 out Error: String): String; overload;
349 procedure BeginConnect;
350 procedure RetryBeginConnect;
351 procedure EndConnect;
352 procedure ConstructMenu(Simple: boolean);
353 property Connecting: boolean read FConnecting write SetConnecting;
354 property BottleSstp: TBottleSstp read FBottleSstp;
355 function GhostNameToSetName(const Ghost: String): String;
356 procedure PostCommand(const Command: array of String); overload;
357 procedure PostCommand(Command: TStrings); overload;
358 procedure PostSetChannel(Channels: TStrings);
359 procedure SaveChainRuleList;
364 frmSender: TfrmSender;
367 PanelConnecting = 0; //
\81u
\90Ú
\91±
\92\86\81v
\95\
\8e¦
\97p
368 PanelBytes = 1; //
\81\9b\81\9b\83o
\83C
\83g
369 PanelCount = 2; //Local Proxy
\81A
\8c»
\8dÝ
\81\9b\8c\8f\91Ò
\82¿
370 PanelMembers = 3; //
\81\9b\81\9b\90l
371 PanelStatus = 4; //SSTP Bottle
\83T
\81[
\83o
\82É
\93o
\98^
\82³
\82ê
\82Ä
\82¢
\82Ü
\82·
\81c
\82È
\82Ç
374 IconDisconnected = 18;
376 IconSleepDisconnected = 20;
378 WarningColor = clRed;
380 SendButtonLongHint = 'Bottle
\82Ì
\91\97\90M';
382 function Token(const Str: String; const Delimiter: char;
383 const Index: integer): String;
387 uses SendConfirm, SettingForm, ChannelListForm, LogForm,
388 MessageBox, FMOExplorer, EditorTalkShow;
392 //
\92P
\8f\83\82É
\83o
\83C
\83g
\92P
\88Ê
\82Å
\95¶
\8e\9a\97ñ
\82ð
\8c©
\82Ä
\82¢
\82«
\95ª
\89ð
\82·
\82é
\83\86\81[
\83e
\83B
\83\8a\83e
\83B
\8aÖ
\90\94
393 function Token(const Str: String; const Delimiter: char;
394 const Index: integer): String;
395 var i, c, len: integer;
401 while i <= len do begin
402 if (Str[i] = Delimiter) and (StrByteType(PChar(Str), i) <> mbTrailByte) then begin
404 if c > Index then Break;
405 end else if c = Index then Result := Result + Str[i];
412 procedure TfrmSender.actConfirmExecute(Sender: TObject);
413 var AScript, Err, AGhost: String;
416 AScript := GetScriptText;
417 if Length(AScript) = 0 then Exit;
419 AScript := ScriptTransForSSTP(AScript, Err);
426 if cbxTargetGhost.ItemIndex > 0 then
427 AGhost := cbxTargetGhost.Text
428 else if FNowChannel <> '' then
429 AGhost := ChannelList.Channel[FNowChannel].Ghost
433 if Pref.IgnoreTimeCritical then
434 AScript := TagReplace(AScript, ['\t'], ['']);
436 Item := TLogItem.Create;
442 Channel := '
\81y
\8am
\94F
\81z';
445 BottleSstp.Unshift(Item);
450 FScriptModified := false;
453 procedure TfrmSender.FormCreate(Sender: TObject);
454 var Str: TStringList;
456 FScriptBuffer := TObjectList.Create(true);
458 SakuraSeeker.OnDetectResultChanged := SakuraSeekerDetectResultChanged;
459 FConstDir := ExtractFileDir(Application.ExeName)+'\consts';
460 ScriptConstList.LoadFromDir(FConstDir);
461 FSppDir := ExtractFileDir(Application.ExeName)+'\spp';
462 Spps.LoadFromDirectory(FSppDir);
463 ConstructMenu(false);
465 Str := TStringList.Create;
468 Str.LoadFromFile(ExtractFilePath(Application.ExeName)+'rule.txt');
469 BottleChainRuleList := StringToComponent(Str.Text) as TBottleChainRuleList;
472 Str.LoadFromFile(ExtractFilePath(Application.ExeName)+'defrule.txt');
473 BottleChainRuleList := StringToComponent(Str.Text) as TBottleChainRuleList;
475 Showmessage('defrule.txt
\93Ç
\82Ý
\8d\9e\82Ý
\92\86\82É
\92v
\96½
\93I
\83G
\83\89\81[
\82ª
\94
\90¶
\82µ
\82Ü
\82µ
\82½
\81Bdefrule.txt
\82ð
\8dÄ
\83C
\83\93\83X
\83g
\81[
\83\8b\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81B');
476 Application.Terminate;
477 Application.ProcessMessages;
485 FOriginalCaption := Self.Caption;
488 ShowMessage('
\93ñ
\8fd
\8bN
\93®
\8b\96\89Â
\83o
\81[
\83W
\83\87\83\93\82Å
\82·
\81B'#13#10 + VersionString);
490 FMutex := CreateMutex(nil, true, 'SSTPBottleClient2');
491 if GetLastError = ERROR_ALREADY_EXISTS then begin
493 ShowMessage('SSTP Bottle Client
\82Í
\93ñ
\8fd
\8bN
\93®
\82Å
\82«
\82Ü
\82¹
\82ñ');
495 Application.Terminate;
496 Application.ProcessMessages; //WM_QUIT
\82ð
\97¬
\82·
502 mnShowToolBar.Checked := Pref.ShowToolBar;
503 mnShowConstBar.Checked := Pref.ShowConstBar;
504 if Pref.StayOnTop then begin
505 FormStyle := fsStayOnTop;
506 mnStayOnTop.Checked := true;
508 FormStyle := fsNormal;
509 mnStayOnTop.Checked := false;
512 // URL
\83W
\83\83\83\93\83v
\90æ
\82ð
\83q
\83\93\83g
\95¶
\8e\9a\97ñ
\82Æ
\82µ
\82Ä
\90Ý
\92è
513 mnGoToHP.Hint := Pref.HomePage;
514 mnGotoGlog.Hint := Pref.GLogPage;
515 mnGotoVote.Hint := Pref.VotePage;
516 mnGotoHelp.Hint := Pref.HelpPage;
518 mnGetNewId.Enabled := (Pref.LUID = '');
520 //
\82³
\82
\82ç
\83X
\83N
\83\8a\83v
\83g
\89ð
\90Í
\83p
\83^
\81[
\83\93\82ð
\93Ç
\82Ý
\8d\9e\82Ý
522 SsParser.TagPattern.LoadFromFile(ExtractFilePath(Application.Exename) + 'tagpat.txt');
523 SsParser.MetaPattern.LoadFromFile(ExtractFilePath(Application.ExeName) + 'metapat.txt');
525 ShowMessage('tagpat.txt, metapat.txt
\82ª
\8c©
\82Â
\82©
\82è
\82Ü
\82¹
\82ñ
\81B');
526 Application.Terminate;
529 //
\83\81\83C
\83\93\83E
\83B
\83\93\83h
\83E
\82Ì
\88Ê
\92u
\82Æ
\83T
\83C
\83Y
\82ð
\95\9c\8bA
530 with Pref.SenderWindowPosition do begin
533 Self.Width := Right - Left + 1;
534 Self.Height := Bottom - Top + 1;
537 //
\83^
\83X
\83N
\83o
\81[
\82Ì
\8dÄ
\8bN
\93®(Explorer
\82ª
\97\8e\82¿
\82½
\82Æ
\82«)
\82ð
\8c\9f\8fo
\82·
\82é
538 FWM_TaskBarCreated := RegisterWindowMessage('TaskBarCreated');
540 //
\83X
\83N
\83\8a\83v
\83g
\95¶
\8e\9a\97ñ
\82Ì
\8f\89\8aú
\89»
541 actClearExecute(Sender);
542 //
\83^
\83X
\83N
\83g
\83\8c\83C
\82É
\83A
\83C
\83R
\83\93\82ð
\92Ç
\89Á
544 //
\83`
\83\83\83\93\83l
\83\8b\8eQ
\89Á
\8aÖ
\8cW
\82Ì
\83^
\83u
\82Ì
\8f\88\97\9d\82È
\82Ç(
\83`
\83\83\83\93\83l
\83\8b\95s
\8eQ
\89Á
\82Å
\8f\89\8aú
\89»)
545 UpdateJoinChannelList(nil);
547 // SSTP
\8dÄ
\91\97\83I
\83u
\83W
\83F
\83N
\83g
548 FBottleSstp := TBottleSstp.Create(false);
549 with FBottleSstp do begin
550 OnResendCountChange := BottleSstpResendCountChange;
551 OnResendTrying := BottleSstpResendTrying;
552 OnResendEnd := BottleSstpResendEnd;
556 procedure TfrmSender.FormDestroy(Sender: TObject);
558 if FScriptBuffer <> nil then
561 if FBottleSstp <> nil then begin
562 FBottleSstp.Terminate;
566 with Pref.SenderWindowPosition do begin
569 Right := Self.Left + Self.Width - 1;
570 Bottom := Self.Top + Self.Height - 1;
573 if JoinChannelsBackup <> nil then JoinChannelsBackup.Free;
575 ScriptConstList.Save;
578 BottleChainRuleList.Free;
581 ReleaseMutex(FMutex);
586 procedure TfrmSender.SetConnecting(const Value: boolean);
588 FConnecting := Value;
590 StatusBar.Panels[PanelConnecting].Text := '
\92Ê
\90M
\92\86';
591 actStart.Enabled := false;
592 actStop.Enabled := false;
593 actSend.Enabled := false;
594 actVoteMessage.Enabled := false;
595 actAgreeMessage.Enabled := false;
596 mnGetNewId.Enabled := false;
597 Screen.Cursor := crAppStart;
599 StatusBar.Panels[PanelConnecting].Text := '';
600 actStart.Enabled := true;
601 actStop.Enabled := true;
602 actSend.Enabled := true;
603 frmLog.lvwLogChange(Self, nil, ctState);
604 mnGetNewId.Enabled := Pref.LUID = '';
605 Screen.Cursor := crDefault;
609 //
\83\81\83b
\83Z
\81[
\83W
\91\97\90M
610 procedure TfrmSender.actSendExecute(Sender: TObject);
611 var Talk, Ghost: String;
612 Command: TStringList;
616 if Length(GetScriptText) = 0 then begin
617 ShowMessage('
\83X
\83N
\83\8a\83v
\83g
\82ª
\8bó
\82Å
\82·
\81B');
621 if Pref.LUID = '' then begin
625 if tabChannel.TabIndex < 0 then begin
626 ShowMessage('
\83`
\83\83\83\93\83l
\83\8b\82É
\8eQ
\89Á
\82µ
\82Ä
\82¢
\82Ü
\82¹
\82ñ
\81B'#13#10+
627 '
\83\81\83j
\83\85\81[
\82©
\82ç
\81u
\83`
\83\83\83\93\83l
\83\8b\8eQ
\89Á
\81v
\82ð
\8ds
\82Á
\82Ä
\82
\82¾
\82³
\82¢
\81B');
630 if ChannelList.Channel[FNowChannel].NoPost then begin
632 ShowMessage(FNowChannel + '
\82Í
\8eó
\90M
\90ê
\97p
\82Å
\82·');
636 if Pref.NeedConfirmBeforeSend and FScriptModified then begin
637 MessageDlg('
\91\97\90M
\91O
\82É
\83\8d\81[
\83J
\83\8b\8am
\94F
\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81B', mtError, [mbOk], 0);
641 if not Pref.NoConfirm then begin
642 if not SendConfirmDialog(FNowChannel, cbxTargetGhost.Text) then Exit;
646 Talk := GetScriptText;
647 Err := DoTrans(Talk, [toWarnMessySurface, toWarnCheck]);
648 if Err <> '' then begin
649 MessageDlg(Err, mtWarning, [mbOk], 0);
654 if cbxTargetGhost.ItemIndex > 0 then Ghost := cbxTargetGhost.Text;
656 Command := TStringList.Create;
657 with Command do begin
658 Add('Command: sendBroadcast');
659 Add('Channel: ' + FNowChannel);
660 Add('LUID: ' + Pref.LUID);
661 Add('Agent: ' + VersionString);
662 if Ghost <> '' then Add('Ghost: ' + Ghost);
663 Add('Talk: ' + Talk);
665 PostCommand(Command);
670 //
\91\97\90M
\83\8d\83O
\95Û
\91¶
671 AssignFile(F, ExtractFilePath(Application.ExeName) + SentLogFile);
672 if FileExists(ExtractFilePath(Application.ExeName) + SentLogFile) then
676 WriteLn(F, Format('%s,%s,%s,%s', [FNowChannel, Ghost, FormatDateTime('yy/mm/dd hh:nn:ss', Now), Talk]));
681 procedure TfrmSender.BeginConnect;
683 if Pref.LUID = '' then begin
687 IdSlpp20.LUID := Pref.LUID;
688 self.Cursor := crHourGlass;
690 if IdSlpp20.Connected then IdSlpp20.Disconnect;
691 if Pref.UseHttpProxy then begin
692 IdSlpp20.Host := Pref.ProxyAddress;
693 IdSlpp20.Port := Pref.ProxyPort;
694 IdSlpp20.ProxyMode := true;
696 IdSlpp20.Host := 'bottle.mikage.to';
697 IdSlpp20.Port := 9871;
698 IdSlpp20.ProxyMode := false;
702 on EIdException do begin
704 if FBeginConnectFailCount = 0 then begin
705 Inc(FBeginConnectFailCount);
707 if Pref.UseHttpProxy then
708 ShowMessage('HTTP Proxy
\82ð
\92Ê
\82¶
\82ÄSSTP Bottle
\83T
\81[
\83o
\82É
\90Ú
\91±
\82Å
\82«
\82Ü
\82¹
\82ñ
\82Å
\82µ
\82½
\81B'#13#10 +
709 '
\83l
\83b
\83g
\83\8f\81[
\83N
\82Ì
\8fó
\91Ô
\81EProxy
\82Ì
\8fó
\91Ô
\82ð
\8am
\94F
\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81B'#13#10 +
710 '
\82 \82é
\82¢
\82Í
\83T
\81[
\83o
\82ª
\83_
\83E
\83\93\82µ
\82Ä
\82¢
\82é
\89Â
\94\
\90«
\82ª
\82 \82è
\82Ü
\82·
\81B')
712 ShowMessage('SSTP Bottle
\83T
\81[
\83o
\82É
\90Ú
\91±
\82Å
\82«
\82Ü
\82¹
\82ñ
\82Å
\82µ
\82½
\81B'#13#10 +
713 '
\83l
\83b
\83g
\83\8f\81[
\83N
\82É
\8cq
\82ª
\82Á
\82Ä
\82¢
\82é
\82©
\8am
\94F
\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81B'#13#10 +
714 '
\82 \82é
\82¢
\82Í
\83T
\81[
\83o
\82ª
\83_
\83E
\83\93\82µ
\82Ä
\82¢
\82é
\89Â
\94\
\90«
\82ª
\82 \82è
\82Ü
\82·
\81B');
716 Inc(FBeginConnectFailCount);
719 self.Cursor := crDefault;
722 procedure TfrmSender.EndConnect;
724 IdSlpp20.OnDisconnect := nil;
728 procedure TfrmSender.SetAdded(const Value: boolean);
730 if FAdded = Value then Exit;
733 StatusText := 'SSTP Bottle
\83T
\81[
\83o
\82É
\90Ú
\91±
\82³
\82ê
\82Ä
\82¢
\82Ü
\82·';
736 StatusText := '
\83T
\81[
\83o
\82Æ
\82Ì
\90Ú
\91±
\82ª
\90Ø
\82ê
\82Ä
\82¢
\82Ü
\82·!';
738 ShowHintLabel('SSTP Bottle
\83T
\81[
\83o
\82©
\82ç
\90Ø
\92f
\82³
\82ê
\82Ü
\82µ
\82½!', WarningColor);
742 procedure TfrmSender.HTTPSuccess(Sender: TObject);
743 var Str, ResStr, Command: String;
744 HeadValue: THeadValue;
746 SetChannel: TStringList;
749 Str := (Sender as THttpDownloadThread).RecvString;
753 HeadValue := THeadValue.Create(Str);
755 ShowMessage('SSTP Bottle
\83T
\81[
\83o
\82ª
\89ð
\90Í
\82Å
\82«
\82È
\82¢
\83G
\83\89\81[
\82ð
\95Ô
\82µ
\82Ü
\82µ
\82½
\81B');
758 Command := HeadValue['Command'];
759 ResStr := HeadValue['Result'];
760 if ResStr = 'Err' then begin
761 if HeadValue['ExtraMessage'] <> '' then begin
763 ShowMessage('SSTP Bottle
\83T
\81[
\83o
\82ª
\8e\9f\82Ì
\83G
\83\89\81[
\82ð
\95Ô
\82µ
\82Ü
\82µ
\82½:'#13#10 +
764 HeadValue['ExtraMessage']);
767 ShowMessage('SSTP Bottle
\83T
\81[
\83o
\82ª
\89½
\82ç
\82©
\82Ì
\83G
\83\89\81[
\82ð
\95Ô
\82µ
\82Ü
\82µ
\82½
\81B');
770 if (Command = 'sendBroadcast') and (ResStr = 'OK') then begin
771 ShowHintLabel(HeadValue['Channel'] + '
\82Ì ' + HeadValue['SentNum'] +
772 '
\90l
\82É
\91\97\90M
\82µ
\82Ü
\82µ
\82½');
773 //
\83S
\81[
\83X
\83g
\82ð
\83f
\83t
\83H
\83\8b\83g
\82É
\96ß
\82·
774 if Pref.ResetIfGhostAfterSend then begin
775 actResetGhostExecute(Self);
777 //
\83X
\83N
\83\8a\83v
\83g
\82ð
\83N
\83\8a\83A
778 if Pref.ClearAfterSend then begin
781 end else if (Command = 'sendBroadcast') and (ResStr <> 'OK') then begin
782 ShowHintLabel('
\83\81\83b
\83Z
\81[
\83W
\82ð
\91\97\90M
\82Å
\82«
\82Ü
\82¹
\82ñ
\82Å
\82µ
\82½', WarningColor);
784 if (Command = 'getNewId') then begin
785 if ResStr = 'OK' then begin
786 Pref.LUID := HeadValue['NewID'];
787 ShowHintLabel('LUID
\8eæ
\93¾
\8a®
\97¹
\81B');
788 mnGetNewId.Enabled := false;
791 ShowHintLabel('LUID
\8eæ
\93¾
\82É
\8e¸
\94s
\82µ
\82Ü
\82µ
\82½');
794 if (Command = 'voteMessage') then begin
795 if ResStr = 'OK' then begin
796 ShowHintLabel('
\83\81\83b
\83Z
\81[
\83W
\82É
\93\8a\95[/
\93¯
\88Ó
\82µ
\82Ü
\82µ
\82½
\81B
\95[
\90\94: ' + HeadValue['Votes']);
799 if (Command = 'getChannels') and (ResStr = 'OK') then begin
800 UpdateChannelInfo(HeadValue);
803 if FAutoAddAfterGetChannel then begin
804 SetChannel := TStringList.Create;
805 if JoinChannelsBackup <> nil then begin
806 //
\88ê
\92U
\83`
\83\83\83\93\83l
\83\8b\8eQ
\89Á
\82É
\90¬
\8c÷
\82µ
\82½
\8cã
\82È
\82ç
\8dÅ
\8cã
\82É
\8eQ
\89Á
\82µ
\82Ä
\82¢
\82½
\83`
\83\83\83\93\83l
\83\8b
807 SetChannel.Assign(JoinChannelsBackup);
809 //
\8a®
\91S
\82É
\8f\89\89ñ
\8bN
\93®
\82Ì
\8fê
\8d\87\82Í
\83v
\83\8c\83t
\83@
\83\8c\83\93\83X
\82©
\82ç
\93o
\98^
\95ª
\82ð
\8eæ
\93¾
810 for i := 0 to Pref.AutoJoinChannels.Count-1 do begin
811 if ChannelList.Channel[Pref.AutoJoinChannels[i]] <> nil then
812 SetChannel.Add(Pref.AutoJoinChannels[i]);
816 Application.CreateForm(TfrmChannelList, frmChannelList);
818 if frmChannelList.Execute(ChannelList, JoinChannels) then begin
819 SetChannel := TStringList.Create;
820 SetChannel.Assign(frmChannelList.JoinList);
823 frmChannelList.Release;
826 if SetChannel <> nil then PostSetChannel(SetChannel);
828 if SetChannel <> nil then FreeAndNil(SetChannel);
831 if (Command = 'setChannels') then begin
832 if ResStr <> 'OK' then begin
834 ShowMessage('
\83`
\83\83\83\93\83l
\83\8b\90Ý
\92è
\82É
\8e¸
\94s
\82µ
\82Ü
\82µ
\82½
\81B
\82à
\82¤
\88ê
\93x
\93o
\98^
\82µ
\82È
\82¨
\82µ
\82Ä
\82
\82¾
\82³
\82¢');
835 ShowHintLabel('
\83`
\83\83\83\93\83l
\83\8b\90Ý
\92è
\82É
\8e¸
\94s
\82µ
\82Ü
\82µ
\82½', WarningColor);
838 if HeadValue['ExtraTip'] <> '' then ShowHintLabel(HeadValue['ExtraTip']);
844 procedure TfrmSender.actStartClick(Sender: TObject);
846 if Pref.LUID = '' then begin
850 if not IdSlpp20.Connected then begin
851 FBeginConnectFailCount := 0; //
\8e©
\93®
\8dÄ
\90Ú
\91±
\83J
\83E
\83\93\83^
\83\8a\83Z
\83b
\83g
855 FAutoAddAfterGetChannel := false;
856 PostCommand(['Command: getChannels']);
860 procedure TfrmSender.actStopExecute(Sender: TObject);
862 //
\8b
\90§
\8dÄ
\90Ú
\91±
\82ð
\8ds
\82¤
863 IdSlpp20.OnDisconnect := nil;
864 if IdSlpp20.Connected then IdSlpp20.Disconnect;
865 FAutoAddAfterGetChannel := true;
867 IdSlpp20.OnDisconnect := Slpp20Disconnect;
870 procedure TfrmSender.FormShow(Sender: TObject);
872 if FBooted or Application.Terminated then Exit;
873 //LUID
\82ª
\8eæ
\93¾
\82³
\82ê
\82Ä
\82¢
\82ê
\82Î
\91\81\91¬
\93o
\98^
\81B
\82»
\82¤
\82Å
\82È
\82¯
\82ê
\82ÎLUID
\8eæ
\93¾
\81B
874 if Pref.LUID <> '' then BeginConnect
875 else mnGetNewIdClick(Self);
876 FAutoAddAfterGetChannel := Pref.AutoStart;
879 frmSurfacePreview.Show;
881 SakuraSeeker.BeginDetect;
882 SakuraSeekerDetectResultChanged(self);
883 if SakuraSeeker.Count = 0 then
884 frmMessageBox.ShowMessage('
\83S
\81[
\83X
\83g(SSTP
\83T
\81[
\83o)
\82ª1
\82Â
\82à
\8bN
\93®
\82µ
\82Ä
\82¢
\82Ü
\82¹
\82ñ
\81B'#13#10 +
885 'SSTP Bottle
\82ð
\97\98\97p
\82·
\82é
\82½
\82ß
\82É
\82Í
\81A
\83S
\81[
\83X
\83g
\82ð
\93¯
\8e\9e\82É
\8bN
\93®
\82·
\82é
\95K
\97v
\82ª
\82 \82è
\82Ü
\82·'#13#10 +
886 '
\8fÚ
\8d×
\82Í
\83w
\83\8b\83v
\82ð
\82²
\97\97\89º
\82³
\82¢
\81B');
889 procedure TfrmSender.mnAboutClick(Sender: TObject);
892 Str := VersionString + #13#10 + BottleDisclaimer + #13#10#13#10;
893 Str := Str + Format('Compiler Version: %f', [CompilerVersion]);
894 frmMessageBox.ShowMessage(Str);
897 procedure TfrmSender.actExitClientExecute(Sender: TObject);
902 procedure TfrmSender.actClearExecute(Sender: TObject);
903 var TmpScript: String;
905 DoSaveBuffer: boolean;
906 SavedScript: TStringList;
908 //
\83X
\83N
\83\8a\83v
\83g
\82Ì
\83N
\83\8a\83A
909 //
\82Ü
\82¸
\81A
\83X
\83N
\83\8a\83v
\83g
\83N
\83\8a\83A
\83o
\83b
\83t
\83@
\82É
\8c»
\8dÝ
\82Ì
\83X
\83N
\83\8a\83v
\83g
\82ð
\95Û
\91¶
\82·
\82é
910 DoSaveBuffer := false;
911 if FScriptBuffer.Count = 0 then
913 else if (FScriptBuffer[0] as TStringList).Text <> GetScriptText then
914 DoSaveBuffer := true;
915 if (GetScriptText = Pref.DefaultScript) or (GetScriptText = '') then
916 DoSaveBuffer := false;
919 SavedScript := TStringList.Create;
920 SavedScript.Text := GetScriptText;
921 FScriptBuffer.Insert(0, SavedScript);
923 if FScriptBuffer.Count >= 4 then
924 FScriptBuffer.Delete(FScriptBuffer.Count-1);
925 actRecallScriptBuffer.Enabled := FScriptBuffer.Count > 0;
927 TmpScript := Pref.DefaultScript;
928 Position := Pos('|', TmpScript);
929 if Position < 1 then Position := 1;
930 TmpScript := StringReplace(TmpScript, '|', '', []);
931 memScript.Lines.Text := TmpScript;
932 Sendmessage(memScript.Handle, WM_VSCROLL, SB_LINEUP, 0);
933 memScript.SelStart := Position-1;
935 if Visible then memScript.SetFocus;
936 FScriptModified := false;
937 memScriptChange(self);
940 procedure TfrmSender.memScriptChange(Sender: TObject);
943 Script := StringReplace(GetScriptText, #13#10, '', [rfReplaceAll]);
944 StatusBar.Panels[PanelBytes].Text := IntToStr(length(Script)) + '
\83o
\83C
\83g';
945 FScriptModified := true;
949 procedure TfrmSender.mnStayOnTopClick(Sender: TObject);
951 Pref.StayOnTop := not Pref.StayOnTop;
952 mnStayOnTop.Checked := Pref.StayOnTop;
953 if Pref.StayOnTop then begin
954 FormStyle := fsStayOnTop;
956 FormStyle := fsNormal;
961 function TfrmSender.GetScriptText: String;
963 Result := memScript.Lines.Text;
966 procedure TfrmSender.mnConstClick(Sender: TObject);
969 i := (Sender as TMenuItem).Tag;
970 memScript.SelText := ScriptConstList.GetConstByID(i).ConstText;
973 procedure TfrmSender.actEditConstExecute(Sender: TObject);
975 ScriptConstList.LoadFromDir(FConstDir);
977 Application.CreateForm(TfrmConstEditor, frmConstEditor);
978 frmConstEditor.Execute;
979 ScriptConstList.Save;
981 frmConstEditor.Release;
983 ConstructMenu(false);
986 procedure TfrmSender.mnTaskBarClick(Sender: TObject);
988 Application.Minimize;
989 WindowState := wsNormal;
992 procedure TfrmSender.FormClose(Sender: TObject; var Action: TCloseAction);
995 TaskTray.Registered := false;
998 procedure TfrmSender.ApplicationEventsMinimize(Sender: TObject);
1001 Application.ShowMainForm := false;
1002 ShowWindow(Application.Handle, SW_HIDE);
1005 procedure TfrmSender.ApplicationEventsRestore(Sender: TObject);
1007 Application.ShowMainForm := true;
1011 procedure TfrmSender.mnTaskRestoreClick(Sender: TObject);
1013 Application.Restore;
1016 procedure TfrmSender.TaskTrayDblClick(Seft: TObject; Button: TMouseButton);
1018 Application.Restore;
1021 procedure TfrmSender.FormActivate(Sender: TObject);
1026 procedure TfrmSender.mnTaskNewMessageClick(Sender: TObject);
1028 Application.Restore;
1029 actClearExecute(Sender);
1032 procedure TfrmSender.ChangeTaskIcon;
1037 if Sleeping then IcoNum := IconSleep else IcoNum := IconConnected;
1039 if Sleeping then IcoNum := IconSleepDisconnected
1040 else IcoNum := IconDisconnected;
1043 Ico := TIcon.Create;
1045 imgIcon.GetIcon(IcoNum, Ico);
1046 TaskTray.Icon := Ico;
1047 TaskTray.Registered := true;
1052 ; // PC
\82Ì
\95\89\89×
\82ª
\8d\82\82¢
\82Æ4
\95b
\88È
\93à
\82É
\83^
\83X
\83N
\83g
\83\8c\83C
\93o
\98^
\82Å
\82«
\82¸
\81A
1053 //
\83V
\83F
\83\8b\82ª
\83n
\83\93\83O
\82µ
\82Ä
\82¢
\82é
\82Æ
\94»
\92f
\82³
\82ê
\82Ä
\97á
\8aO
\82ª
\94
\90¶
\82·
\82é
\81B
1054 //
\82»
\82Ì
\8fê
\8d\87\82Í
\83G
\83\89\81[
\82ð
\96³
\8e\8b\82·
\82é
1058 procedure TfrmSender.SetStatusText(const Value: String);
1060 FStatusText := Value;
1061 StatusBar.Panels[PanelStatus].Text := Value;
1064 procedure TfrmSender.ApplicationEventsHint(Sender: TObject);
1067 if Length(Application.Hint) > 0 then
1069 StatusBar.Panels[PanelStatus].Text := GetLongHint(Application.Hint);
1070 Application.HintColor := clInfoBk;
1071 if (Application.Hint = SendButtonLongHint)
1072 and (FNowChannel <> '') then
1074 //
\91\97\90M
\83{
\83^
\83\93\82Ì
\8fê
\8d\87\82Í
\91¬
\8dU
\8fo
\82·
1075 Application.HintColor := clYellow;
1076 Application.ActivateHint(Mouse.CursorPos);
1078 if IsSurfaceTag(Application.Hint, id) and Pref.SurfacePreviewOnHint then
1080 //
\83T
\81[
\83t
\83B
\83X
\83v
\83\8c\83r
\83\85\81[
1081 DoSurfacePreview(id, spHint);
1085 StatusBar.Panels[PanelStatus].Text := FStatusText;
1086 frmSurfacePreview.HideAway;
1090 procedure TfrmSender.ConstructMenu(Simple: boolean);
1092 BuildMenu(mnPopConst, Simple);
1093 BuildMenu(mnPopUpConst.Items, Simple);
1094 BuildMenu(ConstBarMenu.Items, Simple);
1095 //ConstMenuBar.Menu := nil;
1096 ConstMenuBar.AutoSize := false;
1097 ConstMenuBar.Width := 1000;
1098 ConstMenuBar.Menu := ConstBarMenu;
1099 ConstMenuBar.AutoSize := true;
1102 procedure TfrmSender.memScriptKeyDown(Sender: TObject; var Key: Word;
1103 Shift: TShiftState);
1105 Func: TReturnKeyFunction;
1107 if (Key = VK_RETURN) then begin
1108 if (ssShift in Shift) then
1109 Func := Pref.WhenShiftReturn
1110 else if (ssCtrl in Shift) then
1111 Func := Pref.WhenCtrlReturn
1113 Func := Pref.WhenReturn;
1116 with tbtnInsertConst do
1117 Pos := tbtnInsertConst.ClientToScreen(Point(0, Height));
1118 mnPopUpConst.Popup(Pos.X, Pos.Y);
1121 memScript.SelText := '\n';
1125 memScript.SelText := '\n'#13#10;
1128 memScript.SelText := #13#10
1134 procedure TfrmSender.mnShowToolBarClick(Sender: TObject);
1136 mnShowToolBar.Checked := not mnShowToolBar.Checked;
1137 Pref.ShowToolBar := mnShowToolBar.Checked;
1141 procedure TfrmSender.mnShowConstBarClick(Sender: TObject);
1143 mnShowConstBar.Checked := not mnShowConstBar.Checked;
1144 Pref.ShowConstBar := mnShowConstBar.Checked;
1148 procedure TfrmSender.UpdateLayout;
1150 with SakuraScriptFountain do begin
1151 TagColor.Color := Pref.MarkUpColor;
1152 TagErrorColor.Color := Pref.MarkErrorColor;
1153 Scope0Color.Color := Pref.TalkColorH;
1154 Scope1Color.Color := Pref.TalkColorU;
1155 SynchronizedColor.Color := Pref.TalkColorS;
1157 memScript.Ruler.Visible := Pref.ShowRuler;
1158 memScript.Ruler.Color := Pref.TalkColorH;
1159 memScript.Color := Pref.BgColor;
1161 ToolBar.Visible := Pref.ShowToolBar;
1162 ConstMenuBar.Visible := Pref.ShowConstBar;
1165 with tabChannel do begin
1166 TabPosition := Pref.TabPosition;
1167 case Pref.TabPosition of
1168 tpTop: Align := alTop;
1169 tpBottom: Align := alBottom;
1174 function TfrmSender.DoTrans(var Script: String;
1175 Options: TScriptTransOptions; out FoundURL: boolean): String;
1176 var UrlCancel, Mark: String;
1177 Url, UrlName: array[0..6] of String;
1178 i, j, u, UrlCount: integer;
1179 LastSurfaceH, LastSurfaceU: integer;
1180 UnyuTalking: boolean;
1181 QuickSection, Synchronize: boolean;
1182 Warnings: TStringList;
1187 UnyuTalking := false;
1188 QuickSection := false;
1189 Synchronize := false;
1190 SsParser.LeaveEscape := true;
1191 SsParser.EscapeInvalidMeta := false;
1192 SsParser.InputString := Script;
1194 Warnings := TStringList.Create;
1196 for i := 0 to SsParser.Count-1 do begin
1197 if SsParser[i] = '\t' then begin
1198 if not(toIgnoreTimeCritical in Options) then
1199 Script := Script + '\t';
1200 end else if SsParser[i] = '\e' then begin
1202 end else if (SsParser.Match(SsParser[i], '\URL%b') > 0) then begin
1203 if toConvertURL in Options then begin
1204 UrlCount := 0; //
\91O
\82ÌURL
\83^
\83O
\82Ì
\89e
\8b¿
\82ð
\96³
\8e\8b\81B
1205 for u := 7 downto 1 do begin
1206 if (SsParser.Match(SsParser[i],
1207 '\URL%b'+StringReplace(StringOfChar('-', u*2),
1208 '-', '%b', [rfReplaceAll]))) > 0 then begin
1209 for j := 1 to u do begin
1210 Url[UrlCount] := SsParser.GetParam(SsParser[i], UrlCount*2+2);
1211 UrlName[UrlCount] := SsParser.GetParam(SsParser[i], UrlCount*2+3);
1212 if UrlName[UrlCount] = '' then UrlName[UrlCount] := Url[UrlCount];
1213 if Pos('http://', Url[UrlCount]) > 0 then Inc(UrlCount);
1216 if UrlCount > 0 then UrlCancel := SsParser.GetParam(SsParser[i], 1);
1217 if UrlCancel = '' then UrlCancel := '
\8ds
\82©
\82È
\82¢
\81@
\81@
\81@
\81@';
1219 if SsParser.Match(SsParser[i], '\URL%b%b') = 0 then begin //
\8aÈ
\88Õ
\94ÅURL
\95Ï
\8a·
1220 //
\8aÈ
\88Õ
\8c`
\8e®\URL
\83^
\83O
\95Ï
\8a·
1221 Url[0] := SsParser.GetParam(SsParser[i], 1);
1222 UrlName[0] := '
\8ds
\82
\81@
\81@
\81@
\81@
\81@
\81@';
1223 UrlCancel := '
\8ds
\82©
\82È
\82¢
\81@
\81@
\81@
\81@';
1224 if Pos('http://', Url[0]) > 0 then begin
1226 if not QuickSection then
1227 Script := Script + '\_q' + Url[0] + '\_q'
1229 Script := Script + Url[0];
1232 end else Script := Script + SsParser[i];
1234 Mark := SsParser[i];
1235 if Mark = '\h' then begin
1236 UnyuTalking := false;
1237 if toHUTagTo01Tag in Options then Mark := '\0';
1238 if Synchronize and Pref.WarnScopeChangeInSynchronize then
1239 Warnings.Add('
\83V
\83\93\83N
\83\8d\83i
\83C
\83Y
\83h
\83Z
\83N
\83V
\83\87\83\93\92\86\82É\h
\82ª
\82 \82è
\82Ü
\82·
\81B');
1240 end else if Mark = '\u' then begin
1241 UnyuTalking := true;
1242 if toHUTagTo01Tag in Options then Mark := '\1';
1243 if Synchronize and Pref.WarnScopeChangeInSynchronize then
1244 Warnings.Add('
\83V
\83\93\83N
\83\8d\83i
\83C
\83Y
\83h
\83Z
\83N
\83V
\83\87\83\93\92\86\82É\u
\82ª
\82 \82è
\82Ü
\82·
\81B');
1245 end else if Mark = '\_q' then begin
1246 QuickSection := not QuickSection;
1247 end else if Mark = '\_s' then begin
1248 Synchronize := not Synchronize;
1249 end else if SsParser.Match(Mark, '\s%b') > 0 then begin
1250 if UnyuTalking then begin
1251 LastSurfaceU := StrToIntDef(SsParser.GetParam(Mark, 1),
1254 LastSurfaceH := StrToIntDef(SsParser.GetParam(Mark, 1),
1257 end else if SsParser.Match(Mark, '\s%d') > 0 then begin
1258 if UnyuTalking then begin
1259 LastSurfaceU := StrToIntDef(Mark[3], LastSurfaceU);
1261 LastSurfaceH := StrToIntDef(Mark[3], LastSurfaceH);
1264 Script := Script + Mark;
1267 if UrlCount > 0 then begin
1269 Script := Script + '\h\n';
1270 if not (toNoChoice in Options) then begin
1271 for i := 0 to UrlCount-1 do begin
1272 Script := Script + Format('\q%d[%s][%s]',
1273 [i, SsParser.EscapeParam(Url[i]), UrlName[i]]);
1275 Script := Script + Format('\q%d[#cancel][%s]', [UrlCount, UrlCancel]);
1276 //Script := Script + '\z'; //
\8dÅ
\90Vphase
\82Å
\82Í
\8dí
\8f\9c
1278 Script := Script + '\h';
1279 for i := 0 to UrlCount-1 do begin
1280 Script := Script + Format('\n{%s}(%s)', [UrlName[i], Url[i]]);
1281 Script := Script + Format('\n{%s}', [UrlCancel]);
1286 //
\83X
\83N
\83\8a\83v
\83g
\82Ì
\8dÅ
\8cã
\82É
\83E
\83F
\83C
\83g
\91}
\93ü
1287 if toWaitScriptEnd in Options then begin
1288 i := Pref.WaitScriptEnd;
1289 while i > 0 do begin
1291 Script := Script + '\w9';
1294 Script := Script + '\w' + IntToStr(i);
1300 Script := Script + '\e';
1301 RegExp.Subst('s/\r\n//gk', Script);
1303 //
\83^
\83O
\83`
\83F
\83b
\83N
\8aÖ
\98A
1304 for i := 0 to SsParser.Count-1 do begin
1305 if SsParser.MarkUpType[i] = mtTagErr then begin
1306 Result := '"' + SsParser[i] + '"'#13#10 +
1307 '
\82Í
\81ASSTP Bottle
\82Å
\94F
\82ß
\82ç
\82ê
\82È
\82¢
\82©
\81A
\94F
\8e¯
\82Å
\82«
\82È
\82¢
\83^
\83O
\82Å
\82·
\81B';
1311 if (SsParser[0] <> '\t') and Pref.WarnYenTNotExist then begin
1312 Warnings.Add('
\83X
\83N
\83\8a\83v
\83g
\82ª\t
\82©
\82ç
\8en
\82Ü
\82Á
\82Ä
\82¢
\82Ü
\82¹
\82ñ
\81B');
1316 if (Warnings.Count > 0) and (toWarnCheck in Options) then begin
1317 if MessageDlg(Warnings.Text + #13#10 + '
\91\97\90M
\82µ
\82Ü
\82·
\82©?', mtWarning,
1318 mbOkCancel, 0) = mrCancel then
1319 Result := Warnings.Text;
1326 function TfrmSender.DoTrans(var Script: String;
1327 Options: TScriptTransOptions): String;
1330 Result := DoTrans(Script, Options, dum);
1333 procedure TfrmSender.mnGoToHPClick(Sender: TObject);
1335 ShellExecute(Handle, 'open', PChar(Pref.HomePage), nil, nil, SW_SHOW);
1338 procedure TfrmSender.ShowHintLabel(const Mes: String; Col: TColor);
1340 lblMessage.Caption := Mes;
1341 lblMessage.Font.Color := Col;
1342 lblMessage.Visible := true;
1343 LabelTimer.Enabled := false;
1344 LabelTimer.Enabled := true;
1347 procedure TfrmSender.LabelTimerTimer(Sender: TObject);
1349 LabelTimer.Enabled := false;
1350 lblmessage.Visible := false;
1353 procedure TfrmSender.actCopyAllExecute(Sender: TObject);
1357 Str := memScript.Lines.Text;
1358 Clip := ClipBoard();
1359 Clip.SetTextBuf(PChar(Str));
1362 procedure TfrmSender.actCopyAllNoReturnExecute(Sender: TObject);
1366 Str := memScript.Lines.Text;
1367 RegExp.Subst('s/\r\n//gk', Str);
1368 Clip := ClipBoard();
1369 Clip.SetTextBuf(PChar(Str));
1372 procedure TfrmSender.Slpp20SlppEvent(Sender: TObject; EventType: TIdSlppEventType;
1373 const Param: String);
1374 var HeadValue: THeadValue;
1376 HeadValue := THeadValue.Create(Param);
1379 etScript, etForceBroadcast, etUnicast: begin
1380 //
\83\81\83b
\83Z
\81[
\83W
\8eó
\90M
1381 DispatchBottle(EventType, HeadValue);
1383 etMemberCount: begin
1384 StatusBar.Panels[PanelMembers].Text := HeadValue['Num'] + '
\90l'
1386 etChannelCount: begin
1388 ChannelList.Channel[HeadValue['Channel']].Members := StrToInt(HeadValue['Num']);
1393 ShowHintLabel('SSTP Bottle
\83T
\81[
\83o
\82Æ
\92Ê
\90M
\8am
\97§
\81B');
1395 FBeginConnectFailCount := 0;
1396 //
\83`
\83\83\83\93\83l
\83\8b\8e©
\93®
\93o
\98^
1397 if not Connecting then
1398 PostCommand(['Command: getChannels']);
1399 SakuraSeeker.BeginDetect;
1401 etChannelList: begin
1402 UpdateJoinChannelList(HeadValue);
1403 //
\8dÅ
\8cã
\82É
\8eQ
\89Á
\82µ
\82Ä
\82¢
\82½
\83`
\83\83\83\93\83l
\83\8b\82ð
\8bL
\98^
\82·
\82é
1404 if JoinChannelsBackup = nil then JoinChannelsBackup := TStringList.Create;
1405 JoinChannelsBackup.Assign(JoinChannels);
1407 etCloseChannel: begin
1408 with JoinChannels do
1409 if IndexOf(HeadValue['Channel']) >= 0 then
1410 Delete(IndexOf(HeadValue['Channel']));
1411 with tabChannel do begin
1412 if Tabs.IndexOf(HeadValue['Channel']) >= 0 then
1413 Tabs.Delete(Tabs.IndexOf(HeadValue['Channel']));
1414 if Tabs.Count > 0 then TabIndex := 0 else TabIndex := -1;
1415 tabChannelChange(self);
1417 ShowHintLabel(HeadValue['Channel'] + '
\83`
\83\83\83\93\83l
\83\8b\82Í
\94p
\8e~
\82³
\82ê
\82Ü
\82µ
\82½',
1419 frmLog.AddCurrentSystemLog('SYSTEM', HeadValue['Channel'] + '
\83`
\83\83\83\93\83l
\83\8b\82Í
\94p
\8e~
\82³
\82ê
\82Ü
\82µ
\82½');
1420 frmMessageBox.ShowMessage(HeadValue['Channel'] + '
\83`
\83\83\83\93\83l
\83\8b\82Í
\94p
\8e~
\82³
\82ê
\82Ü
\82µ
\82½');
1422 etForceBroadcastInformation: begin
1423 if HeadValue['Type'] = 'Vote' then begin
1424 frmLog.VoteLog(HeadValue['MID'], StrToIntDef(HeadValue['Num'], 0));
1425 end else if HeadValue['Type'] = 'Agree' then begin
1426 frmLog.AgreeLog(HeadValue['MID'], StrToIntDef(HeadValue['Num'], 0));
1435 procedure TfrmSender.BottleSstpResendCountChange(Sender: TObject);
1437 StatusBar.Panels[PanelCount].Text := IntToStr(FBottleSstp.CueCount) + '
\8c\8f';
1439 TaskTray.TipString := 'SSTP Bottle Client (' +
1440 IntToStr(FBottleSstp.CueCount) + '
\8c\8f)';
1442 ; //
\83^
\83X
\83N
\83g
\83\8c\83C
\93o
\98^
\8e¸
\94s
\82ð
\96³
\8e\8b\82·
\82é
1444 actClearBottles.Enabled := (FBottleSstp.CueCount > 0);
1447 procedure TfrmSender.actSettingExecute(Sender: TObject);
1449 Application.CreateForm(TfrmSetting, frmSetting);
1461 frmLog.UpdateWindow;
1464 procedure TfrmSender.memScriptKeyPress(Sender: TObject; var Key: Char);
1466 if (Key = #13) or (Key = #10) then Key := Char(0);
1469 procedure TfrmSender.Slpp20Disconnect(Sender: TObject);
1472 UpdateJoinChannelList(nil);
1473 frmLog.AddCurrentSystemLog('SYSTEM', '
\83T
\81[
\83o
\82©
\82ç
\90Ø
\92f
\82³
\82ê
\82Ü
\82µ
\82½');
1474 if not Application.Terminated then RetryBeginConnect;
1477 procedure TfrmSender.SetSleeping(const Value: boolean);
1480 FBottleSstp.ResendSleep := Value;
1484 procedure TfrmSender.actClearBottlesExecute(Sender: TObject);
1487 Re := MessageDlg(Format('
\96¢
\94z
\91\97\82Ì%d
\8c\8f\82ÌBottle
\82ð
\91S
\95\94\83N
\83\8a\83A
\82µ
\82Ü
\82·', [FBottleSstp.CueCount]),
1488 mtWarning, mbOkCancel, 0);
1489 if Re = mrOk then begin
1491 frmLog.AllBottleOpened;
1492 frmLog.UpdateWindow;
1496 procedure TfrmSender.SakuraSeekerDetectResultChanged(Sender: TObject);
1499 Http: THTTPDownloadThread;
1502 UpdateIfGhostBox; //
\83h
\83\8d\83b
\83v
\83_
\83E
\83\93\82Ì
\92\86\90g
\82ð
\8f\91\82«
\8a·
\82¦
\82é
1504 if (FLastGhostListSend <> 0) and
1505 (GetTickCount < FLastGhostListSend + 1000*60) then
1509 FLastGhostListSend := GetTickCount;
1511 //
\8d\91\90¨
\92²
\8d¸
\82É
\8eQ
\89Á
1512 if FBooted and not Pref.NoSendGhostList and (SakuraSeeker.Count > 0) then begin
1513 GhostList := 'CCC=' + TIdURI.ParamsEncode('
\88¤');
1514 GhostList := GhostList + '&LUID=' + Pref.LUID;
1516 for i := 0 to SakuraSeeker.Count-1 do begin
1517 if SakuraSeeker[i].Name <> '' then begin//
\82±
\82ê
\82ª
\82È
\82¢
\82Æ
\82½
\82Ü
\82ÉFMO
\89ó
\82ê
\82Å
\8bó
\82Ì
\83S
\81[
\83X
\83g
\82ð
\91\97\82Á
\82Ä
\82µ
\82Ü
\82¤
1518 GhostList := GhostList + '&GHOST=' + TIdURI.ParamsEncode(SakuraSeeker[i].SetName);
1522 if SendOk and (FLastGhostList <> GhostList) then begin
1523 FLastGhostList := GhostList;
1524 Http := THTTPDownloadThread.Create(BottleServer, Pref.CgiNameGhost, GhostList);
1525 if Pref.UseHttpProxy then begin
1526 Http.ProxyServer := Pref.ProxyAddress;
1527 Http.ProxyPort := Pref.ProxyPort;
1529 Http.FreeOnTerminate := true;
1535 procedure TfrmSender.UpdateChannelInfo(Dat: THeadValue);
1537 Ch: TChannelListItem;
1540 for i := 1 to Dat.IntData['Count'] do begin
1541 Ch := TChannelListItem.Create;
1542 Ch.Name := Dat[Format('CH%d_name', [i])];
1543 Ch.Ghost := Dat[Format('CH%d_ghost', [i])];
1544 Ch.Info := Dat[Format('CH%d_info', [i])];
1545 Ch.NoPost := Dat[Format('CH%d_nopost', [i])] = '1';
1546 Ch.Members := Dat.IntData[Format('CH%d_count', [i])];
1547 Ch.WarnPost:= Dat[Format('CH%d_warnpost', [i])] = '1';
1548 ChannelList.Add(Ch);
1553 procedure TfrmSender.mnGetNewIdClick(Sender: TObject);
1555 PostCommand(['Command: getNewId', 'Agent: ' + VersionString]);
1558 procedure TfrmSender.NoLuidError;
1561 ShowMessage('SSTP Bottle ID
\82Ì
\8eæ
\93¾
\82ª
\82Ü
\82¾
\8a®
\97¹
\82µ
\82Ä
\82¢
\82Ü
\82¹
\82ñ
\81B'#13#10+
1562 '
\83w
\83\8b\83v
\83\81\83j
\83\85\81[
\82Ì[LUID
\8eæ
\93¾]
\82©
\82çID
\82ð
\8eæ
\93¾
\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81B'#13#10+
1563 '
\82±
\82Ì
\91\80\8dì
\82ÍClient
\8f\89\89ñ
\8bN
\93®
\8e\9e\82É1
\89ñ
\82¾
\82¯
\95K
\97v
\82Å
\82·
\81B');
1566 procedure TfrmSender.tabChannelChange(Sender: TObject);
1568 if tabChannel.TabIndex >= 0 then begin
1569 FNowChannel := tabChannel.Tabs[tabChannel.TabIndex];
1570 actSend.Hint := Format('
\81u%s
\81v
\82É
\91\97\90M|%s', [FNowChannel, SendButtonLongHint]);
1575 tabChannel.Repaint; //
\82±
\82ê
\82ª
\82È
\82¢
\82Æ
\90F
\82ª
\95Ï
\82í
\82ç
\82È
\82¢
\82±
\82Æ
\82ª
\82 \82é
1576 ConstructMenu(true);
1579 procedure TfrmSender.actPrevChannelExecute(Sender: TObject);
1581 with tabChannel do begin
1582 if Tabs.Count = 0 then Exit;
1583 if TabIndex=0 then TabIndex := Tabs.Count-1
1584 else TabIndex := TabIndex-1;
1586 tabChannelChange(Self);
1589 procedure TfrmSender.actNextChannelExecute(Sender: TObject);
1591 with tabChannel do begin
1592 if Tabs.Count = 0 then Exit;
1593 if TabIndex=Tabs.Count-1 then TabIndex := 0
1594 else TabIndex := TabIndex+1;
1596 tabChannelChange(Self);
1599 procedure TfrmSender.UpdateJoinChannelList(Dat: THeadValue);
1603 nodat := Dat = nil; //nil
\82È
\82ç
\83`
\83\83\83\93\83l
\83\8b\91S
\89ð
\8f\9c
1604 if nodat then Dat := THeadValue.Create('');
1606 for i := 0 to Dat.Count-1 do
1607 if Dat.KeyAt[i] = 'Entry' then begin
1608 if RegExp.Match('m/^(.+?) \((\d+?)\)$/', Dat.ValueAt[i]) then
1609 JoinChannels.Add(RegExp[1]);
1611 with tabChannel do begin
1616 for i := 0 to JoinChannels.Count-1 do begin
1617 //
\8eó
\90M
\90ê
\97p
\83`
\83\83\83\93\83l
\83\8b\82Í
\95\
\8e¦
\82µ
\82È
\82¢
1618 if not ChannelList.Channel[JoinChannels[i]].NoPost then
1619 Tabs.Add(JoinChannels[i]);
1622 //
\8c³
\82©
\82ç
\83`
\83\83\83\93\83l
\83\8b\82É
\8eQ
\89Á
\82µ
\82Ä
\82¢
\82½
\8fê
\8d\87\82Í
1623 //
\91I
\91ð
\82³
\82ê
\82Ä
\82¢
\82½
\83`
\83\83\83\93\83l
\83\8b\82ª
\95Ï
\82í
\82ç
\82È
\82¢
\82æ
\82¤
\82É
\82·
\82é(
\83^
\83u
\82ª
\82¸
\82ê
\82È
\82¢
\8f\88\97\9d)
1625 for i := 0 to Tabs.Count-1 do
1626 if Tabs[i] = FNowChannel then TabIndex := i;
1627 if Tabs.Count > 0 then begin
1628 FNowChannel := Tabs[TabIndex];
1629 actSend.Hint := Format('
\81u%s
\81v
\82É
\91\97\90M|%s', [FNowChannel, SendButtonLongHint]);
1632 actSend.Hint := Format('
\91\97\90M|%s', [SendButtonLongHint]);
1634 Visible := Tabs.Count > 0;
1635 if Tabs.Count > 1 then begin
1636 actNextChannel.Enabled := true;
1637 actPrevChannel.Enabled := true;
1639 actNextChannel.Enabled := false;
1640 actPrevChannel.Enabled := false;
1642 OnChange := tabChannelChange;
1644 if nodat then Dat.Free;
1645 if JoinChannels.Count = 0 then begin
1646 Self.Caption := FOriginalCaption + ' -
\83`
\83\83\83\93\83l
\83\8b\82É
\8eQ
\89Á
\82µ
\82Ä
\82¢
\82Ü
\82¹
\82ñ';
1647 actSend.Enabled := false;
1649 Self.Caption := FOriginalCaption;
1650 actSend.Enabled := true;
1654 procedure TfrmSender.cbxTargetGhostDropDown(Sender: TObject);
1656 SakuraSeeker.BeginDetect;
1660 procedure TfrmSender.actShowLogExecute(Sender: TObject);
1663 if frmLog.WindowState = wsMinimized then frmLog.WindowState := wsNormal;
1666 procedure TfrmSender.actSleepExecute(Sender: TObject);
1668 if actSleep.Checked then begin
1669 actSleep.Checked := false;
1670 ShowHintLabel('
\83X
\83\8a\81[
\83v
\82ð
\89ð
\8f\9c\82µ
\82Ü
\82µ
\82½');
1672 actSleep.Checked := true;
1673 ShowHintLabel('
\83X
\83\8a\81[
\83v
\82ð
\90Ý
\92è
\82µ
\82Ü
\82µ
\82½');
1675 Sleeping := actSleep.Checked;
1680 procedure TfrmSender.DispatchBottle(EventType: TIdSlppEventType;
1682 var Opt: TSstpSendOptions;
1683 Event: TBottleChainBottleEvent;
1684 Script, Sender, Ghost, Channel: String;
1685 BreakFlag, NoDispatch: boolean;
1686 Sound, LogName: String;
1687 i, j, k, SkipCount: integer;
1688 Rule: TBottleChainRule;
1689 Action: TBottleChainAction;
1690 LogNameList: TStringList;
1694 if Pref.NoTranslate then Opt := Opt + [soNoTranslate];
1695 if Pref.NoDescript then Opt := Opt + [soNoDescript];
1696 Channel := Dat['Channel'];
1698 etScript: Sender := Channel;
1699 etForceBroadcast: Sender := '
\81y
\82¨
\92m
\82ç
\82¹
\81z';
1700 etUnicast: Sender := Dat['SenderUID'];
1703 //
\96Ú
\95W
\83S
\81[
\83X
\83g(
\83I
\81[
\83o
\81[
\83\89\83C
\83h
\88È
\91O)
\8c\88\92è
1704 if Dat['IfGhost'] <> '' then begin
1705 Ghost := Dat['IfGhost'];
1707 if ChannelList.Channel[Channel] <> nil then
1708 Ghost := ChannelList.Channel[Channel].Ghost;
1710 Dat['TargetGhost'] := Ghost;
1712 Event := TBottleChainBottleEvent.Create;
1715 if EventType = etScript then Event.LogType := ltBottle
1716 else Event.LogType := ltSystemLog;
1718 //
\83X
\83N
\83\8a\83v
\83g
\95Ï
\8a·
1719 Script := ScriptTransForSSTP(Dat['Script']);
1720 if Script = '' then begin
1721 frmLog.AddCurrentSystemLog('SYSTEM', '
\96â
\91è
\82Ì
\82 \82é
\89Â
\94\
\90«
\82Ì
\82 \82é
\83X
\83N
\83\8a\83v
\83g
\82ª
\93Í
\82¢
\82½
\82½
\82ß
\81A'+
1722 '
\94z
\91\97\82³
\82ê
\82Ü
\82¹
\82ñ
\82Å
\82µ
\82½
\81@
\81c '+Dat['Script']);
1727 NoDispatch := false;
1729 LogNameList := TStringList.Create;
1732 for i := 0 to BottleChainRuleList.Count-1 do begin
1733 if SkipCount > 0 then begin
1737 Rule := BottleChainRuleList[i];
1738 if not Rule.Enabled then Continue;
1739 if not Rule.Check(Event) then Continue;
1740 for j := 0 to Rule.Actions.Count-1 do begin
1741 Action := (Rule.Actions[j] as TBottleChainAction);
1742 if Action is TBottleChainAbortRuleAction then BreakFlag := true;
1743 if Action is TBottleChainSkipRuleAction then
1744 SkipCount := (Action as TBottleChainSkipRuleAction).SkipCount;
1745 if (Action is TBottleChainSoundAction) and (Sound = '') then begin
1746 Sound := (Action as TBottleChainSoundAction).SoundFile;
1747 Sound := StringReplace(Sound, '%channel%', Dat['Channel'], [rfReplaceAll]);
1748 Sound := StringReplace(Sound, '%ghost%', Dat['TargetGhost'], [rfReplaceAll]);
1750 if Action is TBottleChainNoDispatchAction then NoDispatch := true;
1751 if Action is TBottleChainLogAction then begin
1752 for k := 0 to (Action as TBottleChainLogAction).LogNames.Count-1 do begin
1753 LogName := (Action as TBottleChainLogAction).LogNames[k];
1754 LogName := StringReplace(LogName, '%channel%', Dat['Channel'], [rfReplaceAll]);
1755 LogName := StringReplace(LogName, '%ghost%', Dat['TargetGhost'], [rfReplaceAll]);
1756 LogName := StringReplace(LogName, '%date%', FormatDateTime('yy/mm/dd', Now()), [rfReplaceAll]);
1757 LogNameList.Add(LogName);
1760 if Action is TBottleChainOverrideGhostAction then begin
1761 Dat['TargetGhost'] := (Action as TBottleChainOverrideGhostAction).TargetGhost;
1763 if Action is TBottleChainQuitAction then Application.Terminate;
1765 if BreakFlag then Break;
1768 if Dat['Script'] <> '' then begin
1769 for i := 0 to LogNameList.Count-1 do
1770 frmLog.AddCurrentScriptLog(LogNameList[i], Dat['Script'], Sender, Dat['MID'], Dat['IfGhost']);
1771 if NoDispatch then begin
1772 frmLog.SetBottleState(Dat['MID'], lsOpened);
1774 Ghost := Dat['TargetGhost']; //
\83I
\81[
\83o
\81[
\83\89\83C
\83h
\82³
\82ê
\82Ä
\82¢
\82é
\89Â
\94\
\90«
\82ª
\82 \82é
1775 CueItem := TLogItem.Create(ltBottle, Dat['MID'], Dat['Channel'],
1776 Script, Ghost, Now());
1778 FBottleSstp.Push(CueItem);
1785 if Dat['DialogMessage'] <> '' then begin
1787 frmMessageBox.ShowMessage(
1788 DateTimeToStr(Now) + #13#10 +
1789 'SSTP Bottle
\83T
\81[
\83o
\82©
\82ç
\82¨
\92m
\82ç
\82¹'#13#10+Dat['DialogMessage']);
1790 for i := 0 to LogNameList.Count-1 do
1791 frmLog.AddCurrentSystemLog(LogNameList[i], Dat['DialogMessage']);
1795 if (Sound <> '') then PlaySound(Sound);
1804 procedure TfrmSender.YenETrans;
1805 var St, Le, i: integer;
1808 St := memScript.SelStart;
1809 Le := memScript.SelLength;
1810 Orig := GetScriptText;
1811 RegExp.Subst('s/(\r\n)+$//kg', Orig);
1813 with SsParser do begin
1814 LeaveEscape := true;
1815 EscapeInvalidMeta := false;
1816 InputString := Orig;
1818 for i := 0 to SsParser.Count-1 do begin
1819 if SsParser[i] <> '\e' then Text := Text + SsParser[i];
1822 Text := Text + '\e';
1824 if Orig <> Text then memScript.Lines.Text := Text;
1825 SsParser.InputString := Text;
1827 RegExp.Subst('s/\r\n//kg', Text);
1829 memScript.SelStart := St;
1830 memScript.SelLength := Le;
1833 procedure TfrmSender.PostCommand(const Command: array of String);
1834 var PostStr: TStringList;
1839 PostStr := TStringList.Create;
1840 for i := Low(Command) to High(Command) do begin
1841 PostStr.Add(Command[i]);
1843 PostCommand(PostStr);
1849 procedure TfrmSender.PostCommand(Command: TStrings);
1850 var PostStr: String;
1853 PostStr := Command.Text;
1854 PostStr := TIdURI.ParamsEncode(PostStr);
1856 FHttp := THTTPDownloadThread.Create(BottleServer, Pref.CgiName, PostStr);
1857 if Pref.UseHttpProxy then begin
1858 FHttp.ProxyServer := Pref.ProxyAddress;
1859 FHttp.ProxyPort := Pref.ProxyPort;
1861 FHttp.OnSuccess := HttpSuccess;
1862 FHttp.OnConnectionFailed := HttpFailure;
1863 FHttp.FreeOnTerminate := true; //
\8f\9f\8eè
\82É
\8e©
\95ª
\82ÅFree
\82µ
\82Ä
\82
\82¾
\82³
\82¢
1866 on EHeapException do begin
1867 Connecting := false;
1873 procedure TfrmSender.actVoteMessageExecute(Sender: TObject);
1876 if frmLog.lvwLog.Selected = nil then Exit;
1877 Log := frmLog.SelectedBottleLog[frmLog.lvwLog.Selected.Index] as TLogItem;
1878 if Log = nil then Exit;
1879 if Log.LogType <> ltBottle then Exit;
1881 'Command: voteMessage',
1883 'LUID: ' + Pref.LUID,
1889 procedure TfrmSender.actAgreeMessageExecute(Sender: TObject);
1892 if frmLog.lvwLog.Selected = nil then Exit;
1893 Log := frmLog.SelectedBottleLog[frmLog.lvwLog.Selected.Index] as TLogItem;
1894 if Log = nil then Exit;
1895 if Log.LogType <> ltBottle then Exit;
1897 'Command: voteMessage',
1899 'LUID: ' + Pref.LUID,
1905 function TfrmSender.GhostNameToSetName(const Ghost: String): String;
1907 if SakuraSeeker.ProcessByName[Ghost] <> nil then
1908 Result := SakuraSeeker.ProcessByName[Ghost].SetName
1913 procedure TfrmSender.tabChannelContextPopup(Sender: TObject;
1914 MousePos: TPoint; var Handled: Boolean);
1917 with tabChannel do begin
1918 Tag := IndexOfTabAt(MousePos.X, MousePos.Y);
1919 if Tag < 0 then Handled := true;
1924 procedure TfrmSender.PostSetChannel(Channels: TStrings);
1925 var PostStr: TStringList;
1928 PostStr := TStringList.Create;
1930 with PostStr do begin
1931 Add('Command: setChannels');
1932 Add('Agent: ' + VersionString);
1933 Add('LUID: ' + Pref.LUID);
1934 if Channels <> nil then
1935 for i := 0 to Channels.Count-1 do begin
1936 Add(Format('Ch%d: %s'#13#10, [i+1, Channels[i]]));
1939 PostCommand(PostStr);
1945 procedure TfrmSender.mnLeaveThisChannelClick(Sender: TObject);
1949 //
\8ew
\92è
\82µ
\82½
\83`
\83\83\83\93\83l
\83\8b\82©
\82ç
\94²
\82¯
\82é
1951 Ch := Tabs[Tag]; //
\94²
\82¯
\82½
\82¢
\83`
\83\83\83\93\83l
\83\8b\96¼
1952 Chs := TStringList.Create;
1954 //
\8c»
\8dÝ
\8eQ
\89Á
\92\86\82Ì
\83`
\83\83\83\93\83l
\83\8b\82©
\82ç
\81A
\94²
\82¯
\82½
\82¢
\83`
\83\83\83\93\83l
\83\8b\82ð
1955 //
\8aO
\82µ
\82½
\83\8a\83X
\83g
\82Å
\81A
\90V
\82½
\82É
\83`
\83\83\83\93\83l
\83\8b\8eQ
\89Á
\83R
\83}
\83\93\83h
\82ð
\91\97\82é
1957 Chs.Assign(JoinChannels);
1958 while Chs.IndexOf(Ch) >= 0 do
1959 Chs.Delete(Chs.IndexOf(Ch));
1960 PostSetChannel(Chs);
1966 procedure TfrmSender.mnGotoVoteClick(Sender: TObject);
1968 ShellExecute(Handle, 'open', PChar(Pref.VotePage), nil, nil, SW_SHOW);
1971 procedure TfrmSender.mnGotoGLogClick(Sender: TObject);
1973 ShellExecute(Handle, 'open', PChar(Pref.GLogPage), nil, nil, SW_SHOW);
1976 procedure TfrmSender.tabChannelMouseMove(Sender: TObject;
1977 Shift: TShiftState; X, Y: Integer);
1981 with tabChannel do begin
1982 Index := IndexOfTabAt(X, Y);
1984 Hint := Ch + ': ' + IntToStr(ChannelList.Channel[Ch].Members) + '
\90l';
1988 procedure TfrmSender.mnGoToHelpClick(Sender: TObject);
1990 ShellExecute(Handle, 'open', PChar(Pref.HelpPage), nil, nil, SW_SHOW);
1993 procedure TfrmSender.tabChannelMouseDown(Sender: TObject;
1994 Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
1997 with tabChannel do begin
1998 Index := IndexOfTabAt(X, Y);
1999 if Index = -1 then Exit; //
\83^
\83u
\82ª
\82È
\82¢
\82Ì
\82Å
\83h
\83\89\83b
\83O
\82Å
\82«
\82È
\82¢
2000 if Button = mbLeft then begin
2001 FDragTabIndex := Index; //
\83h
\83\89\83b
\83O
\82·
\82é
\83^
\83u
\82Ì
\83C
\83\93\83f
\83b
\83N
\83X
\82ð
\95Û
\91¶
2003 FDragTabDest := -1; //
\83h
\83\89\83b
\83O
\98g
\90ü
\95`
\89æ
\83t
\83\89\83O
\83N
\83\8a\83A
\82Ì
\82½
\82ß
2008 procedure TfrmSender.tabChannelDragOver(Sender, Source: TObject; X,
2009 Y: Integer; State: TDragState; var Accept: Boolean);
2010 var TargetRect: TRect;
2013 Accept := Source = tabChannel;
2014 if not Accept then Exit;
2015 with tabChannel do begin
2016 OldDest := FDragTabDest;
2017 FDragTabDest := IndexOfTabAt(X, Y);
2018 if FDragTabDest = -1 then begin
2019 Accept := false; //
\82±
\82Ì
\8fê
\8d\87\82Í
\83h
\83\8d\83b
\83v
\82ð
\94F
\82ß
\82È
\82¢
2022 with Canvas do begin
2026 if (OldDest <> FDragTabDest) and (OldDest >= 0) then begin
2027 //
\88È
\91O
\82Ì
\98g
\90ü
\8fÁ
\8b\8e
2028 TargetRect := TabRect(OldDest);
2029 with Canvas do begin
2030 Brush.Style := bsClear;
2031 Rectangle(TargetRect.Left, TargetRect.Top,
2032 TargetRect.Right, TargetRect.Bottom);
2035 if (OldDest <> FDragTabDest) then begin
2036 //
\90V
\82µ
\82¢
\98g
\90ü
\95`
\89æ
2037 TargetRect := TabRect(FDragTabDest);
2038 with Canvas do begin
2039 Brush.Style := bsClear;
2040 Rectangle(TargetRect.Left, TargetRect.Top,
2041 TargetRect.Right, TargetRect.Bottom);
2047 procedure TfrmSender.tabChannelDragDrop(Sender, Source: TObject; X,
2049 var DestIndex: integer;
2051 with tabChannel do begin
2052 DestIndex := IndexOfTabAt(X, Y);
2053 Tabs.Move(FDragTabIndex, DestIndex);
2057 procedure TfrmSender.tabChannelEndDrag(Sender, Target: TObject; X,
2060 //
\8b
\90§
\93I
\82É
\83^
\83u
\82ð
\8dÄ
\95`
\89æ
\82³
\82¹
\82é
\81B
\98g
\90ü
\8fÁ
\82µ
\91Î
\8dô
2061 tabChannel.Tabs.BeginUpdate;
2062 tabChannel.Tabs.EndUpdate;
2065 procedure TfrmSender.cbxTargetGhostDrawItem(Control: TWinControl;
2066 Index: Integer; Rect: TRect; State: TOwnerDrawState);
2067 var AlignRight: boolean;
2070 //
\83S
\81[
\83X
\83g
\91I
\91ð
\83{
\83b
\83N
\83X
\82Ì
\83I
\81[
\83i
\81[
\83h
\83\8d\81[
2071 with cbxTargetGhost do begin
2072 AlignRight := false;
2073 if Pref.HideGhosts and not FTargetGhostExpand and
2074 (Index = Items.Count-1) and (Index > 0) then
2076 //
\81u
\82·
\82×
\82Ä
\95\
\8e¦
\81v
2077 Canvas.Font.Color := clWindowText;
2078 Canvas.Font.Style := [];
2080 end else if (Index > 0) then
2082 //
\83S
\81[
\83X
\83g
\96¼
\82ð
\91I
\91ð
2083 if SakuraSeeker.ProcessByName[Items[Index]] = nil then
2084 Canvas.Font.Color := clRed //
\91¶
\8dÝ
\82µ
\82È
\82¢
\83S
\81[
\83X
\83g
2086 Canvas.Font.Color := clBlue; //
\91¶
\8dÝ
\82·
\82é
\83S
\81[
\83X
\83g
2087 Canvas.Font.Style := [fsBold];
2090 Canvas.Font.Color := clWindowText;
2091 Canvas.Font.Style := [];
2093 if odSelected in State then
2094 Canvas.Font.Color := clHighlightText;
2098 w := Canvas.TextWidth(cbxTargetGhost.Items[Index]);
2099 Canvas.TextRect(Rect, Rect.Right - w, Rect.Top,
2100 cbxTargetGhost.Items[Index]);
2102 Canvas.TextRect(Rect, Rect.Left, Rect.Top,
2103 cbxTargetGhost.Items[Index]);
2107 procedure TfrmSender.FormCloseQuery(Sender: TObject;
2108 var CanClose: Boolean);
2110 if not Pref.ConfirmOnExit then Exit;
2111 if MessageDlg('SSTP Bottle Client
\82ð
\8fI
\97¹
\82µ
\82Ü
\82·', mtConfirmation,
2112 mbOkCancel, 0) = mrCancel then CanClose := false;
2115 procedure TfrmSender.UpdateIfGhostBox;
2119 HiddenCount: integer;
2121 cbxTargetGhost.DropDownCount := Pref.GhostDropDownCount;
2122 Selected := cbxTargetGhost.Text;
2124 with cbxTargetGhost do begin
2127 Items.Add(ChannelDefault);
2128 for i := 0 to SakuraSeeker.Count-1 do begin
2129 //
\94j
\91¹FMO
\91Î
\8dô
\81BHWND
\82Ì
\92f
\95Ð
\82ª
\8ec
\82Á
\82Ä
\82¢
\82é
\82ªName
\82ª
\8fÁ
\82¦
\82Ä
\82¢
\82é
\8fê
\8d\87\82ª
\82 \82é
2130 if Length(SakuraSeeker[i].Name) = 0 then Continue;
2131 if Pref.HideGhosts and not FTargetGhostExpand then
2132 if Pref.VisibleGhostsList.IndexOf(SakuraSeeker[i].Name) < 0 then
2137 if cbxTargetGhost.Items.IndexOf(SakuraSeeker[i].Name) < 0 then
2138 cbxTargetGhost.Items.Add(SakuraSeeker[i].Name);
2140 cbxTargetGhost.ItemIndex := 0;
2141 if (Length(Selected) > 0) and (Selected <> ChannelDefault) then begin
2142 with cbxTargetGhost do begin
2143 for i := 1 to Items.Count-1 do begin
2144 if Items[i] = Selected then
2147 //
\83S
\81[
\83X
\83g
\82ª
\93Ë
\91R
\91¶
\8dÝ
\82µ
\82È
\82
\82È
\82Á
\82½
\8fê
\8d\87\91Î
\8dô
2148 if ItemIndex = 0 then begin
2149 Items.Add(Selected);
2150 ItemIndex := Items.Count - 1;
2154 if Pref.HideGhosts and not FTargetGhostExpand then
2155 Items.Add(Format('
\82·
\82×
\82Ä(%d)...', [HiddenCount]));
2160 procedure TfrmSender.HTTPFailure(Sender: TObject);
2164 ShowHintLabel('SSTP Bottle
\83T
\81[
\83o
\82Æ
\82Ì
\90Ú
\91±
\82É
\8e¸
\94s
\82µ
\82Ü
\82µ
\82½', WarningColor);
2165 ShowMessage('SSTP Bottle
\83T
\81[
\83o
\82Æ
\82Ì
\90Ú
\91±
\82É
\8e¸
\94s
\82µ
\82Ü
\82µ
\82½'#13#10 +
2166 (Sender as THTTPDownloadThread).LastErrorMessage);
2167 Connecting := false;
2170 procedure TfrmSender.actPrevGhostExecute(Sender: TObject);
2173 SakuraSeeker.BeginDetect;
2175 i := cbxTargetGhost.ItemIndex;
2179 i := cbxTargetGhost.Items.Count-1;
2180 if Pref.HideGhosts and not FTargetGhostExpand then
2183 cbxTargetGhost.ItemIndex := i;
2184 cbxTargetGhostChange(self);
2187 procedure TfrmSender.actNextGhostExecute(Sender: TObject);
2190 SakuraSeeker.BeginDetect;
2192 i := cbxTargetGhost.ItemIndex;
2194 if Pref.HideGhosts and not FTargetGhostExpand then
2196 if i > cbxTargetGhost.Items.Count-2 then i := 0;
2199 if i > cbxTargetGhost.Items.Count-1 then i := 0;
2201 cbxTargetGhost.ItemIndex := i;
2202 cbxTargetGhostChange(self);
2205 procedure TfrmSender.actResetGhostExecute(Sender: TObject);
2207 cbxTargetGhost.ItemIndex := 0; // (CH
\90\84\8f§)
\82É
\96ß
\82·
2208 FTargetGhostExpand := false;
2209 if Visible then memScript.SetFocus;
2210 cbxTargetGhostChange(self);
2213 procedure TfrmSender.timDisconnectCheckTimerTimer(Sender: TObject);
2215 if (IdSlpp20.LastReadTimeInterval > BottleServerTimeOut) then begin
2217 frmLog.AddCurrentSystemLog('SYSTEM', 'SSTP Bottle
\83T
\81[
\83o
\82Æ
\82Ì
\90Ú
\91±
\82ª
\83^
\83C
\83\80\83A
\83E
\83g
\82µ
\82Ü
\82µ
\82½');
2218 if IdSlpp20.Connected then IdSlpp20.Disconnect;
2220 if not IdSlpp20.Connected then begin
2222 Slpp20Disconnect(self); //
\82È
\82º
\82©Disconnect
\83C
\83x
\83\93\83g
\82ª
\8bN
\82±
\82ç
\82¸
\82É
\90Ø
\92f
\82µ
\82½
\8fê
\8d\87
2224 //
\90Ø
\92f
\82µ
\82½
\82Ü
\82Ü
\8dÄ
\90Ú
\91±
\82Å
\82«
\82¸
\95ú
\92u
\82³
\82ê
\82Ä
\82¢
\82é
\8fê
\8d\87\82à
\88ê
\92è
\8e\9e\8aÔ
\92u
\82«
\82É
\8dÄ
\90Ú
\91±
\83g
\83\89\83C
2225 //
\82½
\82¾
\82µ
\89ñ
\90\94\90§
\8cÀ
\82 \82è
2231 procedure TfrmSender.RetryBeginConnect;
2233 if FBeginConnectFailCount < 3 then begin
2234 //
\90Ø
\92f
\82³
\82ê
\82Ä
\82¢
\82ê
\82Î
\8dÄ
\90Ú
\91±
2235 FAutoAddAfterGetChannel := true;
2237 end else if FBeginConnectFailCount = 3 then begin
2238 frmLog.AddCurrentSystemLog('SYSTEM', '
\8dÄ
\90Ú
\91±
\8e©
\93®
\83\8a\83g
\83\89\83C
\82ð
\92\86\8e~
\82µ
\82Ü
\82·');
2239 frmMessageBox.ShowMessage(
2240 'SSTP Bottle
\83T
\81[
\83o
\82É
\90Ú
\91±
\82Å
\82«
\82Ü
\82¹
\82ñ
\81B'#13#10+
2241 '
\83l
\83b
\83g
\83\8f\81[
\83N
\82É
\90Ú
\91±
\82µ
\82Ä
\82¢
\82é
\82±
\82Æ
\82ð
\8am
\94F
\82µ
\82½
\8cã
\82Å
\81A
\83`
\83\83\83\93\83l
\83\8b\8eQ
\89Á
\83{
\83^
\83\93\82ð
\89\9f\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81B'#13#10+
2242 'SSTP Bottle
\83T
\81[
\83o
\82ª
\83_
\83E
\83\93\82µ
\82Ä
\82¢
\82é
\8fê
\8d\87\82Í
\81A
\82µ
\82Î
\82ç
\82
\82µ
\82Ä
\82©
\82ç
\8dÄ
\90Ú
\91±
\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81B'
2244 Inc(FBeginConnectFailCount);
2248 procedure TfrmSender.actDownloadLogExecute(Sender: TObject);
2249 var BottleLog: TBottleLogList;
2251 Cond: TBottleLogDownloadCondition;
2253 function TimeStr(Mins: integer): String;
2254 var day, hour, min: integer;
2256 day := Mins div (60 * 24);
2257 hour := (Mins div 60) mod 24;
2260 if day > 0 then Result := Result + Format('%d
\93ú', [day]);
2261 if hour > 0 then Result := Result + Format('%d
\8e\9e\8aÔ', [hour]);
2262 if (min > 0) or (Result = '') then Result := Result + Format('%d
\95ª', [min]);
2265 Application.CreateForm(TfrmLogDownload, frmLogDownload);
2267 if frmLogDownload.Execute then begin
2268 with frmLogDownload do begin
2269 if IsRange then begin
2270 if CompareDate(DateLo, DateHi) = 0 then
2271 Title := FormatDateTime('yy/mm/dd', DateLo)
2273 Title := FormatDateTime('yy/mm/dd', DateLo) + ' - ' + FormatdateTime('yy/mm/dd', DateHi);
2275 Title := Format('
\89ß
\8b\8e%s', [TimeStr(RecentCount)]);
2277 if Channel <> '' then Title := Title + '(' + Channel + ')';
2279 BottleLog := TBottleLogList.Create(Title);
2281 BottleLog.OnLoaded := frmLog.LogLoaded;
2282 BottleLog.OnLoadFailure := frmLog.LogLoadFailure;
2283 BottleLog.OnLoadWork := frmLog.LogLoadWork;
2284 with frmLogDownload do begin
2285 Cond.IsRange := IsRange;
2286 Cond.RecentCount := RecentCount;
2287 Cond.DateLo := DateLo;
2288 Cond.DateHi := DateHi;
2289 Cond.MinVote := MinVote;
2290 Cond.MinAgree := MinAgree;
2291 Cond.Channel := Channel;
2293 BottleLog.LoadFromWeb(Cond);
2295 FreeAndNil(BottleLog);
2297 if BottleLog <> nil then begin
2298 NewIndex := frmLog.BottleLogList.Add(BottleLog);
2300 frmLog.tabBottleLog.TabIndex := NewIndex;
2301 frmLog.UpdateWindow;
2305 frmLogDownload.Release;
2309 function TfrmSender.BuildMenuConditionCheck(const IfGhost,
2310 Ghost: String): boolean;
2317 Cond := Token(IfGhost, ',', i);
2318 if Cond <> '' then begin
2319 if Cond[1] = '!' then begin
2320 Cond := Copy(Cond, 2, High(integer));
2321 if Cond = Ghost then Result := false;
2323 if Cond <> Ghost then Result := false;
2330 procedure TfrmSender.BuildMenu(Root: TMenuItem; Simple: boolean);
2331 var i, j, k, count: integer;
2332 ConstData: TScriptConst;
2333 Menu1, Menu2: TMenuItem;
2336 // Simple = false
\82Ì
\8fê
\8d\87\82Í
\83\81\83j
\83\85\81[
\82ð
\8a®
\91S
\82É
\8dÄ
\8d\
\92z
\82·
\82é
\81B
2337 // Simple = true
\82Ì
\8fê
\8d\87\82Í
\83S
\81[
\83X
\83g
\8aÖ
\8cW
\82Ì
\82Ý
\8dÄ
\8d\
\92z
\82·
\82é
\82Ì
\82Å
\8d\82\91¬
\81B
2338 if cbxTargetGhost.ItemIndex > 0 then Ghost := cbxTargetGhost.Text
2339 else if FNowChannel <> '' then Ghost := ChannelList.Channel[FNowChannel].Ghost;
2341 //
\8aù
\91¶
\82Ì
\83\81\83j
\83\85\81[
\8dí
\8f\9c
2342 if Simple then begin
2343 // IfGhost
\8fð
\8c\8f\95t
\82«
\83\81\83j
\83\85\81[
\82Ì
\82Ý
\8dí
\8f\9c
2344 for i := Root.Count-1 downto 0 do begin
2345 if ScriptConstList.GetMenuByID(Root.Items[i].Tag).IfGhost <> '' then
2349 //
\91S
\95\94\8dí
\8f\9c
2350 for i := Root.Count-1 downto 0 do begin
2356 for i := 0 to ScriptConstList.Count-1 do begin
2357 for j := 0 to ScriptConstList[i].Count-1 do begin
2358 //
\83S
\81[
\83X
\83g
\88á
\82¢
\82Ì
\8fê
\8d\87\82Í
\83X
\83L
\83b
\83v
2359 if not BuildMenuConditionCheck(ScriptConstList[i][j].IfGhost, Ghost) then Continue;
2361 // Simple
\82Ì
\8fê
\8d\87\82Í
\8aù
\82É
\8aY
\93\96\83\81\83j
\83\85\81[
\82ª
\91¶
\8dÝ
\82·
\82é
\82±
\82Æ
\82ª
\82 \82é
\82Ì
\82Å
\83X
\83L
\83b
\83v
2362 if Simple and (count < Root.Count) then
2363 if (Root.Items[count].Tag = ScriptConstList[i][j].ID) then begin
2367 Menu1 := TMenuItem.Create(Root);
2368 Menu1.Caption := ScriptConstList[i][j].Caption;
2369 Menu1.Hint := ScriptConstList[i][j].Caption;
2370 Menu1.AutoHotkeys := maManual;
2371 Menu1.Tag := ScriptConstList[i][j].ID;
2372 Menu1.OnClick := mnConstGroupClick;
2374 if not Simple then begin
2377 if count < Root.Count-1 then
2378 Root.Insert(count, Menu1)
2383 Menu1.Enabled := ScriptConstList[i][j].Count > 0;
2384 for k := 0 to ScriptConstList[i][j].Count-1 do begin
2385 ConstData := ScriptConstList[i][j][k];
2386 Menu2 := TMenuItem.Create(Root);
2387 Menu2.Caption := ConstData.Caption;
2388 Menu2.Hint := ConstData.ConstText;
2389 // if ConstData.ShortCut <> 0 then Menu2.Hint := Menu2.Hint
2390 // + ' (' + ShortCutToText(ConstData.ShortCut) + ')';
2391 //
\83T
\81[
\83t
\83B
\83X
\83v
\83\8c\83r
\83\85\81[
\8eÀ
\8c»
\82Ì
\82½
\82ß
\8fã
\8dí
\8f\9c
2392 Menu2.ShortCut := ConstData.ShortCut;
2393 Menu2.OnClick := mnConstClick;
2394 Menu2.AutoHotkeys := maManual;
2395 Menu2.Tag := ConstData.ID;
2396 if (k mod 15 = 0) and (k > 0) then Menu2.Break := mbBarBreak;
2403 procedure TfrmSender.cbxTargetGhostChange(Sender: TObject);
2405 //
\81u
\82·
\82×
\82Ä
\95\
\8e¦
\81v
\82ð
\91I
\91ð
\82³
\82ê
\82½
\8fê
\8d\87\82Í
\83S
\81[
\83X
\83g
\91I
\91ð
\83{
\83b
\83N
\83X
\82ð
\8dÄ
\8d\
\92z
2406 if Pref.HideGhosts and not FTargetGhostExpand then
2408 with cbxTargetGhost do
2410 //
\88ê
\94Ô
\89º
\82Ì
\83A
\83C
\83e
\83\80\82ª
\91I
\91ð
\82³
\82ê
\82½
\82Æ
\82«
\81B
2411 //
\82½
\82¾
\82µItemIndex=0
\82Ì
\8fê
\8d\87(
\83S
\81[
\83X
\83g
\82ª
\8bN
\93®
\82µ
\82Ä
\82¢
\82È
\82¢
\8fê
\8d\87)
\82Í
\97á
\8aO
2412 if (ItemIndex = Items.Count-1) and (ItemIndex > 0) then
2414 FTargetGhostExpand := true;
2417 DroppedDown := true;
2421 //
\92è
\8c^
\8bå
\83\81\83j
\83\85\81[
\82ð
\8dÄ
\8d\
\92z
2422 ConstructMenu(true);
2423 //
\83v
\83\8c\83r
\83\85\81[
\82ª
\82 \82é
\8fê
\8d\87\82Í
\83v
\83\8c\83r
\83\85\81[
2427 procedure TfrmSender.PlaySound(const FileName: String);
2429 if Pref.SilentWhenHidden and not Application.ShowMainForm then Exit;
2431 MediaPlayer.FileName := FileName;
2435 on E: EMCIDeviceError do begin
2436 ShowMessage('
\83T
\83E
\83\93\83h
\8dÄ
\90¶
\83G
\83\89\81[:'#13#10 + FileName + #13#10#13#10 + E.Message);
2441 procedure TfrmSender.actFMOExplorerExecute(Sender: TObject);
2444 if not Assigned(frmFMOExplorer) then
2445 Application.CreateForm(TfrmFMOExplorer, frmFMOExplorer);
2448 ShowMessage('FMO
\83G
\83N
\83X
\83v
\83\8d\81[
\83\89\82ð
\95\
\8e¦
\82Å
\82«
\82Ü
\82¹
\82ñ
\81B'#13#10#13#10 +
2451 frmFMOExplorer.Show;
2454 procedure TfrmSender.SaveChainRuleList;
2455 var Str: TStringList;
2457 Str := TStringList.Create;
2459 Str.Text := ComponentToString(BottleChainRuleList);
2460 Str.SaveToFile(ExtractFileDir(Application.ExeName)+'\rule.txt');
2466 procedure TfrmSender.BottleSstpResendEnd(Sender: TObject; MID: String);
2468 frmLog.SetBottleState(MID, lsOpened);
2471 procedure TfrmSender.BottleSstpResendTrying(Sender: TObject; MID: String);
2473 frmLog.SetBottleState(MID, lsPlaying);
2476 procedure TfrmSender.actInsertCueExecute(Sender: TObject);
2477 var InsertItem: TLogItem;
2478 i, errCount: integer;
2479 Log: TBottleLogList;
2481 if FBottleSstp.CueCount > 0 then begin
2482 if MessageDlg(Format('
\8c»
\8dÝ
\8dÄ
\91\97\83L
\83\85\81[
\82É
\93ü
\82Á
\82Ä
\82¢
\82é%d
\8c\8f\82Ì
\96¢
\94z
\91\97\83{
\83g
\83\8b\82ð
\83N
\83\8a\83A
\82µ
\82Ä
\81A'+
2483 '
\83\8d\83O
\83E
\83B
\83\93\83h
\83E
\82É
\82 \82é
\83{
\83g
\83\8b\82ð
\98A
\91±
\8dÄ
\90¶
\82µ
\82Ü
\82·
\81B'#13#10+
2484 '
\90V
\92\85\83\81\83b
\83Z
\81[
\83W
\82Í
\82»
\82Ì
\8cã
\82É
\8dÄ
\90¶
\82³
\82ê
\82Ü
\82·
\81B', [FBottleSstp.CueCount]),
2485 mtWarning, mbOkCancel, 0) = mrCancel then Exit;
2488 frmLog.AllBottleOpened;
2489 if frmLog.lvwLog.Selected = nil then Exit;
2490 Log := frmLog.SelectedBottleLog;
2491 if Log = nil then Exit;
2492 FBottleSSTP.OnResendCountChange := nil;
2494 for i := frmLog.lvwLog.Selected.Index downto 0 do begin
2495 if (Log[i] as TLogItem).LogType <> ltBottle then Continue;
2496 InsertItem := TLogItem.Create(Log[i] as TLogItem);
2498 InsertItem.Script := ScriptTransForSSTP(InsertItem.Script);
2499 if InsertItem.Script = '' then begin
2500 raise Exception.Create('Script syntax error');
2502 if InsertItem.Ghost = '' then begin
2503 if ChannelList.Channel[InsertItem.Channel] <> nil then
2504 InsertItem.Ghost := ChannelList.Channel[InsertItem.Channel].Ghost;
2506 FBottleSSTP.Push(InsertItem);
2507 frmLog.SetBottleState(InsertItem.MID, lsUnopened);
2513 if errCount > 0 then
2514 ShowMessage(Format('%d
\8c\8f\82Ì
\83{
\83g
\83\8b\82É
\96â
\91è
\82ª
\82 \82Á
\82½
\82½
\82ß
\8dÄ
\90¶
\82Å
\82«
\82Ü
\82¹
\82ñ
\81B', [errCount]));
2515 FBottleSSTP.OnResendCountChange := BottleSstpResendCountChange;
2516 BottleSstpResendCountChange(self);
2519 function TfrmSender.ScriptTransForSSTP(const Script: String): String;
2522 Result := ScriptTransForSSTP(Script, dum);
2525 function TfrmSender.ScriptTransForSSTP(const Script: String;
2526 out Error: String): String;
2527 var TransOpt: TScriptTransOptions;
2530 if Pref.NoTransURL then
2531 TransOpt := [toConvertURL, toNoChoice, toWaitScriptEnd]
2533 TransOpt := [toConvertURL, toWaitScriptEnd];
2534 if Pref.IgnoreFrequentYenS then TransOpt := TransOpt + [toIgnoreFrequentYenS];
2535 if Pref.FixMessySurface then TransOpt := TransOpt + [toFixMessySurface];
2536 if Pref.HUTagTo01Tag then TransOpt := TransOpt + [toHUTagTo01Tag];
2538 Err := DoTrans(Result, TransOpt);
2539 if Length(Err) > 0 then begin
2545 procedure TfrmSender.FormResize(Sender: TObject);
2548 //
\83G
\83f
\83B
\83^
\81[
\95\94\95ª
\82Ì
\83\8f\81[
\83h
\83\89\83b
\83v
\95\9d\82ð
\92²
\90®
\82·
\82é
2549 if memScript.ColWidth <> 0 then
2553 w := Width - LeftMargin - ColWidth div 2;
2554 if ScrollBars in [ssVertical, ssBoth] then
2555 w := w - GetSystemMetrics(SM_CYVSCROLL);
2556 WrapOption.WrapByte := w div ColWidth;
2561 procedure TfrmSender.actCopyExecute(Sender: TObject);
2563 memScript.CopyToClipboard;
2566 procedure TfrmSender.actPasteExecute(Sender: TObject);
2568 memScript.PasteFromClipboard;
2571 procedure TfrmSender.actCutExecute(Sender: TObject);
2573 memScript.CutToClipboard;
2576 procedure TfrmSender.actSelectAllExecute(Sender: TObject);
2578 memScript.SelectAll;
2581 function TfrmSender.IsSurfaceTag(const Script: String;
2582 var ID: integer): boolean;
2585 if SsParser.Match(Script, '\s%d') = 3 then
2588 ID := Ord(Script[3]) - Ord('0')
2590 else if (Length(Script) > 0) and (SsParser.Match(Script, '\s[%D]') = Length(Script)) then
2593 ID := StrToIntDef(SsParser.GetParam(Script, 1), 0);
2597 procedure TfrmSender.memScriptMouseMove(Sender: TObject;
2598 Shift: TShiftState; X, Y: Integer);
2602 //
\95Ò
\8fW
\83E
\83B
\83\93\83h
\83E
\82Å
\83}
\83E
\83X
\83|
\83C
\83\93\83g
\82·
\82é
\82Æ
\83T
\81[
\83t
\83B
\83X
\83v
\83\8c\83r
\83\85\81[
2603 if not Pref.SurfacePreviewOnScriptPoint then
2605 token := memScript.TokenStringFromPos(Point(X, Y));
2606 if IsSurfaceTag(token, id) then
2608 DoSurfacePreview(id, spEditor);
2611 frmSurfacePreview.HideAway;
2615 procedure TfrmSender.DoSurfacePreview(Surface: integer;
2616 const Kind: TSurfacePreviewType);
2621 if cbxTargetGhost.ItemIndex > 0 then
2622 ghost := cbxTargetGhost.Text
2623 else if FNowChannel <> '' then
2624 ghost := ChannelList.Channel[FNowChannel].Ghost;
2626 //
\93ñ
\8fd
\95\
\8e¦
\82Ì
\97}
\90§
2627 if (FVisiblePreviewGhost = Ghost) and (FVisiblePreviewSurface = Surface) and
2628 not (frmSurfacePreview.IsHidden) then
2635 Bmp := TBitmap.Create;
2637 if Spps.TryGetImage(ghost, Surface, Bmp) then
2641 CPos := GetSurfacePreviewPositionHint(Bmp.Width, Bmp.Height);
2643 CPos := GetSurfacePreviewPositionScriptPoint(Bmp.Width, Bmp.Height);
2645 CPos := Point(0, 0);
2647 frmSurfacePreview.ShowPreview(Bmp, CPos.X, CPos.Y);
2648 FVisiblePreviewGhost := Ghost;
2649 FVisiblePreviewSurface := Surface;
2651 frmSurfacePreview.HideAway;
2658 function TfrmSender.GetSurfacePreviewPositionHint(w, h: integer): TPoint;
2659 {var MousePoint: TPoint;
2662 //
\83T
\81[
\83t
\83B
\83X
\83v
\83\8c\83r
\83\85\81[
\83E
\83B
\83\93\83h
\83E
\82Ì
\95\
\8e¦
\88Ê
\92u
\82ð
\8c\88\92è
\82·
\82é
2663 //
\91\97\90M
\83E
\83B
\83\93\83h
\83E
\82Ì
\88Ê
\92u
\82É
\82æ
\82Á
\82Ä
\82Í
\96
\82È
\82Æ
\82±
\82ë
\82É
\83\81\83j
\83\85\81[
\82ª
\95\
\8e¦
\82³
\82ê
\82Ä
\82¢
\82é
\82Ì
\82Å
2664 //
\88Ä
\8aO
\82â
\82â
\82±
\82µ
\82¢
2665 {GetCursorPos(MousePoint);
2666 OutputDebugString(PChar(IntToStr(FVisibleMenuItem.Count)));
2667 //if GetMenuItemRect(Self.Handle, FVisibleMenuItem.Items[0].Handle, 1, MenuRect) then ;
2668 Result := Point(MenuRect.Left-10, MenuRect.Top-10);}
2669 Result := GetSurfacePreviewPositionScriptPoint(w, h);
2672 function TfrmSender.GetSurfacePreviewPositionScriptPoint(w, h: integer): TPoint;
2673 var MousePoint: TPoint;
2675 GetCursorPos(MousePoint);
2676 case Pref.SurfacePreviewOnScriptPointPosition of
2677 spspMainWindowRight:
2678 Result := Point(Self.Left + Self.Width, MousePoint.Y);
2680 Result := Point(Self.Left - w, MousePoint.Y);
2684 procedure TfrmSender.mnConstGroupClick(Sender: TObject);
2686 if (Sender is TMenuItem) then
2687 FVisibleMenuItem := Sender as TMenuItem;
2690 procedure TfrmSender.actRecallScriptBufferExecute(Sender: TObject);
2692 if FScriptBuffer.Count = 0 then
2694 memScript.Lines.Assign(FScriptBuffer[0] as TStringList);
2695 memScriptChange(Self);
2696 ShowHintLabel('
\83X
\83N
\83\8a\83v
\83g
\82ð
\8cÄ
\82Ñ
\8fo
\82µ
\82Ü
\82µ
\82½');
2699 procedure TfrmSender.EditorPreview;
2700 var Ghost, Script: String;
2702 if frmEditorTalkShow <> nil then
2703 if frmEditorTalkShow.Visible then
2705 Script := StringReplace(GetScriptText, #13#10, '', [rfReplaceAll]);
2707 if cbxTargetGhost.ItemIndex > 0 then
2708 Ghost := cbxTargetGhost.Text
2709 else if FNowChannel <> '' then
2710 Ghost := ChannelList.Channel[FNowChannel].Ghost;
2711 frmEditorTalkShow.TalkShowFrame.View(Script, Ghost);
2715 procedure TfrmSender.actEditorPreviewExecute(Sender: TObject);
2717 if frmEditorTalkShow <> nil then
2718 frmEditorTalkShow.Show
2721 Application.CreateForm(TfrmEditorTalkShow, frmEditorTalkShow);
2722 frmEditorTalkShow.Show;
2727 //
\83v
\83\89\83O
\83C
\83\93\83\8a\83Z
\83b
\83g
2728 procedure TfrmSender.actResetPluginsExecute(Sender: TObject);
2730 Spps.ClearImagePool;
2731 Spps.LoadFromDirectory(FSppDir);
2734 procedure TfrmSender.IdSLPP20Connect(Sender: TObject);
2736 ShowHintLabel('SSTP Bottle
\83T
\81[
\83o
\82ª
\8c©
\82Â
\82©
\82è
\82Ü
\82µ
\82½');
2739 //
\83X
\83N
\83\8a\83v
\83g
\92\86\82Ì
\83^
\83O
\82ð
\92u
\8a·
\82·
\82é
2740 //
\83T
\83C
\83Y
\89Â
\95Ï
\82Ì
\94z
\97ñ
\83p
\83\89\83\81\81[
\83^
\94Å
2741 function TfrmSender.TagReplace(Script: String; Before,
2742 After: array of String): String;
2743 var BeforeList, AfterList: TStringList;
2746 BeforeList := TStringList.Create;
2747 AfterList := TStringList.Create;
2749 for i := Low(Before) to High(Before) do
2750 BeforeList.Add(Before[i]);
2751 for i := Low(After) to High(After) do
2752 AfterList.Add(After[i]);
2753 Result := TagReplace(Script, BeforeList, AfterList);
2760 //
\83X
\83N
\83\8a\83v
\83g
\92\86\82Ì
\83^
\83O
\82ð
\92u
\8a·
\82·
\82é
2761 // StringReplace
\82Æ
\88á
\82Á
\82Ä
\90³
\8am
\82É
\83^
\83O
\82É
\83}
\83b
\83`
\82µ
\81A
2762 //
\82Ü
\82½
\83p
\83^
\81[
\83\93\82ð
\95¡
\90\94\8ew
\92è
\82Å
\82«
\82é(
\92u
\8a·
\8cã
\82Ì
\8c\8b\89Ê
\82ª
\82Ü
\82½
\92u
\8a·
\82³
\82ê
\82½
\82è
\82µ
\82È
\82¢)
2763 function TfrmSender.TagReplace(Script: String; Before,
2764 After: TStrings): String;
2766 Flag, OldLeaveEscape, OldEscapeInvalidMeta: boolean;
2772 OldStr := InputString;
2773 OldLeaveEscape := LeaveEscape;
2774 OldEscapeInvalidMeta := EscapeInvalidMeta;
2775 LeaveEscape := true;
2776 EscapeInvalidMeta := false;
2777 InputString := Script;
2779 for i := 0 to SsParser.Count-1 do
2782 for j := 0 to Before.Count-1 do
2784 if (SsParser.MarkUpType[i] = mtTag) and (SsParser[i] = Before[j]) then
2787 Result := Result + After[j];
2791 Result := Result + SsParser[i];
2795 LeaveEscape := OldLeaveEscape;
2796 EscapeInvalidMeta := OldEscapeInvalidMeta;
2797 InputString := OldStr;
2801 // WndProc
\82ð
\83I
\81[
\83o
\81[
\83\89\83C
\83h
\82µ
\82Ä
\81AFWM_TaskBarCraeted
\82É
2802 //
\91Î
\89\9e\82·
\82é
2803 procedure TfrmSender.WndProc(var Message: TMessage);
2805 if (Message.Msg = FWM_TaskBarCreated) and (FWM_TaskBarCreated <> 0) then
2807 TaskTray.Registered := false; // TTaskTray
\82É
\83^
\83X
\83N
\83g
\83\8c\83C
\82ª
\8fÁ
\82¦
\82½
\82±
\82Æ
\82ð
2808 //
\8bC
\82Ã
\82©
\82¹
\82é
2815 //
\8c\9f\8dõ
\81E
\92u
\8a·
\83_
\83C
\83A
\83\8d\83O
\82ð
\8f\89\8aú
\89»
\82µ
\82Ä
\95\
\8e¦
2816 procedure TfrmSender.actReplaceExecute(Sender: TObject);
2818 with ReplaceDialog do
2826 //
\8c\9f\8dõ
\81E
\92u
\8a·
2827 procedure TfrmSender.ReplaceDialogFind(Sender: TObject);
2828 var Opt: TSearchOptions;
2831 if frMatchCase in ReplaceDialog.Options then
2832 Opt := Opt + [sfrMatchCase];
2833 if frWholeWord in ReplaceDialog.Options then
2834 Opt := Opt + [sfrWholeWord];
2835 memScript.Search(ReplaceDialog.FindText, Opt);
2838 //
\8c\9f\8dõ
\81E
\92u
\8a·
2839 procedure TfrmSender.ReplaceDialogReplace(Sender: TObject);
2840 var Opt: TSearchOptions;
2843 if frMatchCase in ReplaceDialog.Options then
2844 Opt := Opt + [sfrMatchCase];
2845 if frWholeWord in ReplaceDialog.Options then
2846 Opt := Opt + [sfrWholeWord];
2847 if frReplaceAll in ReplaceDialog.Options then
2848 while memScript.Search(ReplaceDialog.FindText, Opt) do
2849 memScript.SelText := ReplaceDialog.ReplaceText
2852 if memScript.Search(ReplaceDialog.FindText, Opt) then
2853 memScript.SelText := ReplaceDialog.ReplaceText