6 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
7 Menus, StdCtrls, ComCtrls, BRegExp, BottleDef, BottleSstp,
8 DirectSstp, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
9 IdSLPP20, SsParser, ImgList, AppEvnts, TaskTray, StdActns,
10 ActnList, MPlayer, MenuBar, ToolWin,
11 IniFiles, ExtCtrls, ShellAPI, Contnrs,
12 ConstEditor, Buttons, Clipbrd, HeadValue, Logs,
13 IdException, HttpThread, IdHTTP, IdURI, LogDownload,
14 ScriptConsts, DateUtils, BottleChainRule, BottleChainEvent,
15 SakuraSeekerInstance, HEditor, heClasses, heFountain,
16 SakuraScriptFountain, SppTypes, SppList, SurfacePreview;
19 TSurfacePreviewType = (spHint, spEditor);
21 TfrmSender = class(TForm)
25 mnRegister: TMenuItem;
28 StatusBar: TStatusBar;
31 mnEditConst: TMenuItem;
32 ActionList: TActionList;
34 mnPopPaste: TMenuItem;
37 mnPopSelectAll: TMenuItem;
39 mnPopConst: TMenuItem;
44 mnSelectAll: TMenuItem;
46 ApplicationEvents: TApplicationEvents;
47 mnPopUpTaskTray: TPopupMenu;
48 mnTaskStart: TMenuItem;
50 mnTaskRestore: TMenuItem;
51 mnTaskNewMessage: TMenuItem;
55 mnTaskExit: TMenuItem;
64 mnPopupConst: TPopupMenu;
65 actEditConst: TAction;
67 mnShowToolBar: TMenuItem;
68 mnShowConstBar: TMenuItem;
69 ConstBarMenu: TMainMenu;
71 tbtnClear: TToolButton;
72 tbtnConfirm: TToolButton;
73 tbtnSend: TToolButton;
74 tbtnSeparator: TToolButton;
75 tbtnStart: TToolButton;
76 tbtnSeparator2: TToolButton;
77 tbtnInsertConst: TToolButton;
78 ConstMenuBar: TMenuBar;
81 mnColorScript: TMenuItem;
84 actCopyAllNoReturn: TAction;
85 mnCopyAllNoReturn: TMenuItem;
86 mnPopCopyAll: TMenuItem;
87 mnPopCopyAllNoReturn: TMenuItem;
89 tbtnSetting: TToolButton;
90 mnStayOnTop: TMenuItem;
92 actExitClient: TAction;
94 tbtnEditConst: TToolButton;
95 actClearBottles: TAction;
96 mnClearBottles: TMenuItem;
97 MediaPlayer: TMediaPlayer;
98 mnGetNewId: TMenuItem;
99 actNextChannel: TAction;
100 actPrevChannel: TAction;
102 mnNextChannel: TMenuItem;
103 mnPrevChannel: TMenuItem;
106 tbtnShowLog: TToolButton;
107 tbtnSleep: TToolButton;
111 mnTaskSleep: TMenuItem;
113 tabChannel: TTabControl;
116 cbxTargetGhost: TComboBox;
117 actVoteMessage: TAction;
118 mnPopUpChannelTab: TPopupMenu;
119 mnLeaveThisChannel: TMenuItem;
121 mnGotoVote: TMenuItem;
122 mnGotoGLog: TMenuItem;
123 mnGoToHelp: TMenuItem;
127 mnExitAllChannels: TMenuItem;
128 actAgreeMessage: TAction;
131 actPrevGhost: TAction;
132 actNextGhost: TAction;
133 mnPrevGhost: TMenuItem;
134 mnNextGhost: TMenuItem;
135 actResetGhost: TAction;
136 mnResetGhost: TMenuItem;
137 timDisconnectCheckTimer: TTimer;
138 DirectSstp: TDirectSstp;
139 actDownloadLog: TAction;
140 actFMOExplorer: TAction;
141 tbtnFMOExplorer: TToolButton;
142 mnFMOExplorer: TMenuItem;
144 actInsertCue: TAction;
145 SakuraScriptFountain: TSakuraScriptFountain;
150 actSelectAll: TAction;
151 actEditCopy: TEditCopy;
152 actRecallScriptBuffer: TAction;
154 mnRecallScriptBuffer: TMenuItem;
155 tbtnEditorPreview: TToolButton;
156 actEditorPreview: TAction;
157 mnEditorPreview: TMenuItem;
158 actResetPlugins: TAction;
160 mnResetPlugins: TMenuItem;
161 procedure actConfirmExecute(Sender: TObject);
162 procedure FormCreate(Sender: TObject);
163 procedure FormDestroy(Sender: TObject);
164 procedure actSendExecute(Sender: TObject);
165 procedure HTTPSuccess(Sender: TObject);
166 procedure HTTPFailure(Sender: TObject);
167 procedure actStartClick(Sender: TObject);
168 procedure actStopExecute(Sender: TObject);
169 procedure FormShow(Sender: TObject);
170 procedure mnAboutClick(Sender: TObject);
171 procedure actExitClientExecute(Sender: TObject);
172 procedure actClearExecute(Sender: TObject);
173 procedure memScriptChange(Sender: TObject);
174 procedure mnStayOnTopClick(Sender: TObject);
175 procedure actEditConstExecute(Sender: TObject);
176 procedure mnTaskBarClick(Sender: TObject);
177 procedure FormClose(Sender: TObject; var Action: TCloseAction);
178 procedure ApplicationEventsMinimize(Sender: TObject);
179 procedure ApplicationEventsRestore(Sender: TObject);
180 procedure mnTaskRestoreClick(Sender: TObject);
181 procedure TaskTrayDblClick(Seft: TObject; Button: TMouseButton);
182 procedure FormActivate(Sender: TObject);
183 procedure mnTaskNewMessageClick(Sender: TObject);
184 procedure ApplicationEventsHint(Sender: TObject);
185 procedure memScriptKeyDown(Sender: TObject; var Key: Word;
187 procedure mnShowToolBarClick(Sender: TObject);
188 procedure mnShowConstBarClick(Sender: TObject);
189 procedure mnGoToHPClick(Sender: TObject);
190 procedure LabelTimerTimer(Sender: TObject);
191 procedure actCopyAllExecute(Sender: TObject);
192 procedure actCopyAllNoReturnExecute(Sender: TObject);
193 procedure Slpp20SlppEvent(Sender: TObject; EventType: TIdSlppEventType;
194 const Param: String);
195 procedure actSettingExecute(Sender: TObject);
196 procedure memScriptKeyPress(Sender: TObject; var Key: Char);
197 procedure Slpp20Disconnect(Sender: TObject);
198 procedure actClearBottlesExecute(Sender: TObject);
199 procedure SakuraSeekerDetectResultChanged(Sender: TObject);
200 procedure mnGetNewIdClick(Sender: TObject);
201 procedure tabChannelChange(Sender: TObject);
202 procedure actPrevChannelExecute(Sender: TObject);
203 procedure actNextChannelExecute(Sender: TObject);
204 procedure cbxTargetGhostDropDown(Sender: TObject);
205 procedure actShowLogExecute(Sender: TObject);
206 procedure actSleepExecute(Sender: TObject);
207 procedure actVoteMessageExecute(Sender: TObject);
208 procedure tabChannelContextPopup(Sender: TObject; MousePos: TPoint;
209 var Handled: Boolean);
210 procedure mnLeaveThisChannelClick(Sender: TObject);
211 procedure mnGotoVoteClick(Sender: TObject);
212 procedure mnGotoGLogClick(Sender: TObject);
213 procedure tabChannelMouseMove(Sender: TObject; Shift: TShiftState; X,
215 procedure mnGoToHelpClick(Sender: TObject);
216 procedure tabChannelMouseDown(Sender: TObject; Button: TMouseButton;
217 Shift: TShiftState; X, Y: Integer);
218 procedure tabChannelDragOver(Sender, Source: TObject; X, Y: Integer;
219 State: TDragState; var Accept: Boolean);
220 procedure tabChannelDragDrop(Sender, Source: TObject; X, Y: Integer);
221 procedure tabChannelEndDrag(Sender, Target: TObject; X, Y: Integer);
222 procedure cbxTargetGhostDrawItem(Control: TWinControl; Index: Integer;
223 Rect: TRect; State: TOwnerDrawState);
224 procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
225 procedure actAgreeMessageExecute(Sender: TObject);
226 procedure actPrevGhostExecute(Sender: TObject);
227 procedure actNextGhostExecute(Sender: TObject);
228 procedure actResetGhostExecute(Sender: TObject);
229 procedure timDisconnectCheckTimerTimer(Sender: TObject);
230 procedure actDownloadLogExecute(Sender: TObject);
231 procedure cbxTargetGhostChange(Sender: TObject);
232 procedure actFMOExplorerExecute(Sender: TObject);
233 procedure actInsertCueExecute(Sender: TObject);
234 procedure FormResize(Sender: TObject);
235 procedure actCopyExecute(Sender: TObject);
236 procedure actPasteExecute(Sender: TObject);
237 procedure actCutExecute(Sender: TObject);
238 procedure actSelectAllExecute(Sender: TObject);
239 procedure memScriptMouseMove(Sender: TObject; Shift: TShiftState; X,
241 procedure actRecallScriptBufferExecute(Sender: TObject);
242 procedure actEditorPreviewExecute(Sender: TObject);
243 procedure actResetPluginsExecute(Sender: TObject);
244 procedure IdSLPP20Connect(Sender: TObject);
248 FConnecting: boolean;
250 FBooted: boolean; //
\8f\89\89ñ
\8bN
\93®
\92Ê
\90M
\97p
251 FOriginalCaption: String;
252 FAutoAddAfterGetChannel: boolean;
256 FMutex: THandle; //Mutex
\83I
\83u
\83W
\83F
\83N
\83g
\81c
\93ñ
\8fd
\8bN
\93®
\96h
\8e~
\97p
258 FNowChannel: String; //
\8c»
\8dÝ
\91I
\91ð
\82³
\82ê
\82Ä
\82¢
\82é
\83`
\83\83\83\93\83l
\83\8b
259 JoinChannelsBackup: TStringList; //
261 FScriptModified: boolean; //
\83X
\83N
\83\8a\83v
\83g
\82ª
\95Ï
\8dX
\82³
\82ê
\82Ä
\82¢
\82é
\82©
\82Ç
\82¤
\82©
\81B
262 //
\83\8d\81[
\83J
\83\8b\8am
\94F
\8b
\90§
\97p
\83t
\83\89\83O
\81BTRichEdit.Modified
\82Í
263 //
\95Ê
\82Ì
\97p
\93r
\82Å
\8eg
\82Á
\82Ä
\82¢
\82é
\82Ì
\82Å
\8eg
\82¦
\82È
\82¢
265 FDragTabIndex: integer; //
\83^
\83u
\83h
\83\89\83b
\83O
\83h
\83\8d\83b
\83v
\8aÖ
\98A
266 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)
268 FBottleSstp: TBottleSstp; //
\83X
\83\8c\83b
\83h
\94Å
\8dÄ
\91\97\83v
\83\8d\83O
\83\89\83\80
270 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Ý)
271 FBeginConnectFailCount: integer; //
\89½
\93x
\82à
\90Ú
\91±
\8e¸
\94s
\82µ
\82½
\82ç
\83\8a\83g
\83\89\83C
\92\86\8e~
273 FVisiblePreviewGhost: String;
274 FVisiblePreviewSurface: integer; //
\83T
\81[
\83t
\83B
\83X
\83v
\83\8c\83r
\83\85\81[
\82Å
\8c©
\82¦
\82Ä
\82¢
\82é
\82à
\82Ì
275 FVisibleMenuItem: TMenuItem; //
\83N
\83\8a\83b
\83N
\82³
\82ê
\82½
\83\81\83j
\83\85\81[
\83A
\83C
\83e
\83\80\81B
276 //
\83T
\81[
\83t
\83B
\83X
\83v
\83\8c\83r
\83\85\81[
\82ª
\83\81\83j
\83\85\81[
\82Ì
\89º
\82É
277 //
\89B
\82ê
\82È
\82¢
\82æ
\82¤
\82É
\95\
\8e¦
\82³
\82ê
\82Ä
\82¢
\82é
\82à
\82Ì
\82ð
\8bL
\89¯
\82µ
\82Ä
\82¨
\82
279 FTargetGhostExpand: boolean; //
\83S
\81[
\83X
\83g
\91I
\91ð
\83{
\83b
\83N
\83X
\82ª
\81A
280 //
\88ê
\8e\9e\93I
\82É
\91S
\95\94\95\
\8e¦
\82³
\82ê
\82Ä
\82¢
\82é
\82©
\82Ç
\82¤
\82©
\82Ì
\83t
\83\89\83O
282 FScriptBuffer: TObjectList; //
\83X
\83N
\83\8a\83v
\83g
\83N
\83\8a\83A
\83o
\83b
\83t
\83@
284 FLastGhostList: String; //
\83S
\81[
\83X
\83g
\83\8a\83X
\83g
\82Ì
\95¶
\8e\9a\97ñ
285 FLastGhostListSend: Int64; //
\8d\91\90¨
\92²
\8d¸
\82ð
\8dÅ
\8cã
\82É
\91\97\90M
\82µ
\82½
\8e\9e\8d\8f
287 procedure SetStatusText(const Value: String);
288 procedure SetSleeping(const Value: boolean);
290 procedure SetConnecting(const Value: boolean);
291 procedure SetAdded(const Value: boolean);
292 procedure mnConstClick(Sender: TObject);
293 procedure mnConstGroupClick(Sender: TObject);
294 property Added: boolean read FAdded write SetAdded;
295 property Sleeping: boolean read FSleeping write SetSleeping;
296 property StatusText: String read FStatusText write SetStatusText;
297 function GetScriptText: String;
298 procedure ChangeTaskIcon;
299 procedure ShowHintLabel(const Mes: String; Col: TColor = clBlue);
300 procedure UpdateLayout;
301 procedure DispatchBottle(EventType: TIdSlppEventType; Dat: THeadValue);
302 //
\83`
\83\83\83\93\83l
\83\8b\8aÖ
\8cW
303 procedure UpdateChannelInfo(Dat: THeadValue);
304 procedure UpdateJoinChannelList(Dat: THeadValue);
305 procedure NoLuidError;
306 procedure UpdateIfGhostBox;
307 function BuildMenuConditionCheck(const IfGhost, Ghost: String): boolean;
308 procedure BuildMenu(Root: TMenuItem; Simple: boolean);
309 procedure PlaySound(const FileName: String);
310 //TBottleSstp
\8aÖ
\8cW
\83C
\83x
\83\93\83g
\83n
\83\93\83h
\83\89
311 procedure BottleSstpResendCountChange(Sender: TObject);
312 procedure BottleSstpResendTrying(Sender: TObject; MID: String);
313 procedure BottleSstpResendEnd(Sender: TObject; MID: String);
314 function IsSurfaceTag(const Script: String; var ID: integer): boolean;
315 procedure DoSurfacePreview(Surface: integer; const Kind:
316 TSurfacePreviewType);
317 function GetSurfacePreviewPositionHint(w, h: integer): TPoint;
318 function GetSurfacePreviewPositionScriptPoint(w, h: integer): TPoint;
319 procedure EditorPreview;
320 //
\83^
\83O
\82Ì
\95¶
\8e\9a\97ñ
\82ð
\95Ï
\8a·
\82·
\82é
321 function TagReplace(Script: String;
322 Before, After: array of String): String; overload;
323 function TagReplace(Script: String;
324 Before, After: TStrings): String; overload;
326 function DoTrans(var Script: String;
327 Options: TScriptTransOptions): String; overload;
328 function DoTrans(var Script: String;
329 Options: TScriptTransOptions; out FoundURL: boolean): String; overload;
330 function ScriptTransForSSTP(const Script: String): String; overload;
331 function ScriptTransForSSTP(const Script: String;
332 out Error: String): String; overload;
333 procedure BeginConnect;
334 procedure RetryBeginConnect;
335 procedure EndConnect;
336 procedure ConstructMenu(Simple: boolean);
337 property Connecting: boolean read FConnecting write SetConnecting;
338 property BottleSstp: TBottleSstp read FBottleSstp;
339 function SetHWndToFavoriteGhost(const Ghost: String): String;
340 function GhostNameToSetName(const Ghost: String): String;
341 procedure PostCommand(const Command: array of String); overload;
342 procedure PostCommand(Command: TStrings); overload;
343 procedure PostSetChannel(Channels: TStrings);
344 procedure SaveChainRuleList;
349 frmSender: TfrmSender;
352 PanelConnecting = 0; //
\81u
\90Ú
\91±
\92\86\81v
\95\
\8e¦
\97p
353 PanelBytes = 1; //
\81\9b\81\9b\83o
\83C
\83g
354 PanelCount = 2; //Local Proxy
\81A
\8c»
\8dÝ
\81\9b\8c\8f\91Ò
\82¿
356 PanelStatus = 4; //SSTP Bottle
\83T
\81[
\83o
\82É
\93o
\98^
\82³
\82ê
\82Ä
\82¢
\82Ü
\82·
\81c
\82È
\82Ç
359 IconDisconnected = 18;
361 IconSleepDisconnected = 20;
363 WarningColor = clRed;
365 SendButtonLongHint = 'Bottle
\82Ì
\91\97\90M';
367 function Token(const Str: String; const Delimiter: char;
368 const Index: integer): String;
372 uses SendConfirm, SettingForm, ChannelListForm, LogForm,
373 MessageBox, FMOExplorer, EditorTalkShow;
377 //
\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
378 function Token(const Str: String; const Delimiter: char;
379 const Index: integer): String;
380 var i, c, len: integer;
386 while i <= len do begin
387 if (Str[i] = Delimiter) and (StrByteType(PChar(Str), i) <> mbTrailByte) then begin
389 if c > Index then Break;
390 end else if c = Index then Result := Result + Str[i];
397 procedure TfrmSender.actConfirmExecute(Sender: TObject);
398 var AScript, Err, AGhost: String;
401 AScript := GetScriptText;
402 if Length(AScript) = 0 then Exit;
404 AScript := ScriptTransForSSTP(AScript, Err);
411 if cbxTargetGhost.ItemIndex > 0 then
412 AGhost := cbxTargetGhost.Text
413 else if FNowChannel <> '' then
414 AGhost := ChannelList.Channel[FNowChannel].Ghost
418 if Pref.IgnoreTimeCritical then
419 AScript := TagReplace(AScript, ['\t'], ['']);
421 Item := TLogItem.Create;
427 Channel := '
\81y
\8am
\94F
\81z';
430 BottleSstp.Unshift(Item);
435 FScriptModified := false;
438 procedure TfrmSender.FormCreate(Sender: TObject);
439 var Str: TStringList;
441 FScriptBuffer := TObjectList.Create(true);
443 SakuraSeeker.OnDetectResultChanged := SakuraSeekerDetectResultChanged;
444 FConstDir := ExtractFileDir(Application.ExeName)+'\consts';
445 ScriptConstList.LoadFromDir(FConstDir);
446 FSppDir := ExtractFileDir(Application.ExeName)+'\spp';
447 Spps.LoadFromDirectory(FSppDir);
448 ConstructMenu(false);
450 Str := TStringList.Create;
453 Str.LoadFromFile(ExtractFilePath(Application.ExeName)+'rule.txt');
454 BottleChainRuleList := StringToComponent(Str.Text) as TBottleChainRuleList;
457 Str.LoadFromFile(ExtractFilePath(Application.ExeName)+'defrule.txt');
458 BottleChainRuleList := StringToComponent(Str.Text) as TBottleChainRuleList;
460 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');
461 Application.Terminate;
462 Application.ProcessMessages;
470 FOriginalCaption := Self.Caption;
473 ShowMessage('
\93ñ
\8fd
\8bN
\93®
\8b\96\89Â
\83o
\81[
\83W
\83\87\83\93\82Å
\82·
\81B'#13#10 + VersionString);
475 FMutex := CreateMutex(nil, true, 'SSTPBottleClient2');
476 if GetLastError = ERROR_ALREADY_EXISTS then begin
478 ShowMessage('SSTP Bottle Client
\82Í
\93ñ
\8fd
\8bN
\93®
\82Å
\82«
\82Ü
\82¹
\82ñ');
480 Application.Terminate;
481 Application.ProcessMessages; //WM_QUIT
\82ð
\97¬
\82·
487 mnShowToolBar.Checked := Pref.ShowToolBar;
488 mnShowConstBar.Checked := Pref.ShowConstBar;
489 if Pref.StayOnTop then begin
490 FormStyle := fsStayOnTop;
491 mnStayOnTop.Checked := true;
493 FormStyle := fsNormal;
494 mnStayOnTop.Checked := false;
497 mnGoToHP.Hint := Pref.HomePage;
498 mnGotoGlog.Hint := Pref.GLogPage;
499 mnGotoVote.Hint := Pref.VotePage;
500 mnGotoHelp.Hint := Pref.HelpPage;
502 mnGetNewId.Enabled := (Pref.LUID = '');
505 SsParser.TagPattern.LoadFromFile(ExtractFilePath(Application.Exename) + 'tagpat.txt');
506 SsParser.MetaPattern.LoadFromFile(ExtractFilePath(Application.ExeName) + 'metapat.txt');
508 ShowMessage('tagpat.txt, metapat.txt
\82ª
\8c©
\82Â
\82©
\82è
\82Ü
\82¹
\82ñ
\81B');
509 Application.Terminate;
512 with Pref.SenderWindowPosition do begin
515 Self.Width := Right - Left + 1;
516 Self.Height := Bottom - Top + 1;
519 actClearExecute(Sender);
521 UpdateJoinChannelList(nil);
523 // SSTP
\8dÄ
\91\97\83I
\83u
\83W
\83F
\83N
\83g
524 FBottleSstp := TBottleSstp.Create(false);
525 with FBottleSstp do begin
526 OnResendCountChange := BottleSstpResendCountChange;
527 OnResendTrying := BottleSstpResendTrying;
528 OnResendEnd := BottleSstpResendEnd;
532 procedure TfrmSender.FormDestroy(Sender: TObject);
534 if FScriptBuffer <> nil then
537 if FBottleSstp <> nil then begin
538 FBottleSstp.Terminate;
542 with Pref.SenderWindowPosition do begin
545 Right := Self.Left + Self.Width - 1;
546 Bottom := Self.Top + Self.Height - 1;
549 if JoinChannelsBackup <> nil then JoinChannelsBackup.Free;
551 ScriptConstList.Save;
554 BottleChainRuleList.Free;
557 ReleaseMutex(FMutex);
562 procedure TfrmSender.SetConnecting(const Value: boolean);
564 FConnecting := Value;
566 StatusBar.Panels[PanelConnecting].Text := '
\92Ê
\90M
\92\86';
567 actStart.Enabled := false;
568 actStop.Enabled := false;
569 actSend.Enabled := false;
570 actVoteMessage.Enabled := false;
571 actAgreeMessage.Enabled := false;
572 mnGetNewId.Enabled := false;
573 Screen.Cursor := crAppStart;
575 StatusBar.Panels[PanelConnecting].Text := '';
576 actStart.Enabled := true;
577 actStop.Enabled := true;
578 actSend.Enabled := true;
579 //actVoteMessage.Enabled := true;
580 //actAgreeMessage.Enabled := true;
581 frmLog.lvwLogChange(Self, nil, ctState);
582 mnGetNewId.Enabled := Pref.LUID = '';
583 Screen.Cursor := crDefault;
587 procedure TfrmSender.actSendExecute(Sender: TObject);
588 var Talk, Ghost: String;
589 Command: TStringList;
593 if Length(GetScriptText) = 0 then begin
594 ShowMessage('
\83X
\83N
\83\8a\83v
\83g
\82ª
\8bó
\82Å
\82·
\81B');
598 if Pref.LUID = '' then begin
602 if tabChannel.TabIndex < 0 then begin
603 ShowMessage('
\83`
\83\83\83\93\83l
\83\8b\82É
\8eQ
\89Á
\82µ
\82Ä
\82¢
\82Ü
\82¹
\82ñ
\81B'#13#10+
604 '
\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');
607 if ChannelList.Channel[FNowChannel].NoPost then begin
609 ShowMessage(FNowChannel + '
\82Í
\8eó
\90M
\90ê
\97p
\82Å
\82·');
613 if Pref.NeedConfirmBeforeSend and FScriptModified then begin
614 MessageDlg('
\91\97\90M
\91O
\82É
\83\8d\81[
\83J
\83\8b\8am
\94F
\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81B', mtError, [mbOk], 0);
618 if not Pref.NoConfirm then begin
619 if not SendConfirmDialog(FNowChannel, cbxTargetGhost.Text) then Exit;
623 Talk := GetScriptText;
624 Err := DoTrans(Talk, [toWarnMessySurface, toWarnCheck]);
625 if Err <> '' then begin
626 MessageDlg(Err, mtWarning, [mbOk], 0);
631 if cbxTargetGhost.ItemIndex > 0 then Ghost := cbxTargetGhost.Text;
633 Command := TStringList.Create;
634 with Command do begin
635 Add('Command: sendBroadcast');
636 Add('Channel: ' + FNowChannel);
637 Add('LUID: ' + Pref.LUID);
638 Add('Agent: ' + VersionString);
639 if Ghost <> '' then Add('Ghost: ' + Ghost);
640 Add('Talk: ' + Talk);
642 PostCommand(Command);
647 //
\91\97\90M
\83\8d\83O
\95Û
\91¶
648 AssignFile(F, ExtractFilePath(Application.ExeName) + SentLogFile);
649 if FileExists(ExtractFilePath(Application.ExeName) + SentLogFile) then
653 WriteLn(F, Format('%s,%s,%s,%s', [FNowChannel, Ghost, FormatDateTime('yy/mm/dd hh:nn:ss', Now), Talk]));
658 procedure TfrmSender.BeginConnect;
660 if Pref.LUID = '' then begin
664 IdSlpp20.LUID := Pref.LUID;
665 self.Cursor := crHourGlass;
667 if IdSlpp20.Connected then IdSlpp20.Disconnect;
668 if Pref.UseHttpProxy then begin
669 IdSlpp20.Host := Pref.ProxyAddress;
670 IdSlpp20.Port := Pref.ProxyPort;
671 IdSlpp20.ProxyMode := true;
673 IdSlpp20.Host := 'bottle.mikage.to';
674 IdSlpp20.Port := 9871;
675 IdSlpp20.ProxyMode := false;
679 on EIdException do begin
681 if FBeginConnectFailCount = 0 then begin
682 Inc(FBeginConnectFailCount);
684 if Pref.UseHttpProxy then
685 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 +
686 '
\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 +
687 '
\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')
689 ShowMessage('SSTP Bottle
\83T
\81[
\83o
\82É
\90Ú
\91±
\82Å
\82«
\82Ü
\82¹
\82ñ
\82Å
\82µ
\82½
\81B'#13#10 +
690 '
\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 +
691 '
\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');
693 Inc(FBeginConnectFailCount);
696 self.Cursor := crDefault;
699 procedure TfrmSender.EndConnect;
701 IdSlpp20.OnDisconnect := nil;
705 procedure TfrmSender.SetAdded(const Value: boolean);
707 if FAdded = Value then Exit;
710 StatusText := 'SSTP Bottle
\83T
\81[
\83o
\82É
\90Ú
\91±
\82³
\82ê
\82Ä
\82¢
\82Ü
\82·';
713 StatusText := '
\83T
\81[
\83o
\82Æ
\82Ì
\90Ú
\91±
\82ª
\90Ø
\82ê
\82Ä
\82¢
\82Ü
\82·!';
715 ShowHintLabel('SSTP Bottle
\83T
\81[
\83o
\82©
\82ç
\90Ø
\92f
\82³
\82ê
\82Ü
\82µ
\82½!', WarningColor);
719 procedure TfrmSender.HTTPSuccess(Sender: TObject);
720 var Str, ResStr, Command: String;
721 HeadValue: THeadValue;
723 SetChannel: TStringList;
726 Str := (Sender as THttpDownloadThread).RecvString;
730 HeadValue := THeadValue.Create(Str);
732 ShowMessage('SSTP Bottle
\83T
\81[
\83o
\82ª
\89ð
\90Í
\82Å
\82«
\82È
\82¢
\83G
\83\89\81[
\82ð
\95Ô
\82µ
\82Ü
\82µ
\82½
\81B');
735 Command := HeadValue['Command'];
736 ResStr := HeadValue['Result'];
737 if ResStr = 'Err' then begin
738 if HeadValue['ExtraMessage'] <> '' then begin
740 ShowMessage('SSTP Bottle
\83T
\81[
\83o
\82ª
\8e\9f\82Ì
\83G
\83\89\81[
\82ð
\95Ô
\82µ
\82Ü
\82µ
\82½:'#13#10 +
741 HeadValue['ExtraMessage']);
744 ShowMessage('SSTP Bottle
\83T
\81[
\83o
\82ª
\89½
\82ç
\82©
\82Ì
\83G
\83\89\81[
\82ð
\95Ô
\82µ
\82Ü
\82µ
\82½
\81B');
747 if (Command = 'sendBroadcast') and (ResStr = 'OK') then begin
748 ShowHintLabel(HeadValue['Channel'] + '
\82Ì ' + HeadValue['SentNum'] +
749 '
\90l
\82É
\91\97\90M
\82µ
\82Ü
\82µ
\82½');
750 //
\83S
\81[
\83X
\83g
\82ð
\83f
\83t
\83H
\83\8b\83g
\82É
\96ß
\82·
751 if Pref.ResetIfGhostAfterSend then begin
752 actResetGhostExecute(Self);
754 //
\83X
\83N
\83\8a\83v
\83g
\82ð
\83N
\83\8a\83A
755 if Pref.ClearAfterSend then begin
758 end else if (Command = 'sendBroadcast') and (ResStr <> 'OK') then begin
759 ShowHintLabel('
\83\81\83b
\83Z
\81[
\83W
\82ð
\91\97\90M
\82Å
\82«
\82Ü
\82¹
\82ñ
\82Å
\82µ
\82½', WarningColor);
761 if (Command = 'getNewId') then begin
762 if ResStr = 'OK' then begin
763 Pref.LUID := HeadValue['NewID'];
764 ShowHintLabel('LUID
\8eæ
\93¾
\8a®
\97¹
\81B');
765 mnGetNewId.Enabled := false;
768 ShowHintLabel('LUID
\8eæ
\93¾
\82É
\8e¸
\94s
\82µ
\82Ü
\82µ
\82½');
771 if (Command = 'voteMessage') then begin
772 if ResStr = 'OK' then begin
773 ShowHintLabel('
\83\81\83b
\83Z
\81[
\83W
\82É
\93\8a\95[/
\93¯
\88Ó
\82µ
\82Ü
\82µ
\82½
\81B
\95[
\90\94: ' + HeadValue['Votes']);
776 if (Command = 'getChannels') and (ResStr = 'OK') then begin
777 UpdateChannelInfo(HeadValue);
780 if FAutoAddAfterGetChannel then begin
781 SetChannel := TStringList.Create;
782 if JoinChannelsBackup <> nil then begin
783 //
\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
784 SetChannel.Assign(JoinChannelsBackup);
786 //
\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¾
787 for i := 0 to Pref.AutoJoinChannels.Count-1 do begin
788 if ChannelList.Channel[Pref.AutoJoinChannels[i]] <> nil then
789 SetChannel.Add(Pref.AutoJoinChannels[i]);
793 if frmChannelList.Execute(ChannelList, JoinChannels) then begin
794 SetChannel := TStringList.Create;
795 SetChannel.Assign(frmChannelList.JoinList);
798 if SetChannel <> nil then PostSetChannel(SetChannel);
800 if SetChannel <> nil then FreeAndNil(SetChannel);
803 if (Command = 'setChannels') then begin
804 if ResStr <> 'OK' then begin
806 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¢');
807 ShowHintLabel('
\83`
\83\83\83\93\83l
\83\8b\90Ý
\92è
\82É
\8e¸
\94s
\82µ
\82Ü
\82µ
\82½', WarningColor);
810 if HeadValue['ExtraTip'] <> '' then ShowHintLabel(HeadValue['ExtraTip']);
816 procedure TfrmSender.actStartClick(Sender: TObject);
818 if Pref.LUID = '' then begin
822 if not IdSlpp20.Connected then begin
823 FBeginConnectFailCount := 0; //
\8e©
\93®
\8dÄ
\90Ú
\91±
\83J
\83E
\83\93\83^
\83\8a\83Z
\83b
\83g
827 FAutoAddAfterGetChannel := false;
828 PostCommand(['Command: getChannels']);
832 procedure TfrmSender.actStopExecute(Sender: TObject);
834 //
\8b
\90§
\8dÄ
\90Ú
\91±
\82ð
\8ds
\82¤
835 IdSlpp20.OnDisconnect := nil;
836 if IdSlpp20.Connected then IdSlpp20.Disconnect;
837 FAutoAddAfterGetChannel := true;
839 IdSlpp20.OnDisconnect := Slpp20Disconnect;
842 procedure TfrmSender.FormShow(Sender: TObject);
844 if FBooted or Application.Terminated then Exit;
845 //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
846 if Pref.LUID <> '' then BeginConnect
847 else mnGetNewIdClick(Self);
848 FAutoAddAfterGetChannel := Pref.AutoStart;
851 frmSurfacePreview.Show;
853 SakuraSeekerDetectResultChanged(Self);
856 procedure TfrmSender.mnAboutClick(Sender: TObject);
859 Str := VersionString + #13#10 + BottleDisclaimer + #13#10#13#10;
860 Str := Str + Format('Compiler Version: %f', [CompilerVersion]);
861 frmMessageBox.ShowMessage(Str);
864 procedure TfrmSender.actExitClientExecute(Sender: TObject);
869 procedure TfrmSender.actClearExecute(Sender: TObject);
870 var TmpScript: String;
872 DoSaveBuffer: boolean;
873 SavedScript: TStringList;
875 //
\83X
\83N
\83\8a\83v
\83g
\82Ì
\83N
\83\8a\83A
876 //
\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é
877 DoSaveBuffer := false;
878 if FScriptBuffer.Count = 0 then
880 else if (FScriptBuffer[0] as TStringList).Text <> GetScriptText then
881 DoSaveBuffer := true;
882 if (GetScriptText = Pref.DefaultScript) or (GetScriptText = '') then
883 DoSaveBuffer := false;
886 SavedScript := TStringList.Create;
887 SavedScript.Text := GetScriptText;
888 FScriptBuffer.Insert(0, SavedScript);
890 if FScriptBuffer.Count >= 4 then
891 FScriptBuffer.Delete(FScriptBuffer.Count-1);
892 actRecallScriptBuffer.Enabled := FScriptBuffer.Count > 0;
894 TmpScript := Pref.DefaultScript;
895 Position := Pos('|', TmpScript);
896 if Position < 1 then Position := 1;
897 TmpScript := StringReplace(TmpScript, '|', '', []);
898 memScript.Lines.Text := TmpScript;
899 Sendmessage(memScript.Handle, WM_VSCROLL, SB_LINEUP, 0);
900 memScript.SelStart := Position-1;
902 if Visible then memScript.SetFocus;
903 FScriptModified := false;
904 memScriptChange(self);
907 procedure TfrmSender.memScriptChange(Sender: TObject);
910 Script := StringReplace(GetScriptText, #13#10, '', [rfReplaceAll]);
911 StatusBar.Panels[PanelBytes].Text := IntToStr(length(Script)) + '
\83o
\83C
\83g';
912 FScriptModified := true;
916 procedure TfrmSender.mnStayOnTopClick(Sender: TObject);
918 Pref.StayOnTop := not Pref.StayOnTop;
919 mnStayOnTop.Checked := Pref.StayOnTop;
920 if Pref.StayOnTop then begin
921 FormStyle := fsStayOnTop;
923 FormStyle := fsNormal;
928 function TfrmSender.GetScriptText: String;
930 Result := memScript.Lines.Text;
933 procedure TfrmSender.mnConstClick(Sender: TObject);
936 i := (Sender as TMenuItem).Tag;
937 memScript.SelText := ScriptConstList.GetConstByID(i).ConstText;
940 procedure TfrmSender.actEditConstExecute(Sender: TObject);
942 ScriptConstList.LoadFromDir(FConstDir);
944 Application.CreateForm(TfrmConstEditor, frmConstEditor);
945 frmConstEditor.Execute;
946 ScriptConstList.Save;
948 frmConstEditor.Release;
950 ConstructMenu(false);
953 procedure TfrmSender.mnTaskBarClick(Sender: TObject);
955 Application.Minimize;
956 WindowState := wsNormal;
959 procedure TfrmSender.FormClose(Sender: TObject; var Action: TCloseAction);
962 TaskTray.Registered := false;
965 procedure TfrmSender.ApplicationEventsMinimize(Sender: TObject);
968 Application.ShowMainForm := false;
969 ShowWindow(Application.Handle, SW_HIDE);
972 procedure TfrmSender.ApplicationEventsRestore(Sender: TObject);
974 Application.ShowMainForm := true;
978 procedure TfrmSender.mnTaskRestoreClick(Sender: TObject);
983 procedure TfrmSender.TaskTrayDblClick(Seft: TObject; Button: TMouseButton);
988 procedure TfrmSender.FormActivate(Sender: TObject);
993 procedure TfrmSender.mnTaskNewMessageClick(Sender: TObject);
996 actClearExecute(Sender);
999 procedure TfrmSender.ChangeTaskIcon;
1004 if Sleeping then IcoNum := IconSleep else IcoNum := IconConnected;
1006 if Sleeping then IcoNum := IconSleepDisconnected
1007 else IcoNum := IconDisconnected;
1010 Ico := TIcon.Create;
1012 imgIcon.GetIcon(IcoNum, Ico);
1013 TaskTray.Icon := Ico;
1014 TaskTray.Registered := true;
1019 ; // 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
1020 //
\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
1021 //
\82»
\82Ì
\8fê
\8d\87\82Í
\83G
\83\89\81[
\82ð
\96³
\8e\8b\82·
\82é
1025 procedure TfrmSender.SetStatusText(const Value: String);
1027 FStatusText := Value;
1028 StatusBar.Panels[PanelStatus].Text := Value;
1031 procedure TfrmSender.ApplicationEventsHint(Sender: TObject);
1034 if Length(Application.Hint) > 0 then
1036 StatusBar.Panels[PanelStatus].Text := GetLongHint(Application.Hint);
1037 Application.HintColor := clInfoBk;
1038 if (Application.Hint = SendButtonLongHint)
1039 and (FNowChannel <> '') then
1041 //
\91\97\90M
\83{
\83^
\83\93\82Ì
\8fê
\8d\87\82Í
\91¬
\8dU
\8fo
\82·
1042 Application.HintColor := clYellow;
1043 Application.ActivateHint(Mouse.CursorPos);
1045 if IsSurfaceTag(Application.Hint, id) and Pref.SurfacePreviewOnHint then
1047 //
\83T
\81[
\83t
\83B
\83X
\83v
\83\8c\83r
\83\85\81[
1048 DoSurfacePreview(id, spHint);
1052 StatusBar.Panels[PanelStatus].Text := FStatusText;
1053 frmSurfacePreview.HideAway;
1057 procedure TfrmSender.ConstructMenu(Simple: boolean);
1059 BuildMenu(mnPopConst, Simple);
1060 BuildMenu(mnPopUpConst.Items, Simple);
1061 BuildMenu(ConstBarMenu.Items, Simple);
1062 //ConstMenuBar.Menu := nil;
1063 ConstMenuBar.AutoSize := false;
1064 ConstMenuBar.Width := 1000;
1065 ConstMenuBar.Menu := ConstBarMenu;
1066 ConstMenuBar.AutoSize := true;
1069 procedure TfrmSender.memScriptKeyDown(Sender: TObject; var Key: Word;
1070 Shift: TShiftState);
1072 Func: TReturnKeyFunction;
1074 if (Key = VK_RETURN) then begin
1075 if (ssShift in Shift) then
1076 Func := Pref.WhenShiftReturn
1077 else if (ssCtrl in Shift) then
1078 Func := Pref.WhenCtrlReturn
1080 Func := Pref.WhenReturn;
1083 with tbtnInsertConst do
1084 Pos := tbtnInsertConst.ClientToScreen(Point(0, Height));
1085 mnPopUpConst.Popup(Pos.X, Pos.Y);
1088 memScript.SelText := '\n';
1092 memScript.SelText := '\n'#13#10;
1095 memScript.SelText := #13#10
1101 procedure TfrmSender.mnShowToolBarClick(Sender: TObject);
1103 mnShowToolBar.Checked := not mnShowToolBar.Checked;
1104 Pref.ShowToolBar := mnShowToolBar.Checked;
1108 procedure TfrmSender.mnShowConstBarClick(Sender: TObject);
1110 mnShowConstBar.Checked := not mnShowConstBar.Checked;
1111 Pref.ShowConstBar := mnShowConstBar.Checked;
1115 procedure TfrmSender.UpdateLayout;
1117 with SakuraScriptFountain do begin
1118 TagColor.Color := Pref.MarkUpColor;
1119 TagErrorColor.Color := Pref.MarkErrorColor;
1120 Scope0Color.Color := Pref.TalkColorH;
1121 Scope1Color.Color := Pref.TalkColorU;
1122 SynchronizedColor.Color := Pref.TalkColorS;
1124 memScript.Ruler.Visible := Pref.ShowRuler;
1125 memScript.Ruler.Color := Pref.TalkColorH;
1126 memScript.Color := Pref.BgColor;
1128 ToolBar.Visible := Pref.ShowToolBar;
1129 ConstMenuBar.Visible := Pref.ShowConstBar;
1132 with tabChannel do begin
1133 TabPosition := Pref.TabPosition;
1134 case Pref.TabPosition of
1135 tpTop: Align := alTop;
1136 tpBottom: Align := alBottom;
1141 function TfrmSender.DoTrans(var Script: String;
1142 Options: TScriptTransOptions; out FoundURL: boolean): String;
1143 var UrlCancel, Mark: String;
1144 Url, UrlName: array[0..6] of String;
1145 i, j, u, UrlCount: integer;
1146 LastSurfaceH, LastSurfaceU: integer;
1147 UnyuTalking: boolean;
1148 QuickSection, Synchronize: boolean;
1149 Warnings: TStringList;
1154 UnyuTalking := false;
1155 QuickSection := false;
1156 Synchronize := false;
1157 SsParser.LeaveEscape := true;
1158 SsParser.EscapeInvalidMeta := false;
1159 SsParser.InputString := Script;
1161 Warnings := TStringList.Create;
1163 for i := 0 to SsParser.Count-1 do begin
1164 if SsParser[i] = '\t' then begin
1165 if not(toIgnoreTimeCritical in Options) then
1166 Script := Script + '\t';
1167 end else if SsParser[i] = '\e' then begin
1169 end else if (SsParser.Match(SsParser[i], '\URL%b') > 0) then begin
1170 if toConvertURL in Options then begin
1171 UrlCount := 0; //
\91O
\82ÌURL
\83^
\83O
\82Ì
\89e
\8b¿
\82ð
\96³
\8e\8b\81B
1172 for u := 7 downto 1 do begin
1173 if (SsParser.Match(SsParser[i],
1174 '\URL%b'+StringReplace(StringOfChar('-', u*2),
1175 '-', '%b', [rfReplaceAll]))) > 0 then begin
1176 for j := 1 to u do begin
1177 Url[UrlCount] := SsParser.GetParam(SsParser[i], UrlCount*2+2);
1178 UrlName[UrlCount] := SsParser.GetParam(SsParser[i], UrlCount*2+3);
1179 if UrlName[UrlCount] = '' then UrlName[UrlCount] := Url[UrlCount];
1180 if Pos('http://', Url[UrlCount]) > 0 then Inc(UrlCount);
1183 if UrlCount > 0 then UrlCancel := SsParser.GetParam(SsParser[i], 1);
1184 if UrlCancel = '' then UrlCancel := '
\8ds
\82©
\82È
\82¢
\81@
\81@
\81@
\81@';
1186 if SsParser.Match(SsParser[i], '\URL%b%b') = 0 then begin //
\8aÈ
\88Õ
\94ÅURL
\95Ï
\8a·
1187 //
\8aÈ
\88Õ
\8c`
\8e®\URL
\83^
\83O
\95Ï
\8a·
1188 Url[0] := SsParser.GetParam(SsParser[i], 1);
1189 UrlName[0] := '
\8ds
\82
\81@
\81@
\81@
\81@
\81@
\81@';
1190 UrlCancel := '
\8ds
\82©
\82È
\82¢
\81@
\81@
\81@
\81@';
1191 if Pos('http://', Url[0]) > 0 then begin
1193 if not QuickSection then
1194 Script := Script + '\_q' + Url[0] + '\_q'
1196 Script := Script + Url[0];
1199 end else Script := Script + SsParser[i];
1201 Mark := SsParser[i];
1202 if Mark = '\h' then begin
1203 UnyuTalking := false;
1204 if toHUTagTo01Tag in Options then Mark := '\0';
1205 if Synchronize and Pref.WarnScopeChangeInSynchronize then
1206 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');
1207 end else if Mark = '\u' then begin
1208 UnyuTalking := true;
1209 if toHUTagTo01Tag in Options then Mark := '\1';
1210 if Synchronize and Pref.WarnScopeChangeInSynchronize then
1211 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');
1212 end else if Mark = '\_q' then begin
1213 QuickSection := not QuickSection;
1214 end else if Mark = '\_s' then begin
1215 Synchronize := not Synchronize;
1216 end else if SsParser.Match(Mark, '\s%b') > 0 then begin
1217 if UnyuTalking then begin
1218 LastSurfaceU := StrToIntDef(SsParser.GetParam(Mark, 1),
1221 LastSurfaceH := StrToIntDef(SsParser.GetParam(Mark, 1),
1224 end else if SsParser.Match(Mark, '\s%d') > 0 then begin
1225 if UnyuTalking then begin
1226 LastSurfaceU := StrToIntDef(Mark[3], LastSurfaceU);
1228 LastSurfaceH := StrToIntDef(Mark[3], LastSurfaceH);
1231 Script := Script + Mark;
1234 if UrlCount > 0 then begin
1236 Script := Script + '\h\n';
1237 if not (toNoChoice in Options) then begin
1238 for i := 0 to UrlCount-1 do begin
1239 Script := Script + Format('\q%d[%s][%s]',
1240 [i, SsParser.EscapeParam(Url[i]), UrlName[i]]);
1242 Script := Script + Format('\q%d[#cancel][%s]', [UrlCount, UrlCancel]);
1243 //Script := Script + '\z'; //
\8dÅ
\90Vphase
\82Å
\82Í
\8dí
\8f\9c
1245 Script := Script + '\h';
1246 for i := 0 to UrlCount-1 do begin
1247 Script := Script + Format('\n{%s}(%s)', [UrlName[i], Url[i]]);
1248 Script := Script + Format('\n{%s}', [UrlCancel]);
1253 //
\83X
\83N
\83\8a\83v
\83g
\82Ì
\8dÅ
\8cã
\82É
\83E
\83F
\83C
\83g
\91}
\93ü
1254 if toWaitScriptEnd in Options then begin
1255 i := Pref.WaitScriptEnd;
1256 while i > 0 do begin
1258 Script := Script + '\w9';
1261 Script := Script + '\w' + IntToStr(i);
1267 Script := Script + '\e';
1268 RegExp.Subst('s/\r\n//gk', Script);
1270 //
\83^
\83O
\83`
\83F
\83b
\83N
\8aÖ
\98A
1271 for i := 0 to SsParser.Count-1 do begin
1272 if SsParser.MarkUpType[i] = mtTagErr then begin
1273 Result := '"' + SsParser[i] + '"'#13#10 +
1274 '
\82Í
\81ASSTP Bottle
\82Å
\94F
\82ß
\82ç
\82ê
\82È
\82¢
\82©
\81A
\94F
\8e¯
\82Å
\82«
\82È
\82¢
\83^
\83O
\82Å
\82·
\81B';
1278 if (SsParser[0] <> '\t') and Pref.WarnYenTNotExist then begin
1279 Warnings.Add('
\83X
\83N
\83\8a\83v
\83g
\82ª\t
\82©
\82ç
\8en
\82Ü
\82Á
\82Ä
\82¢
\82Ü
\82¹
\82ñ
\81B');
1283 if (Warnings.Count > 0) and (toWarnCheck in Options) then begin
1284 if MessageDlg(Warnings.Text + #13#10 + '
\91\97\90M
\82µ
\82Ü
\82·
\82©?', mtWarning,
1285 mbOkCancel, 0) = mrCancel then
1286 Result := Warnings.Text;
1293 function TfrmSender.DoTrans(var Script: String;
1294 Options: TScriptTransOptions): String;
1297 Result := DoTrans(Script, Options, dum);
1300 procedure TfrmSender.mnGoToHPClick(Sender: TObject);
1302 ShellExecute(Handle, 'open', PChar(Pref.HomePage), nil, nil, SW_SHOW);
1305 procedure TfrmSender.ShowHintLabel(const Mes: String; Col: TColor);
1307 lblMessage.Caption := Mes;
1308 lblMessage.Font.Color := Col;
1309 lblMessage.Visible := true;
1310 LabelTimer.Enabled := false;
1311 LabelTimer.Enabled := true;
1314 procedure TfrmSender.LabelTimerTimer(Sender: TObject);
1316 LabelTimer.Enabled := false;
1317 lblmessage.Visible := false;
1320 procedure TfrmSender.actCopyAllExecute(Sender: TObject);
1324 Str := memScript.Lines.Text;
1325 Clip := ClipBoard();
1326 Clip.SetTextBuf(PChar(Str));
1329 procedure TfrmSender.actCopyAllNoReturnExecute(Sender: TObject);
1333 Str := memScript.Lines.Text;
1334 RegExp.Subst('s/\r\n//gk', Str);
1335 Clip := ClipBoard();
1336 Clip.SetTextBuf(PChar(Str));
1339 procedure TfrmSender.Slpp20SlppEvent(Sender: TObject; EventType: TIdSlppEventType;
1340 const Param: String);
1341 var HeadValue: THeadValue;
1343 HeadValue := THeadValue.Create(Param);
1346 etScript, etForceBroadcast, etUnicast: begin
1347 //
\83\81\83b
\83Z
\81[
\83W
\8eó
\90M
1348 DispatchBottle(EventType, HeadValue);
1350 etMemberCount: begin
1351 StatusBar.Panels[PanelMembers].Text := HeadValue['Num'] + '
\90l'
1353 etChannelCount: begin
1355 ChannelList.Channel[HeadValue['Channel']].Members := StrToInt(HeadValue['Num']);
1360 ShowHintLabel('SSTP Bottle
\83T
\81[
\83o
\82Æ
\92Ê
\90M
\8am
\97§
\81B');
1362 FBeginConnectFailCount := 0;
1363 //
\83`
\83\83\83\93\83l
\83\8b\8e©
\93®
\93o
\98^
1364 if not Connecting then
1365 PostCommand(['Command: getChannels']);
1366 SakuraSeeker.BeginDetect;
1367 if SakuraSeeker.Count = 0 then
1368 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 +
1369 '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 +
1370 '
\8fÚ
\8d×
\82Í
\83w
\83\8b\83v
\82ð
\82²
\97\97\89º
\82³
\82¢
\81B');
1372 etChannelList: begin
1373 UpdateJoinChannelList(HeadValue);
1374 //
\8dÅ
\8cã
\82É
\8eQ
\89Á
\82µ
\82Ä
\82¢
\82½
\83`
\83\83\83\93\83l
\83\8b\82ð
\8bL
\98^
\82·
\82é
1375 if JoinChannelsBackup = nil then JoinChannelsBackup := TStringList.Create;
1376 JoinChannelsBackup.Assign(JoinChannels);
1378 etCloseChannel: begin
1379 with JoinChannels do
1380 if IndexOf(HeadValue['Channel']) >= 0 then
1381 Delete(IndexOf(HeadValue['Channel']));
1382 with tabChannel do begin
1383 if Tabs.IndexOf(HeadValue['Channel']) >= 0 then
1384 Tabs.Delete(Tabs.IndexOf(HeadValue['Channel']));
1385 if Tabs.Count > 0 then TabIndex := 0 else TabIndex := -1;
1386 tabChannelChange(self);
1388 ShowHintLabel(HeadValue['Channel'] + '
\83`
\83\83\83\93\83l
\83\8b\82Í
\94p
\8e~
\82³
\82ê
\82Ü
\82µ
\82½',
1390 frmLog.AddCurrentSystemLog('SYSTEM', HeadValue['Channel'] + '
\83`
\83\83\83\93\83l
\83\8b\82Í
\94p
\8e~
\82³
\82ê
\82Ü
\82µ
\82½');
1391 frmMessageBox.ShowMessage(HeadValue['Channel'] + '
\83`
\83\83\83\93\83l
\83\8b\82Í
\94p
\8e~
\82³
\82ê
\82Ü
\82µ
\82½');
1393 etForceBroadcastInformation: begin
1394 if HeadValue['Type'] = 'Vote' then begin
1395 frmLog.VoteLog(HeadValue['MID'], StrToIntDef(HeadValue['Num'], 0));
1396 end else if HeadValue['Type'] = 'Agree' then begin
1397 frmLog.AgreeLog(HeadValue['MID'], StrToIntDef(HeadValue['Num'], 0));
1406 procedure TfrmSender.BottleSstpResendCountChange(Sender: TObject);
1408 StatusBar.Panels[PanelCount].Text := IntToStr(FBottleSstp.CueCount) + '
\8c\8f';
1410 TaskTray.TipString := 'SSTP Bottle Client (' +
1411 IntToStr(FBottleSstp.CueCount) + '
\8c\8f)';
1413 ; //
\83^
\83X
\83N
\83g
\83\8c\83C
\93o
\98^
\8e¸
\94s
\82ð
\96³
\8e\8b\82·
\82é
1415 actClearBottles.Enabled := (FBottleSstp.CueCount > 0);
1418 procedure TfrmSender.actSettingExecute(Sender: TObject);
1420 Application.CreateForm(TfrmSetting, frmSetting);
1432 frmLog.UpdateWindow;
1435 procedure TfrmSender.memScriptKeyPress(Sender: TObject; var Key: Char);
1437 if (Key = #13) or (Key = #10) then Key := Char(0);
1440 procedure TfrmSender.Slpp20Disconnect(Sender: TObject);
1443 UpdateJoinChannelList(nil);
1444 frmLog.AddCurrentSystemLog('SYSTEM', '
\83T
\81[
\83o
\82©
\82ç
\90Ø
\92f
\82³
\82ê
\82Ü
\82µ
\82½');
1445 if not Application.Terminated then RetryBeginConnect;
1448 procedure TfrmSender.SetSleeping(const Value: boolean);
1451 FBottleSstp.ResendSleep := Value;
1455 procedure TfrmSender.actClearBottlesExecute(Sender: TObject);
1458 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]),
1459 mtWarning, mbOkCancel, 0);
1460 if Re = mrOk then begin
1462 frmLog.AllBottleOpened;
1463 frmLog.UpdateWindow;
1467 procedure TfrmSender.SakuraSeekerDetectResultChanged(Sender: TObject);
1470 Http: THTTPDownloadThread;
1473 UpdateIfGhostBox; //
\83h
\83\8d\83b
\83v
\83_
\83E
\83\93\82Ì
\92\86\90g
\82ð
\8f\91\82«
\8a·
\82¦
\82é
1475 if (FLastGhostListSend <> 0) and
1476 (GetTickCount < FLastGhostListSend + 1000*60) then
1480 FLastGhostListSend := GetTickCount;
1482 //
\8d\91\90¨
\92²
\8d¸
\82É
\8eQ
\89Á
1483 if FBooted and not Pref.NoSendGhostList and (SakuraSeeker.Count > 0) then begin
1484 GhostList := 'CCC=' + TIdURI.ParamsEncode('
\88¤');
1485 GhostList := GhostList + '&LUID=' + Pref.LUID;
1487 for i := 0 to SakuraSeeker.Count-1 do begin
1488 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¤
1489 GhostList := GhostList + '&GHOST=' + TIdURI.ParamsEncode(SakuraSeeker[i].SetName);
1493 if SendOk and (FLastGhostList <> GhostList) then begin
1494 FLastGhostList := GhostList;
1495 Http := THTTPDownloadThread.Create(BottleServer, Pref.CgiNameGhost, GhostList);
1496 if Pref.UseHttpProxy then begin
1497 Http.ProxyServer := Pref.ProxyAddress;
1498 Http.ProxyPort := Pref.ProxyPort;
1500 Http.FreeOnTerminate := true;
1506 procedure TfrmSender.UpdateChannelInfo(Dat: THeadValue);
1508 Ch: TChannelListItem;
1511 for i := 1 to Dat.IntData['Count'] do begin
1512 Ch := TChannelListItem.Create;
1513 Ch.Name := Dat[Format('CH%d_name', [i])];
1514 Ch.Ghost := Dat[Format('CH%d_ghost', [i])];
1515 Ch.Info := Dat[Format('CH%d_info', [i])];
1516 Ch.NoPost := Dat[Format('CH%d_nopost', [i])] = '1';
1517 Ch.Members := Dat.IntData[Format('CH%d_count', [i])];
1518 Ch.WarnPost:= Dat[Format('CH%d_warnpost', [i])] = '1';
1519 ChannelList.Add(Ch);
1524 procedure TfrmSender.mnGetNewIdClick(Sender: TObject);
1526 PostCommand(['Command: getNewId', 'Agent: ' + VersionString]);
1529 procedure TfrmSender.NoLuidError;
1532 ShowMessage('SSTP Bottle ID
\82Ì
\8eæ
\93¾
\82ª
\82Ü
\82¾
\8a®
\97¹
\82µ
\82Ä
\82¢
\82Ü
\82¹
\82ñ
\81B'#13#10+
1533 '
\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+
1534 '
\82±
\82Ì
\91\80\8dì
\82ÍClient
\8f\89\89ñ
\8bN
\93®
\8e\9e\82É1
\89ñ
\82¾
\82¯
\95K
\97v
\82Å
\82·
\81B');
1537 procedure TfrmSender.tabChannelChange(Sender: TObject);
1539 if tabChannel.TabIndex >= 0 then begin
1540 FNowChannel := tabChannel.Tabs[tabChannel.TabIndex];
1541 actSend.Hint := Format('
\81u%s
\81v
\82É
\91\97\90M|%s', [FNowChannel, SendButtonLongHint]);
1546 tabChannel.Repaint; //
\82±
\82ê
\82ª
\82È
\82¢
\82Æ
\90F
\82ª
\95Ï
\82í
\82ç
\82È
\82¢
\82±
\82Æ
\82ª
\82 \82é
1547 ConstructMenu(true);
1550 procedure TfrmSender.actPrevChannelExecute(Sender: TObject);
1552 with tabChannel do begin
1553 if Tabs.Count = 0 then Exit;
1554 if TabIndex=0 then TabIndex := Tabs.Count-1
1555 else TabIndex := TabIndex-1;
1557 tabChannelChange(Self);
1560 procedure TfrmSender.actNextChannelExecute(Sender: TObject);
1562 with tabChannel do begin
1563 if Tabs.Count = 0 then Exit;
1564 if TabIndex=Tabs.Count-1 then TabIndex := 0
1565 else TabIndex := TabIndex+1;
1567 tabChannelChange(Self);
1570 procedure TfrmSender.UpdateJoinChannelList(Dat: THeadValue);
1574 nodat := Dat = nil; //nil
\82È
\82ç
\83`
\83\83\83\93\83l
\83\8b\91S
\89ð
\8f\9c
1575 if nodat then Dat := THeadValue.Create('');
1577 for i := 0 to Dat.Count-1 do
1578 if Dat.KeyAt[i] = 'Entry' then begin
1579 if RegExp.Match('m/^(.+?) \((\d+?)\)$/', Dat.ValueAt[i]) then
1580 JoinChannels.Add(RegExp[1]);
1582 with tabChannel do begin
1587 for i := 0 to JoinChannels.Count-1 do begin
1588 //
\8eó
\90M
\90ê
\97p
\83`
\83\83\83\93\83l
\83\8b\82Í
\95\
\8e¦
\82µ
\82È
\82¢
1589 if not ChannelList.Channel[JoinChannels[i]].NoPost then
1590 Tabs.Add(JoinChannels[i]);
1594 for i := 0 to Tabs.Count-1 do
1595 if Tabs[i] = FNowChannel then TabIndex := i;
1596 if Tabs.Count > 0 then begin
1597 FNowChannel := Tabs[TabIndex];
1598 actSend.Hint := Format('
\81u%s
\81v
\82É
\91\97\90M|%s', [FNowChannel, SendButtonLongHint]);
1601 actSend.Hint := Format('
\91\97\90M|%s', [SendButtonLongHint]);
1603 Visible := Tabs.Count > 0;
1604 if Tabs.Count > 1 then begin
1605 actNextChannel.Enabled := true;
1606 actPrevChannel.Enabled := true;
1608 actNextChannel.Enabled := false;
1609 actPrevChannel.Enabled := false;
1611 OnChange := tabChannelChange;
1613 if nodat then Dat.Free;
1614 if JoinChannels.Count = 0 then begin
1615 Self.Caption := FOriginalCaption + ' -
\83`
\83\83\83\93\83l
\83\8b\82É
\8eQ
\89Á
\82µ
\82Ä
\82¢
\82Ü
\82¹
\82ñ';
1616 actSend.Enabled := false;
1618 Self.Caption := FOriginalCaption;
1619 actSend.Enabled := true;
1623 procedure TfrmSender.cbxTargetGhostDropDown(Sender: TObject);
1625 SakuraSeeker.BeginDetect;
1629 procedure TfrmSender.actShowLogExecute(Sender: TObject);
1632 if frmLog.WindowState = wsMinimized then frmLog.WindowState := wsNormal;
1635 procedure TfrmSender.actSleepExecute(Sender: TObject);
1637 if actSleep.Checked then begin
1638 actSleep.Checked := false;
1639 ShowHintLabel('
\83X
\83\8a\81[
\83v
\82ð
\89ð
\8f\9c\82µ
\82Ü
\82µ
\82½');
1641 actSleep.Checked := true;
1642 ShowHintLabel('
\83X
\83\8a\81[
\83v
\82ð
\90Ý
\92è
\82µ
\82Ü
\82µ
\82½');
1644 Sleeping := actSleep.Checked;
1649 procedure TfrmSender.DispatchBottle(EventType: TIdSlppEventType;
1651 var Opt: TSstpSendOptions;
1652 Event: TBottleChainBottleEvent;
1653 Script, Sender, Ghost, Channel: String;
1654 BreakFlag, NoDispatch: boolean;
1655 Sound, LogName: String;
1656 i, j, k, SkipCount: integer;
1657 Rule: TBottleChainRule;
1658 Action: TBottleChainAction;
1659 LogNameList: TStringList;
1663 if Pref.NoTranslate then Opt := Opt + [soNoTranslate];
1664 if Pref.NoDescript then Opt := Opt + [soNoDescript];
1665 Channel := Dat['Channel'];
1667 etScript: Sender := Channel;
1668 etForceBroadcast: Sender := '
\81y
\82¨
\92m
\82ç
\82¹
\81z';
1669 etUnicast: Sender := Dat['SenderUID'];
1672 //
\96Ú
\95W
\83S
\81[
\83X
\83g(
\83I
\81[
\83o
\81[
\83\89\83C
\83h
\88È
\91O)
\8c\88\92è
1673 if Dat['IfGhost'] <> '' then begin
1674 Ghost := Dat['IfGhost'];
1676 if ChannelList.Channel[Channel] <> nil then
1677 Ghost := ChannelList.Channel[Channel].Ghost;
1679 Dat['TargetGhost'] := Ghost;
1681 Event := TBottleChainBottleEvent.Create;
1684 if EventType = etScript then Event.LogType := ltBottle
1685 else Event.LogType := ltSystemLog;
1687 //
\83X
\83N
\83\8a\83v
\83g
\95Ï
\8a·
1688 Script := ScriptTransForSSTP(Dat['Script']);
1689 if Script = '' then begin
1690 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'+
1691 '
\94z
\91\97\82³
\82ê
\82Ü
\82¹
\82ñ
\82Å
\82µ
\82½
\81@
\81c '+Dat['Script']);
1696 NoDispatch := false;
1698 LogNameList := TStringList.Create;
1701 for i := 0 to BottleChainRuleList.Count-1 do begin
1702 if SkipCount > 0 then begin
1706 Rule := BottleChainRuleList[i];
1707 if not Rule.Enabled then Continue;
1708 if not Rule.Check(Event) then Continue;
1709 for j := 0 to Rule.Actions.Count-1 do begin
1710 Action := (Rule.Actions[j] as TBottleChainAction);
1711 if Action is TBottleChainAbortRuleAction then BreakFlag := true;
1712 if Action is TBottleChainSkipRuleAction then
1713 SkipCount := (Action as TBottleChainSkipRuleAction).SkipCount;
1714 if (Action is TBottleChainSoundAction) and (Sound = '') then begin
1715 Sound := (Action as TBottleChainSoundAction).SoundFile;
1716 Sound := StringReplace(Sound, '%channel%', Dat['Channel'], [rfReplaceAll]);
1717 Sound := StringReplace(Sound, '%ghost%', Dat['TargetGhost'], [rfReplaceAll]);
1719 if Action is TBottleChainNoDispatchAction then NoDispatch := true;
1720 if Action is TBottleChainLogAction then begin
1721 for k := 0 to (Action as TBottleChainLogAction).LogNames.Count-1 do begin
1722 LogName := (Action as TBottleChainLogAction).LogNames[k];
1723 LogName := StringReplace(LogName, '%channel%', Dat['Channel'], [rfReplaceAll]);
1724 LogName := StringReplace(LogName, '%ghost%', Dat['TargetGhost'], [rfReplaceAll]);
1725 LogName := StringReplace(LogName, '%date%', FormatDateTime('yy/mm/dd', Now()), [rfReplaceAll]);
1726 LogNameList.Add(LogName);
1729 if Action is TBottleChainOverrideGhostAction then begin
1730 Dat['TargetGhost'] := (Action as TBottleChainOverrideGhostAction).TargetGhost;
1732 if Action is TBottleChainQuitAction then Application.Terminate;
1734 if BreakFlag then Break;
1737 if Dat['Script'] <> '' then begin
1738 for i := 0 to LogNameList.Count-1 do
1739 frmLog.AddCurrentScriptLog(LogNameList[i], Dat['Script'], Sender, Dat['MID'], Dat['IfGhost']);
1740 if NoDispatch then begin
1741 frmLog.SetBottleState(Dat['MID'], lsOpened);
1743 Ghost := Dat['TargetGhost']; //
\83I
\81[
\83o
\81[
\83\89\83C
\83h
\82³
\82ê
\82Ä
\82¢
\82é
\89Â
\94\
\90«
\82ª
\82 \82é
1744 CueItem := TLogItem.Create(ltBottle, Dat['MID'], Dat['Channel'],
1745 Script, Ghost, Now());
1747 FBottleSstp.Push(CueItem);
1754 if Dat['DialogMessage'] <> '' then begin
1756 frmMessageBox.ShowMessage(
1757 DateTimeToStr(Now) + #13#10 +
1758 'SSTP Bottle
\83T
\81[
\83o
\82©
\82ç
\82¨
\92m
\82ç
\82¹'#13#10+Dat['DialogMessage']);
1759 for i := 0 to LogNameList.Count-1 do
1760 frmLog.AddCurrentSystemLog(LogNameList[i], Dat['DialogMessage']);
1764 if (Sound <> '') then PlaySound(Sound);
1773 function TfrmSender.SetHWndToFavoriteGhost(const Ghost: String): String;
1775 //DirectSstp.TargetHWnd
\82ð
\81A
\90\84\8f§
\82·
\82é
\83S
\81[
\83X
\83g
\82É
\90Ý
\92è
\82·
\82é
\81B
1776 //
\82È
\82¢
\8fê
\8d\87\82Í
\81A
\82Æ
\82è
\82 \82¦
\82¸
\8eè
\8bß
\82È
\83S
\81[
\83X
\83g
\82É
\8cü
\82¯
\82Ä
\91\97\90M
\82Å
\82«
\82é
\82æ
\82¤
\82É
\82Í
\82·
\82é
\81B
1777 SakuraSeeker.BeginDetect; //
\8dÅ
\90V
\82ÌFMO
\8eæ
\93¾
1778 if SakuraSeeker.ProcessByName[Ghost] <> nil then begin
1779 DirectSstp.TargetHWnd := SakuraSeeker.ProcessByName[Ghost].HWnd;
1781 end else if SakuraSeeker.Count > 0 then begin
1782 DirectSstp.TargetHWnd := SakuraSeeker[0].HWnd;
1783 Result := SakuraSeeker[0].Name;
1785 DirectSstp.TargetHwnd := 0;
1790 procedure TfrmSender.YenETrans;
1791 var St, Le, i: integer;
1794 St := memScript.SelStart;
1795 Le := memScript.SelLength;
1796 Orig := GetScriptText;
1797 RegExp.Subst('s/(\r\n)+$//kg', Orig);
1799 with SsParser do begin
1800 LeaveEscape := true;
1801 EscapeInvalidMeta := false;
1802 InputString := Orig;
1804 for i := 0 to SsParser.Count-1 do begin
1805 if SsParser[i] <> '\e' then Text := Text + SsParser[i];
1808 Text := Text + '\e';
1810 if Orig <> Text then memScript.Lines.Text := Text;
1811 SsParser.InputString := Text;
1813 RegExp.Subst('s/\r\n//kg', Text);
1815 memScript.SelStart := St;
1816 memScript.SelLength := Le;
1819 procedure TfrmSender.PostCommand(const Command: array of String);
1820 var PostStr: TStringList;
1825 PostStr := TStringList.Create;
1826 for i := Low(Command) to High(Command) do begin
1827 PostStr.Add(Command[i]);
1829 PostCommand(PostStr);
1835 procedure TfrmSender.PostCommand(Command: TStrings);
1836 var PostStr: String;
1839 PostStr := Command.Text;
1840 PostStr := TIdURI.ParamsEncode(PostStr);
1842 FHttp := THTTPDownloadThread.Create(BottleServer, Pref.CgiName, PostStr);
1843 if Pref.UseHttpProxy then begin
1844 FHttp.ProxyServer := Pref.ProxyAddress;
1845 FHttp.ProxyPort := Pref.ProxyPort;
1847 FHttp.OnSuccess := HttpSuccess;
1848 FHttp.OnConnectionFailed := HttpFailure;
1849 FHttp.FreeOnTerminate := true; //
\8f\9f\8eè
\82É
\8e©
\95ª
\82ÅFree
\82µ
\82Ä
\82
\82¾
\82³
\82¢
1852 on EHeapException do begin
1853 Connecting := false;
1859 procedure TfrmSender.actVoteMessageExecute(Sender: TObject);
1862 if frmLog.lvwLog.Selected = nil then Exit;
1863 Log := frmLog.SelectedBottleLog[frmLog.lvwLog.Selected.Index] as TLogItem;
1864 if Log = nil then Exit;
1865 if Log.LogType <> ltBottle then Exit;
1867 'Command: voteMessage',
1869 'LUID: ' + Pref.LUID,
1875 procedure TfrmSender.actAgreeMessageExecute(Sender: TObject);
1878 if frmLog.lvwLog.Selected = nil then Exit;
1879 Log := frmLog.SelectedBottleLog[frmLog.lvwLog.Selected.Index] as TLogItem;
1880 if Log = nil then Exit;
1881 if Log.LogType <> ltBottle then Exit;
1883 'Command: voteMessage',
1885 'LUID: ' + Pref.LUID,
1891 function TfrmSender.GhostNameToSetName(const Ghost: String): String;
1893 if SakuraSeeker.ProcessByName[Ghost] <> nil then
1894 Result := SakuraSeeker.ProcessByName[Ghost].SetName
1899 procedure TfrmSender.tabChannelContextPopup(Sender: TObject;
1900 MousePos: TPoint; var Handled: Boolean);
1903 with tabChannel do begin
1904 Tag := IndexOfTabAt(MousePos.X, MousePos.Y);
1905 if Tag < 0 then Handled := true;
1910 procedure TfrmSender.PostSetChannel(Channels: TStrings);
1911 var PostStr: TStringList;
1916 PostStr := TStringList.Create;
1917 with PostStr do begin
1918 Add('Command: setChannels');
1919 Add('Agent: ' + VersionString);
1920 Add('LUID: ' + Pref.LUID);
1921 if Channels <> nil then
1922 for i := 0 to Channels.Count-1 do begin
1923 Add(Format('Ch%d: %s'#13#10, [i+1, Channels[i]]));
1926 PostCommand(PostStr);
1932 procedure TfrmSender.mnLeaveThisChannelClick(Sender: TObject);
1936 with tabChannel do Ch := Tabs[Tag];
1939 Chs := TStringList.Create;
1940 Chs.Assign(JoinChannels);
1941 while Chs.IndexOf(Ch) >= 0 do Chs.Delete(Chs.IndexOf(Ch));
1942 PostSetChannel(Chs);
1948 procedure TfrmSender.mnGotoVoteClick(Sender: TObject);
1950 ShellExecute(Handle, 'open', PChar(Pref.VotePage), nil, nil, SW_SHOW);
1953 procedure TfrmSender.mnGotoGLogClick(Sender: TObject);
1955 ShellExecute(Handle, 'open', PChar(Pref.GLogPage), nil, nil, SW_SHOW);
1958 procedure TfrmSender.tabChannelMouseMove(Sender: TObject;
1959 Shift: TShiftState; X, Y: Integer);
1963 with tabChannel do begin
1964 Index := IndexOfTabAt(X, Y);
1966 Hint := Ch + ': ' + IntToStr(ChannelList.Channel[Ch].Members) + '
\90l';
1970 procedure TfrmSender.mnGoToHelpClick(Sender: TObject);
1972 ShellExecute(Handle, 'open', PChar(Pref.HelpPage), nil, nil, SW_SHOW);
1975 procedure TfrmSender.tabChannelMouseDown(Sender: TObject;
1976 Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
1979 with tabChannel do begin
1980 Index := IndexOfTabAt(X, Y);
1981 if Index = -1 then Exit; //
\83^
\83u
\82ª
\82È
\82¢
\82Ì
\82Å
\83h
\83\89\83b
\83O
\82Å
\82«
\82È
\82¢
1982 if Button = mbLeft then begin
1983 FDragTabIndex := Index; //
\83h
\83\89\83b
\83O
\82·
\82é
\83^
\83u
\82Ì
\83C
\83\93\83f
\83b
\83N
\83X
\82ð
\95Û
\91¶
1985 FDragTabDest := -1; //
\83h
\83\89\83b
\83O
\98g
\90ü
\95`
\89æ
\83t
\83\89\83O
\83N
\83\8a\83A
\82Ì
\82½
\82ß
1990 procedure TfrmSender.tabChannelDragOver(Sender, Source: TObject; X,
1991 Y: Integer; State: TDragState; var Accept: Boolean);
1992 var TargetRect: TRect;
1995 Accept := Source = tabChannel;
1996 if not Accept then Exit;
1997 with tabChannel do begin
1998 OldDest := FDragTabDest;
1999 FDragTabDest := IndexOfTabAt(X, Y);
2000 if FDragTabDest = -1 then begin
2001 Accept := false; //
\82±
\82Ì
\8fê
\8d\87\82Í
\83h
\83\8d\83b
\83v
\82ð
\94F
\82ß
\82È
\82¢
2004 with Canvas do begin
2008 if (OldDest <> FDragTabDest) and (OldDest >= 0) then begin
2009 //
\88È
\91O
\82Ì
\98g
\90ü
\8fÁ
\8b\8e
2010 TargetRect := TabRect(OldDest);
2011 with Canvas do begin
2012 Brush.Style := bsClear;
2013 Rectangle(TargetRect.Left, TargetRect.Top,
2014 TargetRect.Right, TargetRect.Bottom);
2017 if (OldDest <> FDragTabDest) then begin
2018 //
\90V
\82µ
\82¢
\98g
\90ü
\95`
\89æ
2019 TargetRect := TabRect(FDragTabDest);
2020 with Canvas do begin
2021 Brush.Style := bsClear;
2022 Rectangle(TargetRect.Left, TargetRect.Top,
2023 TargetRect.Right, TargetRect.Bottom);
2029 procedure TfrmSender.tabChannelDragDrop(Sender, Source: TObject; X,
2031 var DestIndex: integer;
2033 with tabChannel do begin
2034 DestIndex := IndexOfTabAt(X, Y);
2035 Tabs.Move(FDragTabIndex, DestIndex);
2039 procedure TfrmSender.tabChannelEndDrag(Sender, Target: TObject; X,
2042 //
\8b
\90§
\93I
\82É
\83^
\83u
\82ð
\8dÄ
\95`
\89æ
\82³
\82¹
\82é
\81B
\98g
\90ü
\8fÁ
\82µ
\91Î
\8dô
2043 tabChannel.Tabs.BeginUpdate;
2044 tabChannel.Tabs.EndUpdate;
2047 procedure TfrmSender.cbxTargetGhostDrawItem(Control: TWinControl;
2048 Index: Integer; Rect: TRect; State: TOwnerDrawState);
2049 var AlignRight: boolean;
2052 //
\83S
\81[
\83X
\83g
\91I
\91ð
\83{
\83b
\83N
\83X
\82Ì
\83I
\81[
\83i
\81[
\83h
\83\8d\81[
2053 with cbxTargetGhost do begin
2054 AlignRight := false;
2055 if Pref.HideGhosts and not FTargetGhostExpand and (Index = Items.Count-1) then
2057 //
\81u
\82·
\82×
\82Ä
\95\
\8e¦
\81v
2058 Canvas.Font.Color := clWindowText;
2059 Canvas.Font.Style := [];
2061 end else if (Index > 0) then
2063 //
\83S
\81[
\83X
\83g
\96¼
\82ð
\91I
\91ð
2064 if SakuraSeeker.ProcessByName[Items[Index]] = nil then
2065 Canvas.Font.Color := clRed //
\91¶
\8dÝ
\82µ
\82È
\82¢
\83S
\81[
\83X
\83g
2067 Canvas.Font.Color := clBlue; //
\91¶
\8dÝ
\82·
\82é
\83S
\81[
\83X
\83g
2068 Canvas.Font.Style := [fsBold];
2071 Canvas.Font.Color := clWindowText;
2072 Canvas.Font.Style := [];
2074 if odSelected in State then
2075 Canvas.Font.Color := clHighlightText;
2079 w := Canvas.TextWidth(cbxTargetGhost.Items[Index]);
2080 Canvas.TextRect(Rect, Rect.Right - w, Rect.Top,
2081 cbxTargetGhost.Items[Index]);
2083 Canvas.TextRect(Rect, Rect.Left, Rect.Top,
2084 cbxTargetGhost.Items[Index]);
2088 procedure TfrmSender.FormCloseQuery(Sender: TObject;
2089 var CanClose: Boolean);
2091 if not Pref.ConfirmOnExit then Exit;
2092 if MessageDlg('SSTP Bottle Client
\82ð
\8fI
\97¹
\82µ
\82Ü
\82·', mtConfirmation,
2093 mbOkCancel, 0) = mrCancel then CanClose := false;
2096 procedure TfrmSender.UpdateIfGhostBox;
2100 HiddenCount: integer;
2102 cbxTargetGhost.DropDownCount := Pref.GhostDropDownCount;
2103 Selected := cbxTargetGhost.Text;
2105 with cbxTargetGhost do begin
2108 Items.Add('(CH
\90\84\8f§)');
2109 for i := 0 to SakuraSeeker.Count-1 do begin
2110 //
\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é
2111 if Length(SakuraSeeker[i].Name) = 0 then Continue;
2112 if Pref.HideGhosts and not FTargetGhostExpand then
2113 if Pref.VisibleGhostsList.IndexOf(SakuraSeeker[i].Name) < 0 then
2118 if cbxTargetGhost.Items.IndexOf(SakuraSeeker[i].Name) < 0 then
2119 cbxTargetGhost.Items.Add(SakuraSeeker[i].Name);
2121 cbxTargetGhost.ItemIndex := 0;
2122 if (Length(Selected) > 0) and (Selected <> '(CH
\90\84\8f§)') then begin
2123 with cbxTargetGhost do begin
2124 for i := 1 to Items.Count-1 do begin
2125 if Items[i] = Selected then
2128 //
\83S
\81[
\83X
\83g
\82ª
\93Ë
\91R
\91¶
\8dÝ
\82µ
\82È
\82
\82È
\82Á
\82½
\8fê
\8d\87\91Î
\8dô
2129 if ItemIndex = 0 then begin
2130 Items.Add(Selected);
2131 ItemIndex := Items.Count - 1;
2135 if Pref.HideGhosts and not FTargetGhostExpand then
2136 Items.Add(Format('
\82·
\82×
\82Ä(%d)...', [HiddenCount]));
2141 procedure TfrmSender.HTTPFailure(Sender: TObject);
2145 ShowHintLabel('SSTP Bottle
\83T
\81[
\83o
\82Æ
\82Ì
\90Ú
\91±
\82É
\8e¸
\94s
\82µ
\82Ü
\82µ
\82½', WarningColor);
2146 ShowMessage('SSTP Bottle
\83T
\81[
\83o
\82Æ
\82Ì
\90Ú
\91±
\82É
\8e¸
\94s
\82µ
\82Ü
\82µ
\82½'#13#10 +
2147 (Sender as THTTPDownloadThread).LastErrorMessage);
2148 Connecting := false;
2151 procedure TfrmSender.actPrevGhostExecute(Sender: TObject);
2154 SakuraSeeker.BeginDetect;
2156 i := cbxTargetGhost.ItemIndex;
2160 i := cbxTargetGhost.Items.Count-1;
2161 if Pref.HideGhosts and not FTargetGhostExpand then
2164 cbxTargetGhost.ItemIndex := i;
2165 cbxTargetGhostChange(self);
2168 procedure TfrmSender.actNextGhostExecute(Sender: TObject);
2171 SakuraSeeker.BeginDetect;
2173 i := cbxTargetGhost.ItemIndex;
2175 if Pref.HideGhosts and not FTargetGhostExpand then
2177 if i > cbxTargetGhost.Items.Count-2 then i := 0;
2180 if i > cbxTargetGhost.Items.Count-1 then i := 0;
2182 cbxTargetGhost.ItemIndex := i;
2183 cbxTargetGhostChange(self);
2186 procedure TfrmSender.actResetGhostExecute(Sender: TObject);
2188 cbxTargetGhost.ItemIndex := 0; // (CH
\90\84\8f§)
\82É
\96ß
\82·
2189 FTargetGhostExpand := false;
2190 if Visible then memScript.SetFocus;
2191 cbxTargetGhostChange(self);
2194 procedure TfrmSender.timDisconnectCheckTimerTimer(Sender: TObject);
2196 if (IdSlpp20.LastReadTimeInterval > BottleServerTimeOut) then begin
2198 frmLog.AddCurrentSystemLog('SYSTEM', 'SSTP Bottle
\83T
\81[
\83o
\82Æ
\82Ì
\90Ú
\91±
\82ª
\83^
\83C
\83\80\83A
\83E
\83g
\82µ
\82Ü
\82µ
\82½');
2199 if IdSlpp20.Connected then IdSlpp20.Disconnect;
2201 if not IdSlpp20.Connected then begin
2203 Slpp20Disconnect(self); //
\82È
\82º
\82©Disconnect
\83C
\83x
\83\93\83g
\82ª
\8bN
\82±
\82ç
\82¸
\82É
\90Ø
\92f
\82µ
\82½
\8fê
\8d\87
2205 //
\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
2206 //
\82½
\82¾
\82µ
\89ñ
\90\94\90§
\8cÀ
\82 \82è
2212 procedure TfrmSender.RetryBeginConnect;
2214 if FBeginConnectFailCount < 3 then begin
2215 //
\90Ø
\92f
\82³
\82ê
\82Ä
\82¢
\82ê
\82Î
\8dÄ
\90Ú
\91±
2216 FAutoAddAfterGetChannel := true;
2218 end else if FBeginConnectFailCount = 3 then begin
2219 frmLog.AddCurrentSystemLog('SYSTEM', '
\8dÄ
\90Ú
\91±
\8e©
\93®
\83\8a\83g
\83\89\83C
\82ð
\92\86\8e~
\82µ
\82Ü
\82·');
2220 frmMessageBox.ShowMessage(
2221 'SSTP Bottle
\83T
\81[
\83o
\82É
\90Ú
\91±
\82Å
\82«
\82Ü
\82¹
\82ñ
\81B'#13#10+
2222 '
\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+
2223 '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'
2225 Inc(FBeginConnectFailCount);
2229 procedure TfrmSender.actDownloadLogExecute(Sender: TObject);
2230 var BottleLog: TBottleLogList;
2232 Cond: TBottleLogDownloadCondition;
2234 function TimeStr(Mins: integer): String;
2235 var day, hour, min: integer;
2237 day := Mins div (60 * 24);
2238 hour := (Mins div 60) mod 24;
2241 if day > 0 then Result := Result + Format('%d
\93ú', [day]);
2242 if hour > 0 then Result := Result + Format('%d
\8e\9e\8aÔ', [hour]);
2243 if (min > 0) or (Result = '') then Result := Result + Format('%d
\95ª', [min]);
2246 Application.CreateForm(TfrmLogDownload, frmLogDownload);
2248 if frmLogDownload.Execute then begin
2249 with frmLogDownload do begin
2250 if IsRange then begin
2251 if CompareDate(DateLo, DateHi) = 0 then
2252 Title := FormatDateTime('yy/mm/dd', DateLo)
2254 Title := FormatDateTime('yy/mm/dd', DateLo) + ' - ' + FormatdateTime('yy/mm/dd', DateHi);
2256 Title := Format('
\89ß
\8b\8e%s', [TimeStr(RecentCount)]);
2258 if Channel <> '' then Title := Title + '(' + Channel + ')';
2260 BottleLog := TBottleLogList.Create(Title);
2262 BottleLog.OnLoaded := frmLog.LogLoaded;
2263 BottleLog.OnLoadFailure := frmLog.LogLoadFailure;
2264 BottleLog.OnLoadWork := frmLog.LogLoadWork;
2265 with frmLogDownload do begin
2266 Cond.IsRange := IsRange;
2267 Cond.RecentCount := RecentCount;
2268 Cond.DateLo := DateLo;
2269 Cond.DateHi := DateHi;
2270 Cond.MinVote := MinVote;
2271 Cond.MinAgree := MinAgree;
2272 Cond.Channel := Channel;
2274 BottleLog.LoadFromWeb(Cond);
2276 FreeAndNil(BottleLog);
2278 if BottleLog <> nil then begin
2279 NewIndex := frmLog.BottleLogList.Add(BottleLog);
2281 frmLog.tabBottleLog.TabIndex := NewIndex;
2282 frmLog.UpdateWindow;
2286 frmLogDownload.Release;
2290 function TfrmSender.BuildMenuConditionCheck(const IfGhost,
2291 Ghost: String): boolean;
2298 Cond := Token(IfGhost, ',', i);
2299 if Cond <> '' then begin
2300 if Cond[1] = '!' then begin
2301 Cond := Copy(Cond, 2, High(integer));
2302 if Cond = Ghost then Result := false;
2304 if Cond <> Ghost then Result := false;
2311 procedure TfrmSender.BuildMenu(Root: TMenuItem; Simple: boolean);
2312 var i, j, k, count: integer;
2313 ConstData: TScriptConst;
2314 Menu1, Menu2: TMenuItem;
2317 // Simple = false
\82Ì
\8fê
\8d\87\82Í
\83\81\83j
\83\85\81[
\82ð
\8a®
\91S
\82É
\8dÄ
\8d\
\92z
\82·
\82é
\81B
2318 // 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
2319 if cbxTargetGhost.ItemIndex > 0 then Ghost := cbxTargetGhost.Text
2320 else if FNowChannel <> '' then Ghost := ChannelList.Channel[FNowChannel].Ghost;
2322 //
\8aù
\91¶
\82Ì
\83\81\83j
\83\85\81[
\8dí
\8f\9c
2323 if Simple then begin
2324 // IfGhost
\8fð
\8c\8f\95t
\82«
\83\81\83j
\83\85\81[
\82Ì
\82Ý
\8dí
\8f\9c
2325 for i := Root.Count-1 downto 0 do begin
2326 if ScriptConstList.GetMenuByID(Root.Items[i].Tag).IfGhost <> '' then
2330 //
\91S
\95\94\8dí
\8f\9c
2331 for i := Root.Count-1 downto 0 do begin
2337 for i := 0 to ScriptConstList.Count-1 do begin
2338 for j := 0 to ScriptConstList[i].Count-1 do begin
2339 //
\83S
\81[
\83X
\83g
\88á
\82¢
\82Ì
\8fê
\8d\87\82Í
\83X
\83L
\83b
\83v
2340 if not BuildMenuConditionCheck(ScriptConstList[i][j].IfGhost, Ghost) then Continue;
2342 // 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
2343 if Simple and (count < Root.Count) then
2344 if (Root.Items[count].Tag = ScriptConstList[i][j].ID) then begin
2348 Menu1 := TMenuItem.Create(Root);
2349 Menu1.Caption := ScriptConstList[i][j].Caption;
2350 Menu1.Hint := ScriptConstList[i][j].Caption;
2351 Menu1.AutoHotkeys := maManual;
2352 Menu1.Tag := ScriptConstList[i][j].ID;
2353 Menu1.OnClick := mnConstGroupClick;
2355 if not Simple then begin
2358 if count < Root.Count-1 then
2359 Root.Insert(count, Menu1)
2364 Menu1.Enabled := ScriptConstList[i][j].Count > 0;
2365 for k := 0 to ScriptConstList[i][j].Count-1 do begin
2366 ConstData := ScriptConstList[i][j][k];
2367 Menu2 := TMenuItem.Create(Root);
2368 Menu2.Caption := ConstData.Caption;
2369 Menu2.Hint := ConstData.ConstText;
2370 // if ConstData.ShortCut <> 0 then Menu2.Hint := Menu2.Hint
2371 // + ' (' + ShortCutToText(ConstData.ShortCut) + ')';
2372 //
\83T
\81[
\83t
\83B
\83X
\83v
\83\8c\83r
\83\85\81[
\8eÀ
\8c»
\82Ì
\82½
\82ß
\8fã
\8dí
\8f\9c
2373 Menu2.ShortCut := ConstData.ShortCut;
2374 Menu2.OnClick := mnConstClick;
2375 Menu2.AutoHotkeys := maManual;
2376 Menu2.Tag := ConstData.ID;
2377 if (k mod 15 = 0) and (k > 0) then Menu2.Break := mbBarBreak;
2384 procedure TfrmSender.cbxTargetGhostChange(Sender: TObject);
2386 //
\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
2387 if Pref.HideGhosts and not FTargetGhostExpand then
2389 with cbxTargetGhost do
2391 if ItemIndex = Items.Count-1 then
2393 FTargetGhostExpand := true;
2396 DroppedDown := true;
2400 //
\92è
\8c^
\8bå
\83\81\83j
\83\85\81[
\82ð
\8dÄ
\8d\
\92z
2401 ConstructMenu(true);
2402 //
\83v
\83\8c\83r
\83\85\81[
\82ª
\82 \82é
\8fê
\8d\87\82Í
\83v
\83\8c\83r
\83\85\81[
2406 procedure TfrmSender.PlaySound(const FileName: String);
2408 if Pref.SilentWhenHidden and not Application.ShowMainForm then Exit;
2410 MediaPlayer.FileName := FileName;
2414 on E: EMCIDeviceError do begin
2415 ShowMessage('
\83T
\83E
\83\93\83h
\8dÄ
\90¶
\83G
\83\89\81[:'#13#10 + FileName + #13#10#13#10 + E.Message);
2420 procedure TfrmSender.actFMOExplorerExecute(Sender: TObject);
2422 frmFMOExplorer.Show;
2425 procedure TfrmSender.SaveChainRuleList;
2426 var Str: TStringList;
2428 Str := TStringList.Create;
2430 Str.Text := ComponentToString(BottleChainRuleList);
2431 Str.SaveToFile(ExtractFileDir(Application.ExeName)+'\rule.txt');
2437 procedure TfrmSender.BottleSstpResendEnd(Sender: TObject; MID: String);
2439 frmLog.SetBottleState(MID, lsOpened);
2442 procedure TfrmSender.BottleSstpResendTrying(Sender: TObject; MID: String);
2444 frmLog.SetBottleState(MID, lsPlaying);
2447 procedure TfrmSender.actInsertCueExecute(Sender: TObject);
2448 var InsertItem: TLogItem;
2449 i, errCount: integer;
2450 Log: TBottleLogList;
2452 if FBottleSstp.CueCount > 0 then begin
2453 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'+
2454 '
\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+
2455 '
\90V
\92\85\83\81\83b
\83Z
\81[
\83W
\82Í
\82»
\82Ì
\8cã
\82É
\8dÄ
\90¶
\82³
\82ê
\82Ü
\82·
\81B', [FBottleSstp.CueCount]),
2456 mtWarning, mbOkCancel, 0) = mrCancel then Exit;
2459 frmLog.AllBottleOpened;
2460 if frmLog.lvwLog.Selected = nil then Exit;
2461 Log := frmLog.SelectedBottleLog;
2462 if Log = nil then Exit;
2463 FBottleSSTP.OnResendCountChange := nil;
2465 for i := frmLog.lvwLog.Selected.Index downto 0 do begin
2466 if (Log[i] as TLogItem).LogType <> ltBottle then Continue;
2467 InsertItem := TLogItem.Create(Log[i] as TLogItem);
2469 InsertItem.Script := ScriptTransForSSTP(InsertItem.Script);
2470 if InsertItem.Script = '' then begin
2471 raise Exception.Create('Script syntax error');
2473 if InsertItem.Ghost = '' then begin
2474 if ChannelList.Channel[InsertItem.Channel] <> nil then
2475 InsertItem.Ghost := ChannelList.Channel[InsertItem.Channel].Ghost;
2477 FBottleSSTP.Push(InsertItem);
2478 frmLog.SetBottleState(InsertItem.MID, lsUnopened);
2484 if errCount > 0 then
2485 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]));
2486 FBottleSSTP.OnResendCountChange := BottleSstpResendCountChange;
2487 BottleSstpResendCountChange(self);
2490 function TfrmSender.ScriptTransForSSTP(const Script: String): String;
2493 Result := ScriptTransForSSTP(Script, dum);
2496 function TfrmSender.ScriptTransForSSTP(const Script: String;
2497 out Error: String): String;
2498 var TransOpt: TScriptTransOptions;
2501 if Pref.NoTransURL then
2502 TransOpt := [toConvertURL, toNoChoice, toWaitScriptEnd]
2504 TransOpt := [toConvertURL, toWaitScriptEnd];
2505 if Pref.IgnoreFrequentYenS then TransOpt := TransOpt + [toIgnoreFrequentYenS];
2506 if Pref.FixMessySurface then TransOpt := TransOpt + [toFixMessySurface];
2507 if Pref.HUTagTo01Tag then TransOpt := TransOpt + [toHUTagTo01Tag];
2509 Err := DoTrans(Result, TransOpt);
2510 if Length(Err) > 0 then begin
2516 procedure TfrmSender.FormResize(Sender: TObject);
2519 //
\83G
\83f
\83B
\83^
\81[
\95\94\95ª
\82Ì
\83\8f\81[
\83h
\83\89\83b
\83v
\95\9d\82ð
\92²
\90®
\82·
\82é
2520 if memScript.ColWidth <> 0 then
2524 w := Width - LeftMargin - ColWidth div 2;
2525 if ScrollBars in [ssVertical, ssBoth] then
2526 w := w - GetSystemMetrics(SM_CYVSCROLL);
2527 WrapOption.WrapByte := w div ColWidth;
2532 procedure TfrmSender.actCopyExecute(Sender: TObject);
2534 memScript.CopyToClipboard;
2537 procedure TfrmSender.actPasteExecute(Sender: TObject);
2539 memScript.PasteFromClipboard;
2542 procedure TfrmSender.actCutExecute(Sender: TObject);
2544 memScript.CutToClipboard;
2547 procedure TfrmSender.actSelectAllExecute(Sender: TObject);
2549 memScript.SelectAll;
2552 function TfrmSender.IsSurfaceTag(const Script: String;
2553 var ID: integer): boolean;
2556 if SsParser.Match(Script, '\s%d') = 3 then
2559 ID := Ord(Script[3]) - Ord('0')
2561 else if (Length(Script) > 0) and (SsParser.Match(Script, '\s[%D]') = Length(Script)) then
2564 ID := StrToIntDef(SsParser.GetParam(Script, 1), 0);
2568 procedure TfrmSender.memScriptMouseMove(Sender: TObject;
2569 Shift: TShiftState; X, Y: Integer);
2573 //
\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[
2574 if not Pref.SurfacePreviewOnScriptPoint then
2576 token := memScript.TokenStringFromPos(Point(X, Y));
2577 if IsSurfaceTag(token, id) then
2579 DoSurfacePreview(id, spEditor);
2582 frmSurfacePreview.HideAway;
2586 procedure TfrmSender.DoSurfacePreview(Surface: integer;
2587 const Kind: TSurfacePreviewType);
2592 if cbxTargetGhost.ItemIndex > 0 then
2593 ghost := cbxTargetGhost.Text
2594 else if FNowChannel <> '' then
2595 ghost := ChannelList.Channel[FNowChannel].Ghost;
2597 //
\93ñ
\8fd
\95\
\8e¦
\82Ì
\97}
\90§
2598 if (FVisiblePreviewGhost = Ghost) and (FVisiblePreviewSurface = Surface) and
2599 not (frmSurfacePreview.IsHidden) then
2606 Bmp := TBitmap.Create;
2608 if Spps.TryGetImage(ghost, Surface, Bmp) then
2612 CPos := GetSurfacePreviewPositionHint(Bmp.Width, Bmp.Height);
2614 CPos := GetSurfacePreviewPositionScriptPoint(Bmp.Width, Bmp.Height);
2616 CPos := Point(0, 0);
2618 frmSurfacePreview.ShowPreview(Bmp, CPos.X, CPos.Y);
2619 FVisiblePreviewGhost := Ghost;
2620 FVisiblePreviewSurface := Surface;
2622 frmSurfacePreview.HideAway;
2629 function TfrmSender.GetSurfacePreviewPositionHint(w, h: integer): TPoint;
2630 {var MousePoint: TPoint;
2633 //
\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é
2634 //
\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Å
2635 //
\88Ä
\8aO
\82â
\82â
\82±
\82µ
\82¢
2636 {GetCursorPos(MousePoint);
2637 OutputDebugString(PChar(IntToStr(FVisibleMenuItem.Count)));
2638 //if GetMenuItemRect(Self.Handle, FVisibleMenuItem.Items[0].Handle, 1, MenuRect) then ;
2639 Result := Point(MenuRect.Left-10, MenuRect.Top-10);}
2640 Result := GetSurfacePreviewPositionScriptPoint(w, h);
2643 function TfrmSender.GetSurfacePreviewPositionScriptPoint(w, h: integer): TPoint;
2644 var MousePoint: TPoint;
2646 GetCursorPos(MousePoint);
2647 case Pref.SurfacePreviewOnScriptPointPosition of
2648 spspMainWindowRight:
2649 Result := Point(Self.Left + Self.Width, MousePoint.Y);
2651 Result := Point(Self.Left - w, MousePoint.Y);
2655 procedure TfrmSender.mnConstGroupClick(Sender: TObject);
2657 if (Sender is TMenuItem) then
2658 FVisibleMenuItem := Sender as TMenuItem;
2661 procedure TfrmSender.actRecallScriptBufferExecute(Sender: TObject);
2663 if FScriptBuffer.Count = 0 then
2665 memScript.Lines.Assign(FScriptBuffer[0] as TStringList);
2666 memScriptChange(Self);
2667 ShowHintLabel('
\83X
\83N
\83\8a\83v
\83g
\82ð
\8cÄ
\82Ñ
\8fo
\82µ
\82Ü
\82µ
\82½');
2670 procedure TfrmSender.EditorPreview;
2671 var Ghost, Script: String;
2673 if frmEditorTalkShow <> nil then
2674 if frmEditorTalkShow.Visible then
2676 Script := StringReplace(GetScriptText, #13#10, '', [rfReplaceAll]);
2678 if cbxTargetGhost.ItemIndex > 0 then
2679 Ghost := cbxTargetGhost.Text
2680 else if FNowChannel <> '' then
2681 Ghost := ChannelList.Channel[FNowChannel].Ghost;
2682 frmEditorTalkShow.TalkShowFrame.View(Script, Ghost);
2686 procedure TfrmSender.actEditorPreviewExecute(Sender: TObject);
2688 if frmEditorTalkShow <> nil then
2689 frmEditorTalkShow.Show
2692 Application.CreateForm(TfrmEditorTalkShow, frmEditorTalkShow);
2693 frmEditorTalkShow.Show;
2698 procedure TfrmSender.actResetPluginsExecute(Sender: TObject);
2700 Spps.ClearImagePool;
2701 Spps.LoadFromDirectory(FSppDir);
2704 procedure TfrmSender.IdSLPP20Connect(Sender: TObject);
2706 ShowHintLabel('SSTP Bottle
\83T
\81[
\83o
\82ª
\8c©
\82Â
\82©
\82è
\82Ü
\82µ
\82½');
2709 function TfrmSender.TagReplace(Script: String; Before,
2710 After: array of String): String;
2711 var BeforeList, AfterList: TStringList;
2714 BeforeList := TStringList.Create;
2715 AfterList := TStringList.Create;
2717 for i := Low(Before) to High(Before) do
2718 BeforeList.Add(Before[i]);
2719 for i := Low(After) to High(After) do
2720 AfterList.Add(After[i]);
2721 Result := TagReplace(Script, BeforeList, AfterList);
2728 function TfrmSender.TagReplace(Script: String; Before,
2729 After: TStrings): String;
2731 Flag, OldLeaveEscape, OldEscapeInvalidMeta: boolean;
2737 OldStr := InputString;
2738 OldLeaveEscape := LeaveEscape;
2739 OldEscapeInvalidMeta := EscapeInvalidMeta;
2740 LeaveEscape := true;
2741 EscapeInvalidMeta := false;
2742 InputString := Script;
2744 for i := 0 to SsParser.Count-1 do
2747 for j := 0 to Before.Count-1 do
2749 if (SsParser.MarkUpType[i] = mtTag) and (SsParser[i] = Before[j]) then
2752 Result := Result + After[j];
2756 Result := Result + SsParser[i];
2760 LeaveEscape := OldLeaveEscape;
2761 EscapeInvalidMeta := OldEscapeInvalidMeta;
2762 InputString := OldStr;