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;
321 function DoTrans(var Script: String;
322 Options: TScriptTransOptions): String;
323 function ScriptTransForSSTP(const Script: String): String;
324 procedure BeginConnect;
325 procedure RetryBeginConnect;
326 procedure EndConnect;
327 procedure ConstructMenu(Simple: boolean);
328 property Connecting: boolean read FConnecting write SetConnecting;
329 property BottleSstp: TBottleSstp read FBottleSstp;
330 function SetHWndToFavoriteGhost(const Ghost: String): String;
331 function GhostNameToSetName(const Ghost: String): String;
332 procedure PostCommand(const Command: array of String); overload;
333 procedure PostCommand(Command: TStrings); overload;
334 procedure PostSetChannel(Channels: TStrings);
335 procedure SaveChainRuleList;
340 frmSender: TfrmSender;
343 PanelConnecting = 0; //
\81u
\90Ú
\91±
\92\86\81v
\95\
\8e¦
\97p
344 PanelBytes = 1; //
\81\9b\81\9b\83o
\83C
\83g
345 PanelCount = 2; //Local Proxy
\81A
\8c»
\8dÝ
\81\9b\8c\8f\91Ò
\82¿
347 PanelStatus = 4; //SSTP Bottle
\83T
\81[
\83o
\82É
\93o
\98^
\82³
\82ê
\82Ä
\82¢
\82Ü
\82·
\81c
\82È
\82Ç
350 IconDisconnected = 18;
352 IconSleepDisconnected = 20;
354 WarningColor = clRed;
356 SendButtonLongHint = 'Bottle
\82Ì
\91\97\90M';
358 function Token(const Str: String; const Delimiter: char;
359 const Index: integer): String;
363 uses SendConfirm, SettingForm, ChannelListForm, LogForm,
364 MessageBox, FMOExplorer, EditorTalkShow;
368 //
\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
369 function Token(const Str: String; const Delimiter: char;
370 const Index: integer): String;
371 var i, c, len: integer;
377 while i <= len do begin
378 if (Str[i] = Delimiter) and (StrByteType(PChar(Str), i) <> mbTrailByte) then begin
380 if c > Index then Break;
381 end else if c = Index then Result := Result + Str[i];
388 procedure TfrmSender.actConfirmExecute(Sender: TObject);
389 var Res: TSstpResult;
390 Script, Ghost, Err: String;
391 Opt: TScriptTransOptions;
393 if Length(GetScriptText) = 0 then Exit;
395 Script := GetScriptText;
396 if Pref.IgnoreTimeCritical then
397 Opt := [toIgnoreTimeCritical, toWarnCheck]
399 Opt := [toWarnCheck];
400 if Pref.NoTransUrl then Opt := Opt + [toNoChoice];
401 if Pref.HUTagTo01Tag then Opt := Opt + [toHUTagTo01Tag];
402 Err := DoTrans(Script, Opt + [toConvertURL, toWarnMessySurface]);
403 if Err <> '' then begin
407 if cbxTargetGhost.ItemIndex > 0 then begin
408 Ghost := cbxTargetGhost.Text
410 if FNowChannel <> '' then
411 Ghost := ChannelList.Channel[FNowChannel].Ghost;
413 Ghost := SetHWndToFavoriteGhost(Ghost);
414 DirectSstp.SstpSender := 'SSTP Bottle -
\81y
\8am
\94F
\81z';
416 Res := DirectSstp.SstpSEND(Script, [soNoTranslate], GhostNameToSetName(Ghost));
417 if Res <> srOk then begin
418 ShowHintLabel('
\91\97\90M
\8e¸
\94s:' + DirectSstp.RecvLog, WarningColor);
421 FScriptModified := false;
425 procedure TfrmSender.FormCreate(Sender: TObject);
426 var Str: TStringList;
428 FScriptBuffer := TObjectList.Create(true);
430 SakuraSeeker.OnDetectResultChanged := SakuraSeekerDetectResultChanged;
431 FConstDir := ExtractFileDir(Application.ExeName)+'\consts';
432 ScriptConstList.LoadFromDir(FConstDir);
433 FSppDir := ExtractFileDir(Application.ExeName)+'\spp';
434 Spps.LoadFromDirectory(FSppDir);
435 ConstructMenu(false);
437 Str := TStringList.Create;
440 Str.LoadFromFile(ExtractFilePath(Application.ExeName)+'rule.txt');
441 BottleChainRuleList := StringToComponent(Str.Text) as TBottleChainRuleList;
444 Str.LoadFromFile(ExtractFilePath(Application.ExeName)+'defrule.txt');
445 BottleChainRuleList := StringToComponent(Str.Text) as TBottleChainRuleList;
447 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');
448 Application.Terminate;
449 Application.ProcessMessages;
457 FOriginalCaption := Self.Caption;
460 ShowMessage('
\93ñ
\8fd
\8bN
\93®
\8b\96\89Â
\83o
\81[
\83W
\83\87\83\93\82Å
\82·
\81B'#13#10 + VersionString);
462 FMutex := CreateMutex(nil, true, 'SSTPBottleClient2');
463 if GetLastError = ERROR_ALREADY_EXISTS then begin
465 ShowMessage('SSTP Bottle Client
\82Í
\93ñ
\8fd
\8bN
\93®
\82Å
\82«
\82Ü
\82¹
\82ñ');
467 Application.Terminate;
468 Application.ProcessMessages; //WM_QUIT
\82ð
\97¬
\82·
474 mnShowToolBar.Checked := Pref.ShowToolBar;
475 mnShowConstBar.Checked := Pref.ShowConstBar;
476 if Pref.StayOnTop then begin
477 FormStyle := fsStayOnTop;
478 mnStayOnTop.Checked := true;
480 FormStyle := fsNormal;
481 mnStayOnTop.Checked := false;
484 mnGoToHP.Hint := Pref.HomePage;
485 mnGotoGlog.Hint := Pref.GLogPage;
486 mnGotoVote.Hint := Pref.VotePage;
487 mnGotoHelp.Hint := Pref.HelpPage;
489 mnGetNewId.Enabled := (Pref.LUID = '');
492 SsParser.TagPattern.LoadFromFile(ExtractFilePath(Application.Exename) + 'tagpat.txt');
493 SsParser.MetaPattern.LoadFromFile(ExtractFilePath(Application.ExeName) + 'metapat.txt');
495 ShowMessage('tagpat.txt, metapat.txt
\82ª
\8c©
\82Â
\82©
\82è
\82Ü
\82¹
\82ñ
\81B');
496 Application.Terminate;
499 with Pref.SenderWindowPosition do begin
502 Self.Width := Right - Left + 1;
503 Self.Height := Bottom - Top + 1;
506 actClearExecute(Sender);
508 UpdateJoinChannelList(nil);
510 // SSTP
\8dÄ
\91\97\83I
\83u
\83W
\83F
\83N
\83g
511 FBottleSstp := TBottleSstp.Create(false);
512 with FBottleSstp do begin
513 OnResendCountChange := BottleSstpResendCountChange;
514 OnResendTrying := BottleSstpResendTrying;
515 OnResendEnd := BottleSstpResendEnd;
519 procedure TfrmSender.FormDestroy(Sender: TObject);
521 if FScriptBuffer <> nil then
524 if FBottleSstp <> nil then begin
525 FBottleSstp.Terminate;
529 with Pref.SenderWindowPosition do begin
532 Right := Self.Left + Self.Width - 1;
533 Bottom := Self.Top + Self.Height - 1;
536 if JoinChannelsBackup <> nil then JoinChannelsBackup.Free;
538 ScriptConstList.Save;
541 BottleChainRuleList.Free;
544 ReleaseMutex(FMutex);
549 procedure TfrmSender.SetConnecting(const Value: boolean);
551 FConnecting := Value;
553 StatusBar.Panels[PanelConnecting].Text := '
\92Ê
\90M
\92\86';
554 actStart.Enabled := false;
555 actStop.Enabled := false;
556 actSend.Enabled := false;
557 actVoteMessage.Enabled := false;
558 actAgreeMessage.Enabled := false;
559 mnGetNewId.Enabled := false;
560 Screen.Cursor := crAppStart;
562 StatusBar.Panels[PanelConnecting].Text := '';
563 actStart.Enabled := true;
564 actStop.Enabled := true;
565 actSend.Enabled := true;
566 //actVoteMessage.Enabled := true;
567 //actAgreeMessage.Enabled := true;
568 frmLog.lvwLogChange(Self, nil, ctState);
569 mnGetNewId.Enabled := Pref.LUID = '';
570 Screen.Cursor := crDefault;
574 procedure TfrmSender.actSendExecute(Sender: TObject);
575 var Talk, Ghost: String;
576 Command: TStringList;
580 if Length(GetScriptText) = 0 then begin
581 ShowMessage('
\83X
\83N
\83\8a\83v
\83g
\82ª
\8bó
\82Å
\82·
\81B');
585 if Pref.LUID = '' then begin
589 if tabChannel.TabIndex < 0 then begin
590 ShowMessage('
\83`
\83\83\83\93\83l
\83\8b\82É
\8eQ
\89Á
\82µ
\82Ä
\82¢
\82Ü
\82¹
\82ñ
\81B'#13#10+
591 '
\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');
594 if ChannelList.Channel[FNowChannel].NoPost then begin
596 ShowMessage(FNowChannel + '
\82Í
\8eó
\90M
\90ê
\97p
\82Å
\82·');
600 if Pref.NeedConfirmBeforeSend and FScriptModified then begin
601 MessageDlg('
\91\97\90M
\91O
\82É
\83\8d\81[
\83J
\83\8b\8am
\94F
\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81B', mtError, [mbOk], 0);
605 if not Pref.NoConfirm then begin
606 if not SendConfirmDialog(FNowChannel, cbxTargetGhost.Text) then Exit;
610 Talk := GetScriptText;
611 Err := DoTrans(Talk, [toWarnMessySurface, toWarnCheck]);
612 if Err <> '' then begin
613 MessageDlg(Err, mtWarning, [mbOk], 0);
618 if cbxTargetGhost.ItemIndex > 0 then Ghost := cbxTargetGhost.Text;
620 Command := TStringList.Create;
621 with Command do begin
622 Add('Command: sendBroadcast');
623 Add('Channel: ' + FNowChannel);
624 Add('LUID: ' + Pref.LUID);
625 Add('Agent: ' + VersionString);
626 if Ghost <> '' then Add('Ghost: ' + Ghost);
627 Add('Talk: ' + Talk);
629 PostCommand(Command);
634 //
\91\97\90M
\83\8d\83O
\95Û
\91¶
635 AssignFile(F, ExtractFilePath(Application.ExeName) + SentLogFile);
636 if FileExists(ExtractFilePath(Application.ExeName) + SentLogFile) then
640 WriteLn(F, Format('%s,%s,%s,%s', [FNowChannel, Ghost, FormatDateTime('yy/mm/dd hh:nn:ss', Now), Talk]));
645 procedure TfrmSender.BeginConnect;
647 if Pref.LUID = '' then begin
651 IdSlpp20.LUID := Pref.LUID;
652 self.Cursor := crHourGlass;
654 if IdSlpp20.Connected then IdSlpp20.Disconnect;
655 if Pref.UseHttpProxy then begin
656 IdSlpp20.Host := Pref.ProxyAddress;
657 IdSlpp20.Port := Pref.ProxyPort;
658 IdSlpp20.ProxyMode := true;
660 IdSlpp20.Host := 'bottle.mikage.to';
661 IdSlpp20.Port := 9871;
662 IdSlpp20.ProxyMode := false;
666 on EIdException do begin
668 if FBeginConnectFailCount = 0 then begin
669 Inc(FBeginConnectFailCount);
671 if Pref.UseHttpProxy then
672 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 +
673 '
\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 +
674 '
\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')
676 ShowMessage('SSTP Bottle
\83T
\81[
\83o
\82É
\90Ú
\91±
\82Å
\82«
\82Ü
\82¹
\82ñ
\82Å
\82µ
\82½
\81B'#13#10 +
677 '
\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 +
678 '
\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');
680 Inc(FBeginConnectFailCount);
683 self.Cursor := crDefault;
686 procedure TfrmSender.EndConnect;
688 IdSlpp20.OnDisconnect := nil;
692 procedure TfrmSender.SetAdded(const Value: boolean);
694 if FAdded = Value then Exit;
697 StatusText := 'SSTP Bottle
\83T
\81[
\83o
\82É
\90Ú
\91±
\82³
\82ê
\82Ä
\82¢
\82Ü
\82·';
700 StatusText := '
\83T
\81[
\83o
\82Æ
\82Ì
\90Ú
\91±
\82ª
\90Ø
\82ê
\82Ä
\82¢
\82Ü
\82·!';
702 ShowHintLabel('SSTP Bottle
\83T
\81[
\83o
\82©
\82ç
\90Ø
\92f
\82³
\82ê
\82Ü
\82µ
\82½!', WarningColor);
706 procedure TfrmSender.HTTPSuccess(Sender: TObject);
707 var Str, ResStr, Command: String;
708 HeadValue: THeadValue;
710 SetChannel: TStringList;
713 Str := (Sender as THttpDownloadThread).RecvString;
717 HeadValue := THeadValue.Create(Str);
719 ShowMessage('SSTP Bottle
\83T
\81[
\83o
\82ª
\89ð
\90Í
\82Å
\82«
\82È
\82¢
\83G
\83\89\81[
\82ð
\95Ô
\82µ
\82Ü
\82µ
\82½
\81B');
722 Command := HeadValue['Command'];
723 ResStr := HeadValue['Result'];
724 if ResStr = 'Err' then begin
725 if HeadValue['ExtraMessage'] <> '' then begin
727 ShowMessage('SSTP Bottle
\83T
\81[
\83o
\82ª
\8e\9f\82Ì
\83G
\83\89\81[
\82ð
\95Ô
\82µ
\82Ü
\82µ
\82½:'#13#10 +
728 HeadValue['ExtraMessage']);
731 ShowMessage('SSTP Bottle
\83T
\81[
\83o
\82ª
\89½
\82ç
\82©
\82Ì
\83G
\83\89\81[
\82ð
\95Ô
\82µ
\82Ü
\82µ
\82½
\81B');
734 if (Command = 'sendBroadcast') and (ResStr = 'OK') then begin
735 ShowHintLabel(HeadValue['Channel'] + '
\82Ì ' + HeadValue['SentNum'] +
736 '
\90l
\82É
\91\97\90M
\82µ
\82Ü
\82µ
\82½');
737 //
\83S
\81[
\83X
\83g
\82ð
\83f
\83t
\83H
\83\8b\83g
\82É
\96ß
\82·
738 if Pref.ResetIfGhostAfterSend then begin
739 actResetGhostExecute(Self);
741 //
\83X
\83N
\83\8a\83v
\83g
\82ð
\83N
\83\8a\83A
742 if Pref.ClearAfterSend then begin
745 end else if (Command = 'sendBroadcast') and (ResStr <> 'OK') then begin
746 ShowHintLabel('
\83\81\83b
\83Z
\81[
\83W
\82ð
\91\97\90M
\82Å
\82«
\82Ü
\82¹
\82ñ
\82Å
\82µ
\82½', WarningColor);
748 if (Command = 'getNewId') then begin
749 if ResStr = 'OK' then begin
750 Pref.LUID := HeadValue['NewID'];
751 ShowHintLabel('LUID
\8eæ
\93¾
\8a®
\97¹
\81B');
752 mnGetNewId.Enabled := false;
755 ShowHintLabel('LUID
\8eæ
\93¾
\82É
\8e¸
\94s
\82µ
\82Ü
\82µ
\82½');
758 if (Command = 'voteMessage') then begin
759 if ResStr = 'OK' then begin
760 ShowHintLabel('
\83\81\83b
\83Z
\81[
\83W
\82É
\93\8a\95[/
\93¯
\88Ó
\82µ
\82Ü
\82µ
\82½
\81B
\95[
\90\94: ' + HeadValue['Votes']);
763 if (Command = 'getChannels') and (ResStr = 'OK') then begin
764 UpdateChannelInfo(HeadValue);
767 if FAutoAddAfterGetChannel then begin
768 SetChannel := TStringList.Create;
769 if JoinChannelsBackup <> nil then begin
770 //
\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
771 SetChannel.Assign(JoinChannelsBackup);
773 //
\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¾
774 for i := 0 to Pref.AutoJoinChannels.Count-1 do begin
775 if ChannelList.Channel[Pref.AutoJoinChannels[i]] <> nil then
776 SetChannel.Add(Pref.AutoJoinChannels[i]);
780 if frmChannelList.Execute(ChannelList, JoinChannels) then begin
781 SetChannel := TStringList.Create;
782 SetChannel.Assign(frmChannelList.JoinList);
785 if SetChannel <> nil then PostSetChannel(SetChannel);
787 if SetChannel <> nil then FreeAndNil(SetChannel);
790 if (Command = 'setChannels') then begin
791 if ResStr <> 'OK' then begin
793 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¢');
794 ShowHintLabel('
\83`
\83\83\83\93\83l
\83\8b\90Ý
\92è
\82É
\8e¸
\94s
\82µ
\82Ü
\82µ
\82½', WarningColor);
797 if HeadValue['ExtraTip'] <> '' then ShowHintLabel(HeadValue['ExtraTip']);
803 procedure TfrmSender.actStartClick(Sender: TObject);
805 if Pref.LUID = '' then begin
809 if not IdSlpp20.Connected then begin
810 FBeginConnectFailCount := 0; //
\8e©
\93®
\8dÄ
\90Ú
\91±
\83J
\83E
\83\93\83^
\83\8a\83Z
\83b
\83g
814 FAutoAddAfterGetChannel := false;
815 PostCommand(['Command: getChannels']);
819 procedure TfrmSender.actStopExecute(Sender: TObject);
821 //
\8b
\90§
\8dÄ
\90Ú
\91±
\82ð
\8ds
\82¤
822 IdSlpp20.OnDisconnect := nil;
823 if IdSlpp20.Connected then IdSlpp20.Disconnect;
824 FAutoAddAfterGetChannel := true;
826 IdSlpp20.OnDisconnect := Slpp20Disconnect;
829 procedure TfrmSender.FormShow(Sender: TObject);
831 if FBooted or Application.Terminated then Exit;
832 //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
833 if Pref.LUID <> '' then BeginConnect
834 else mnGetNewIdClick(Self);
835 FAutoAddAfterGetChannel := Pref.AutoStart;
838 frmSurfacePreview.Show;
840 SakuraSeekerDetectResultChanged(Self);
843 procedure TfrmSender.mnAboutClick(Sender: TObject);
846 Str := VersionString + #13#10 + BottleDisclaimer + #13#10#13#10;
847 Str := Str + Format('Compiler Version: %f', [CompilerVersion]);
848 frmMessageBox.ShowMessage(Str);
851 procedure TfrmSender.actExitClientExecute(Sender: TObject);
856 procedure TfrmSender.actClearExecute(Sender: TObject);
857 var TmpScript: String;
859 DoSaveBuffer: boolean;
860 SavedScript: TStringList;
862 //
\83X
\83N
\83\8a\83v
\83g
\82Ì
\83N
\83\8a\83A
863 //
\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é
864 DoSaveBuffer := false;
865 if FScriptBuffer.Count = 0 then
867 else if (FScriptBuffer[0] as TStringList).Text <> GetScriptText then
868 DoSaveBuffer := true;
869 if (GetScriptText = Pref.DefaultScript) or (GetScriptText = '') then
870 DoSaveBuffer := false;
873 SavedScript := TStringList.Create;
874 SavedScript.Text := GetScriptText;
875 FScriptBuffer.Insert(0, SavedScript);
877 if FScriptBuffer.Count >= 4 then
878 FScriptBuffer.Delete(FScriptBuffer.Count-1);
879 actRecallScriptBuffer.Enabled := FScriptBuffer.Count > 0;
881 TmpScript := Pref.DefaultScript;
882 Position := Pos('|', TmpScript);
883 if Position < 1 then Position := 1;
884 TmpScript := StringReplace(TmpScript, '|', '', []);
885 memScript.Lines.Text := TmpScript;
886 Sendmessage(memScript.Handle, WM_VSCROLL, SB_LINEUP, 0);
887 memScript.SelStart := Position-1;
889 if Visible then memScript.SetFocus;
890 FScriptModified := false;
891 memScriptChange(self);
894 procedure TfrmSender.memScriptChange(Sender: TObject);
897 Script := StringReplace(GetScriptText, #13#10, '', [rfReplaceAll]);
898 StatusBar.Panels[PanelBytes].Text := IntToStr(length(Script)) + '
\83o
\83C
\83g';
899 FScriptModified := true;
903 procedure TfrmSender.mnStayOnTopClick(Sender: TObject);
905 Pref.StayOnTop := not Pref.StayOnTop;
906 mnStayOnTop.Checked := Pref.StayOnTop;
907 if Pref.StayOnTop then begin
908 FormStyle := fsStayOnTop;
910 FormStyle := fsNormal;
915 function TfrmSender.GetScriptText: String;
917 Result := memScript.Lines.Text;
920 procedure TfrmSender.mnConstClick(Sender: TObject);
923 i := (Sender as TMenuItem).Tag;
924 memScript.SelText := ScriptConstList.GetConstByID(i).ConstText;
927 procedure TfrmSender.actEditConstExecute(Sender: TObject);
929 ScriptConstList.LoadFromDir(FConstDir);
931 Application.CreateForm(TfrmConstEditor, frmConstEditor);
932 frmConstEditor.Execute;
933 ScriptConstList.Save;
935 frmConstEditor.Release;
937 ConstructMenu(false);
940 procedure TfrmSender.mnTaskBarClick(Sender: TObject);
942 Application.Minimize;
943 WindowState := wsNormal;
946 procedure TfrmSender.FormClose(Sender: TObject; var Action: TCloseAction);
949 TaskTray.Registered := false;
952 procedure TfrmSender.ApplicationEventsMinimize(Sender: TObject);
955 Application.ShowMainForm := false;
956 ShowWindow(Application.Handle, SW_HIDE);
959 procedure TfrmSender.ApplicationEventsRestore(Sender: TObject);
961 Application.ShowMainForm := true;
965 procedure TfrmSender.mnTaskRestoreClick(Sender: TObject);
970 procedure TfrmSender.TaskTrayDblClick(Seft: TObject; Button: TMouseButton);
975 procedure TfrmSender.FormActivate(Sender: TObject);
980 procedure TfrmSender.mnTaskNewMessageClick(Sender: TObject);
983 actClearExecute(Sender);
986 procedure TfrmSender.ChangeTaskIcon;
991 if Sleeping then IcoNum := IconSleep else IcoNum := IconConnected;
993 if Sleeping then IcoNum := IconSleepDisconnected
994 else IcoNum := IconDisconnected;
999 imgIcon.GetIcon(IcoNum, Ico);
1000 TaskTray.Icon := Ico;
1001 TaskTray.Registered := true;
1006 ; // 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
1007 //
\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
1008 //
\82»
\82Ì
\8fê
\8d\87\82Í
\83G
\83\89\81[
\82ð
\96³
\8e\8b\82·
\82é
1012 procedure TfrmSender.SetStatusText(const Value: String);
1014 FStatusText := Value;
1015 StatusBar.Panels[PanelStatus].Text := Value;
1018 procedure TfrmSender.ApplicationEventsHint(Sender: TObject);
1021 if Length(Application.Hint) > 0 then
1023 StatusBar.Panels[PanelStatus].Text := GetLongHint(Application.Hint);
1024 Application.HintColor := clInfoBk;
1025 if (Application.Hint = SendButtonLongHint)
1026 and (FNowChannel <> '') then
1028 //
\91\97\90M
\83{
\83^
\83\93\82Ì
\8fê
\8d\87\82Í
\91¬
\8dU
\8fo
\82·
1029 Application.HintColor := clYellow;
1030 Application.ActivateHint(Mouse.CursorPos);
1032 if IsSurfaceTag(Application.Hint, id) and Pref.SurfacePreviewOnHint then
1034 //
\83T
\81[
\83t
\83B
\83X
\83v
\83\8c\83r
\83\85\81[
1035 DoSurfacePreview(id, spHint);
1039 StatusBar.Panels[PanelStatus].Text := FStatusText;
1040 frmSurfacePreview.HideAway;
1044 procedure TfrmSender.ConstructMenu(Simple: boolean);
1046 BuildMenu(mnPopConst, Simple);
1047 BuildMenu(mnPopUpConst.Items, Simple);
1048 BuildMenu(ConstBarMenu.Items, Simple);
1049 //ConstMenuBar.Menu := nil;
1050 ConstMenuBar.AutoSize := false;
1051 ConstMenuBar.Width := 1000;
1052 ConstMenuBar.Menu := ConstBarMenu;
1053 ConstMenuBar.AutoSize := true;
1056 procedure TfrmSender.memScriptKeyDown(Sender: TObject; var Key: Word;
1057 Shift: TShiftState);
1059 Func: TReturnKeyFunction;
1061 if (Key = VK_RETURN) then begin
1062 if (ssShift in Shift) then
1063 Func := Pref.WhenShiftReturn
1064 else if (ssCtrl in Shift) then
1065 Func := Pref.WhenCtrlReturn
1067 Func := Pref.WhenReturn;
1070 with tbtnInsertConst do
1071 Pos := tbtnInsertConst.ClientToScreen(Point(0, Height));
1072 mnPopUpConst.Popup(Pos.X, Pos.Y);
1075 memScript.SelText := '\n';
1079 memScript.SelText := '\n'#13#10;
1082 memScript.SelText := #13#10
1088 procedure TfrmSender.mnShowToolBarClick(Sender: TObject);
1090 mnShowToolBar.Checked := not mnShowToolBar.Checked;
1091 Pref.ShowToolBar := mnShowToolBar.Checked;
1095 procedure TfrmSender.mnShowConstBarClick(Sender: TObject);
1097 mnShowConstBar.Checked := not mnShowConstBar.Checked;
1098 Pref.ShowConstBar := mnShowConstBar.Checked;
1102 procedure TfrmSender.UpdateLayout;
1104 with SakuraScriptFountain do begin
1105 TagColor.Color := Pref.MarkUpColor;
1106 TagErrorColor.Color := Pref.MarkErrorColor;
1107 Scope0Color.Color := Pref.TalkColorH;
1108 Scope1Color.Color := Pref.TalkColorU;
1109 SynchronizedColor.Color := Pref.TalkColorS;
1111 memScript.Ruler.Visible := Pref.ShowRuler;
1112 memScript.Ruler.Color := Pref.TalkColorH;
1113 memScript.Color := Pref.BgColor;
1115 ToolBar.Visible := Pref.ShowToolBar;
1116 ConstMenuBar.Visible := Pref.ShowConstBar;
1119 with tabChannel do begin
1120 TabPosition := Pref.TabPosition;
1121 case Pref.TabPosition of
1122 tpTop: Align := alTop;
1123 tpBottom: Align := alBottom;
1128 function TfrmSender.DoTrans(var Script: String;
1129 Options: TScriptTransOptions): String;
1130 var UrlCancel, Mark: String;
1131 Url, UrlName: array[0..6] of String;
1132 i, j, u, UrlCount: integer;
1133 LastSurfaceH, LastSurfaceU: integer;
1134 UnyuTalking: boolean;
1135 QuickSection, Synchronize: boolean;
1136 Warnings: TStringList;
1141 UnyuTalking := false;
1142 QuickSection := false;
1143 Synchronize := false;
1144 SsParser.LeaveEscape := true;
1145 SsParser.EscapeInvalidMeta := false;
1146 SsParser.InputString := Script;
1148 Warnings := TStringList.Create;
1150 for i := 0 to SsParser.Count-1 do begin
1151 if SsParser[i] = '\t' then begin
1152 if not(toIgnoreTimeCritical in Options) then
1153 Script := Script + '\t';
1154 end else if SsParser[i] = '\e' then begin
1156 end else if (SsParser.Match(SsParser[i], '\URL%b') > 0) then begin
1157 if toConvertURL in Options then begin
1158 UrlCount := 0; //
\91O
\82ÌURL
\83^
\83O
\82Ì
\89e
\8b¿
\82ð
\96³
\8e\8b\81B
1159 for u := 7 downto 1 do begin
1160 if (SsParser.Match(SsParser[i],
1161 '\URL%b'+StringReplace(StringOfChar('-', u*2),
1162 '-', '%b', [rfReplaceAll]))) > 0 then begin
1163 for j := 1 to u do begin
1164 Url[UrlCount] := SsParser.GetParam(SsParser[i], UrlCount*2+2);
1165 UrlName[UrlCount] := SsParser.GetParam(SsParser[i], UrlCount*2+3);
1166 if UrlName[UrlCount] = '' then UrlName[UrlCount] := Url[UrlCount];
1167 if Pos('http://', Url[UrlCount]) > 0 then Inc(UrlCount);
1170 if UrlCount > 0 then UrlCancel := SsParser.GetParam(SsParser[i], 1);
1171 if UrlCancel = '' then UrlCancel := '
\8ds
\82©
\82È
\82¢
\81@
\81@
\81@
\81@';
1173 if SsParser.Match(SsParser[i], '\URL%b%b') = 0 then begin //
\8aÈ
\88Õ
\94ÅURL
\95Ï
\8a·
1174 //
\8aÈ
\88Õ
\8c`
\8e®\URL
\83^
\83O
\95Ï
\8a·
1175 Url[0] := SsParser.GetParam(SsParser[i], 1);
1176 UrlName[0] := '
\8ds
\82
\81@
\81@
\81@
\81@
\81@
\81@';
1177 UrlCancel := '
\8ds
\82©
\82È
\82¢
\81@
\81@
\81@
\81@';
1178 if Pos('http://', Url[0]) > 0 then begin
1180 if not QuickSection then
1181 Script := Script + '\_q' + Url[0] + '\_q'
1183 Script := Script + Url[0];
1186 end else Script := Script + SsParser[i];
1188 Mark := SsParser[i];
1189 if Mark = '\h' then begin
1190 UnyuTalking := false;
1191 if toHUTagTo01Tag in Options then Mark := '\0';
1192 if Synchronize and Pref.WarnScopeChangeInSynchronize then
1193 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');
1194 end else if Mark = '\u' then begin
1195 UnyuTalking := true;
1196 if toHUTagTo01Tag in Options then Mark := '\1';
1197 if Synchronize and Pref.WarnScopeChangeInSynchronize then
1198 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');
1199 end else if Mark = '\_q' then begin
1200 QuickSection := not QuickSection;
1201 end else if Mark = '\_s' then begin
1202 Synchronize := not Synchronize;
1203 end else if SsParser.Match(Mark, '\s%b') > 0 then begin
1204 if UnyuTalking then begin
1205 LastSurfaceU := StrToIntDef(SsParser.GetParam(Mark, 1),
1208 LastSurfaceH := StrToIntDef(SsParser.GetParam(Mark, 1),
1211 end else if SsParser.Match(Mark, '\s%d') > 0 then begin
1212 if UnyuTalking then begin
1213 LastSurfaceU := StrToIntDef(Mark[3], LastSurfaceU);
1215 LastSurfaceH := StrToIntDef(Mark[3], LastSurfaceH);
1218 Script := Script + Mark;
1221 if UrlCount > 0 then begin
1222 Script := Script + '\h\n';
1223 if not (toNoChoice in Options) then begin
1224 for i := 0 to UrlCount-1 do begin
1225 Script := Script + Format('\q%d[%s][%s]',
1226 [i, SsParser.EscapeParam(Url[i]), UrlName[i]]);
1228 Script := Script + Format('\q%d[#cancel][%s]', [UrlCount, UrlCancel]);
1229 //Script := Script + '\z'; //
\8dÅ
\90Vphase
\82Å
\82Í
\8dí
\8f\9c
1231 Script := Script + '\h';
1232 for i := 0 to UrlCount-1 do begin
1233 Script := Script + Format('\n{%s}(%s)', [UrlName[i], Url[i]]);
1234 Script := Script + Format('\n{%s}', [UrlCancel]);
1238 //
\83X
\83N
\83\8a\83v
\83g
\82Ì
\8dÅ
\8cã
\82É
\83E
\83F
\83C
\83g
\91}
\93ü
1239 if toWaitScriptEnd in Options then begin
1240 i := Pref.WaitScriptEnd;
1241 while i > 0 do begin
1243 Script := Script + '\w9';
1246 Script := Script + '\w' + IntToStr(i);
1252 Script := Script + '\e';
1253 RegExp.Subst('s/\r\n//gk', Script);
1255 //
\83^
\83O
\83`
\83F
\83b
\83N
\8aÖ
\98A
1256 for i := 0 to SsParser.Count-1 do begin
1257 if SsParser.MarkUpType[i] = mtTagErr then begin
1258 Result := '"' + SsParser[i] + '"'#13#10 +
1259 '
\82Í
\81ASSTP Bottle
\82Å
\94F
\82ß
\82ç
\82ê
\82È
\82¢
\82©
\81A
\94F
\8e¯
\82Å
\82«
\82È
\82¢
\83^
\83O
\82Å
\82·
\81B';
1263 if (SsParser[0] <> '\t') and Pref.WarnYenTNotExist then begin
1264 Warnings.Add('
\83X
\83N
\83\8a\83v
\83g
\82ª\t
\82©
\82ç
\8en
\82Ü
\82Á
\82Ä
\82¢
\82Ü
\82¹
\82ñ
\81B');
1268 if (Warnings.Count > 0) and (toWarnCheck in Options) then begin
1269 if MessageDlg(Warnings.Text + #13#10 + '
\91\97\90M
\82µ
\82Ü
\82·
\82©?', mtWarning,
1270 mbOkCancel, 0) = mrCancel then
1271 Result := Warnings.Text;
1278 procedure TfrmSender.mnGoToHPClick(Sender: TObject);
1280 ShellExecute(Handle, 'open', PChar(Pref.HomePage), nil, nil, SW_SHOW);
1283 procedure TfrmSender.ShowHintLabel(const Mes: String; Col: TColor);
1285 lblMessage.Caption := Mes;
1286 lblMessage.Font.Color := Col;
1287 lblMessage.Visible := true;
1288 LabelTimer.Enabled := false;
1289 LabelTimer.Enabled := true;
1292 procedure TfrmSender.LabelTimerTimer(Sender: TObject);
1294 LabelTimer.Enabled := false;
1295 lblmessage.Visible := false;
1298 procedure TfrmSender.actCopyAllExecute(Sender: TObject);
1302 Str := memScript.Lines.Text;
1303 Clip := ClipBoard();
1304 Clip.SetTextBuf(PChar(Str));
1307 procedure TfrmSender.actCopyAllNoReturnExecute(Sender: TObject);
1311 Str := memScript.Lines.Text;
1312 RegExp.Subst('s/\r\n//gk', Str);
1313 Clip := ClipBoard();
1314 Clip.SetTextBuf(PChar(Str));
1317 procedure TfrmSender.Slpp20SlppEvent(Sender: TObject; EventType: TIdSlppEventType;
1318 const Param: String);
1319 var HeadValue: THeadValue;
1321 HeadValue := THeadValue.Create(Param);
1324 etScript, etForceBroadcast, etUnicast: begin
1325 //
\83\81\83b
\83Z
\81[
\83W
\8eó
\90M
1326 DispatchBottle(EventType, HeadValue);
1328 etMemberCount: begin
1329 StatusBar.Panels[PanelMembers].Text := HeadValue['Num'] + '
\90l'
1331 etChannelCount: begin
1333 ChannelList.Channel[HeadValue['Channel']].Members := StrToInt(HeadValue['Num']);
1338 ShowHintLabel('SSTP Bottle
\83T
\81[
\83o
\82Æ
\92Ê
\90M
\8am
\97§
\81B');
1340 FBeginConnectFailCount := 0;
1341 //
\83`
\83\83\83\93\83l
\83\8b\8e©
\93®
\93o
\98^
1342 if not Connecting then
1343 PostCommand(['Command: getChannels']);
1344 SakuraSeeker.BeginDetect;
1345 if SakuraSeeker.Count = 0 then
1346 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 +
1347 '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 +
1348 '
\8fÚ
\8d×
\82Í
\83w
\83\8b\83v
\82ð
\82²
\97\97\89º
\82³
\82¢
\81B');
1350 etChannelList: begin
1351 UpdateJoinChannelList(HeadValue);
1352 //
\8dÅ
\8cã
\82É
\8eQ
\89Á
\82µ
\82Ä
\82¢
\82½
\83`
\83\83\83\93\83l
\83\8b\82ð
\8bL
\98^
\82·
\82é
1353 if JoinChannelsBackup = nil then JoinChannelsBackup := TStringList.Create;
1354 JoinChannelsBackup.Assign(JoinChannels);
1356 etCloseChannel: begin
1357 with JoinChannels do
1358 if IndexOf(HeadValue['Channel']) >= 0 then
1359 Delete(IndexOf(HeadValue['Channel']));
1360 with tabChannel do begin
1361 if Tabs.IndexOf(HeadValue['Channel']) >= 0 then
1362 Tabs.Delete(Tabs.IndexOf(HeadValue['Channel']));
1363 if Tabs.Count > 0 then TabIndex := 0 else TabIndex := -1;
1364 tabChannelChange(self);
1366 ShowHintLabel(HeadValue['Channel'] + '
\83`
\83\83\83\93\83l
\83\8b\82Í
\94p
\8e~
\82³
\82ê
\82Ü
\82µ
\82½',
1368 frmLog.AddCurrentSystemLog('SYSTEM', HeadValue['Channel'] + '
\83`
\83\83\83\93\83l
\83\8b\82Í
\94p
\8e~
\82³
\82ê
\82Ü
\82µ
\82½');
1369 frmMessageBox.ShowMessage(HeadValue['Channel'] + '
\83`
\83\83\83\93\83l
\83\8b\82Í
\94p
\8e~
\82³
\82ê
\82Ü
\82µ
\82½');
1371 etForceBroadcastInformation: begin
1372 if HeadValue['Type'] = 'Vote' then begin
1373 frmLog.VoteLog(HeadValue['MID'], StrToIntDef(HeadValue['Num'], 0));
1374 end else if HeadValue['Type'] = 'Agree' then begin
1375 frmLog.AgreeLog(HeadValue['MID'], StrToIntDef(HeadValue['Num'], 0));
1384 procedure TfrmSender.BottleSstpResendCountChange(Sender: TObject);
1386 StatusBar.Panels[PanelCount].Text := IntToStr(FBottleSstp.CueCount) + '
\8c\8f';
1388 TaskTray.TipString := 'SSTP Bottle Client (' +
1389 IntToStr(FBottleSstp.CueCount) + '
\8c\8f)';
1391 ; //
\83^
\83X
\83N
\83g
\83\8c\83C
\93o
\98^
\8e¸
\94s
\82ð
\96³
\8e\8b\82·
\82é
1393 actClearBottles.Enabled := (FBottleSstp.CueCount > 0);
1396 procedure TfrmSender.actSettingExecute(Sender: TObject);
1398 Application.CreateForm(TfrmSetting, frmSetting);
1410 frmLog.UpdateWindow;
1413 procedure TfrmSender.memScriptKeyPress(Sender: TObject; var Key: Char);
1415 if (Key = #13) or (Key = #10) then Key := Char(0);
1418 procedure TfrmSender.Slpp20Disconnect(Sender: TObject);
1421 UpdateJoinChannelList(nil);
1422 frmLog.AddCurrentSystemLog('SYSTEM', '
\83T
\81[
\83o
\82©
\82ç
\90Ø
\92f
\82³
\82ê
\82Ü
\82µ
\82½');
1423 if not Application.Terminated then RetryBeginConnect;
1426 procedure TfrmSender.SetSleeping(const Value: boolean);
1429 FBottleSstp.ResendSleep := Value;
1433 procedure TfrmSender.actClearBottlesExecute(Sender: TObject);
1436 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]),
1437 mtWarning, mbOkCancel, 0);
1438 if Re = mrOk then begin
1440 frmLog.AllBottleOpened;
1441 frmLog.UpdateWindow;
1445 procedure TfrmSender.SakuraSeekerDetectResultChanged(Sender: TObject);
1448 Http: THTTPDownloadThread;
1451 UpdateIfGhostBox; //
\83h
\83\8d\83b
\83v
\83_
\83E
\83\93\82Ì
\92\86\90g
\82ð
\8f\91\82«
\8a·
\82¦
\82é
1453 if (FLastGhostListSend <> 0) and
1454 (GetTickCount < FLastGhostListSend + 1000*60) then
1458 FLastGhostListSend := GetTickCount;
1460 //
\8d\91\90¨
\92²
\8d¸
\82É
\8eQ
\89Á
1461 if FBooted and not Pref.NoSendGhostList and (SakuraSeeker.Count > 0) then begin
1462 GhostList := 'CCC=' + TIdURI.ParamsEncode('
\88¤');
1463 GhostList := GhostList + '&LUID=' + Pref.LUID;
1465 for i := 0 to SakuraSeeker.Count-1 do begin
1466 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¤
1467 GhostList := GhostList + '&GHOST=' + TIdURI.ParamsEncode(SakuraSeeker[i].SetName);
1471 if SendOk and (FLastGhostList <> GhostList) then begin
1472 FLastGhostList := GhostList;
1473 Http := THTTPDownloadThread.Create(BottleServer, Pref.CgiNameGhost, GhostList);
1474 if Pref.UseHttpProxy then begin
1475 Http.ProxyServer := Pref.ProxyAddress;
1476 Http.ProxyPort := Pref.ProxyPort;
1478 Http.FreeOnTerminate := true;
1484 procedure TfrmSender.UpdateChannelInfo(Dat: THeadValue);
1486 Ch: TChannelListItem;
1489 for i := 1 to Dat.IntData['Count'] do begin
1490 Ch := TChannelListItem.Create;
1491 Ch.Name := Dat[Format('CH%d_name', [i])];
1492 Ch.Ghost := Dat[Format('CH%d_ghost', [i])];
1493 Ch.Info := Dat[Format('CH%d_info', [i])];
1494 Ch.NoPost := Dat[Format('CH%d_nopost', [i])] = '1';
1495 Ch.Members := Dat.IntData[Format('CH%d_count', [i])];
1496 Ch.WarnPost:= Dat[Format('CH%d_warnpost', [i])] = '1';
1497 ChannelList.Add(Ch);
1502 procedure TfrmSender.mnGetNewIdClick(Sender: TObject);
1504 PostCommand(['Command: getNewId', 'Agent: ' + VersionString]);
1507 procedure TfrmSender.NoLuidError;
1510 ShowMessage('SSTP Bottle ID
\82Ì
\8eæ
\93¾
\82ª
\82Ü
\82¾
\8a®
\97¹
\82µ
\82Ä
\82¢
\82Ü
\82¹
\82ñ
\81B'#13#10+
1511 '
\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+
1512 '
\82±
\82Ì
\91\80\8dì
\82ÍClient
\8f\89\89ñ
\8bN
\93®
\8e\9e\82É1
\89ñ
\82¾
\82¯
\95K
\97v
\82Å
\82·
\81B');
1515 procedure TfrmSender.tabChannelChange(Sender: TObject);
1517 if tabChannel.TabIndex >= 0 then begin
1518 FNowChannel := tabChannel.Tabs[tabChannel.TabIndex];
1519 actSend.Hint := Format('
\81u%s
\81v
\82É
\91\97\90M|%s', [FNowChannel, SendButtonLongHint]);
1524 tabChannel.Repaint; //
\82±
\82ê
\82ª
\82È
\82¢
\82Æ
\90F
\82ª
\95Ï
\82í
\82ç
\82È
\82¢
\82±
\82Æ
\82ª
\82 \82é
1525 ConstructMenu(true);
1528 procedure TfrmSender.actPrevChannelExecute(Sender: TObject);
1530 with tabChannel do begin
1531 if Tabs.Count = 0 then Exit;
1532 if TabIndex=0 then TabIndex := Tabs.Count-1
1533 else TabIndex := TabIndex-1;
1535 tabChannelChange(Self);
1538 procedure TfrmSender.actNextChannelExecute(Sender: TObject);
1540 with tabChannel do begin
1541 if Tabs.Count = 0 then Exit;
1542 if TabIndex=Tabs.Count-1 then TabIndex := 0
1543 else TabIndex := TabIndex+1;
1545 tabChannelChange(Self);
1548 procedure TfrmSender.UpdateJoinChannelList(Dat: THeadValue);
1552 nodat := Dat = nil; //nil
\82È
\82ç
\83`
\83\83\83\93\83l
\83\8b\91S
\89ð
\8f\9c
1553 if nodat then Dat := THeadValue.Create('');
1555 for i := 0 to Dat.Count-1 do
1556 if Dat.KeyAt[i] = 'Entry' then begin
1557 if RegExp.Match('m/^(.+?) \((\d+?)\)$/', Dat.ValueAt[i]) then
1558 JoinChannels.Add(RegExp[1]);
1560 with tabChannel do begin
1565 for i := 0 to JoinChannels.Count-1 do begin
1566 //
\8eó
\90M
\90ê
\97p
\83`
\83\83\83\93\83l
\83\8b\82Í
\95\
\8e¦
\82µ
\82È
\82¢
1567 if not ChannelList.Channel[JoinChannels[i]].NoPost then
1568 Tabs.Add(JoinChannels[i]);
1572 for i := 0 to Tabs.Count-1 do
1573 if Tabs[i] = FNowChannel then TabIndex := i;
1574 if Tabs.Count > 0 then begin
1575 FNowChannel := Tabs[TabIndex];
1576 actSend.Hint := Format('
\81u%s
\81v
\82É
\91\97\90M|%s', [FNowChannel, SendButtonLongHint]);
1579 actSend.Hint := Format('
\91\97\90M|%s', [SendButtonLongHint]);
1581 Visible := Tabs.Count > 0;
1582 if Tabs.Count > 1 then begin
1583 actNextChannel.Enabled := true;
1584 actPrevChannel.Enabled := true;
1586 actNextChannel.Enabled := false;
1587 actPrevChannel.Enabled := false;
1589 OnChange := tabChannelChange;
1591 if nodat then Dat.Free;
1592 if JoinChannels.Count = 0 then begin
1593 Self.Caption := FOriginalCaption + ' -
\83`
\83\83\83\93\83l
\83\8b\82É
\8eQ
\89Á
\82µ
\82Ä
\82¢
\82Ü
\82¹
\82ñ';
1594 actSend.Enabled := false;
1596 Self.Caption := FOriginalCaption;
1597 actSend.Enabled := true;
1601 procedure TfrmSender.cbxTargetGhostDropDown(Sender: TObject);
1603 SakuraSeeker.BeginDetect;
1607 procedure TfrmSender.actShowLogExecute(Sender: TObject);
1610 if frmLog.WindowState = wsMinimized then frmLog.WindowState := wsNormal;
1613 procedure TfrmSender.actSleepExecute(Sender: TObject);
1615 if actSleep.Checked then begin
1616 actSleep.Checked := false;
1617 ShowHintLabel('
\83X
\83\8a\81[
\83v
\82ð
\89ð
\8f\9c\82µ
\82Ü
\82µ
\82½');
1619 actSleep.Checked := true;
1620 ShowHintLabel('
\83X
\83\8a\81[
\83v
\82ð
\90Ý
\92è
\82µ
\82Ü
\82µ
\82½');
1622 Sleeping := actSleep.Checked;
1627 procedure TfrmSender.DispatchBottle(EventType: TIdSlppEventType;
1629 var Opt: TSstpSendOptions;
1630 Event: TBottleChainBottleEvent;
1631 Script, Sender, Ghost, Channel: String;
1632 BreakFlag, NoDispatch: boolean;
1633 Sound, LogName: String;
1634 i, j, k, SkipCount: integer;
1635 Rule: TBottleChainRule;
1636 Action: TBottleChainAction;
1637 LogNameList: TStringList;
1641 if Pref.NoTranslate then Opt := Opt + [soNoTranslate];
1642 if Pref.NoDescript then Opt := Opt + [soNoDescript];
1643 Channel := Dat['Channel'];
1645 etScript: Sender := Channel;
1646 etForceBroadcast: Sender := '
\81y
\82¨
\92m
\82ç
\82¹
\81z';
1647 etUnicast: Sender := Dat['SenderUID'];
1650 //
\96Ú
\95W
\83S
\81[
\83X
\83g(
\83I
\81[
\83o
\81[
\83\89\83C
\83h
\88È
\91O)
\8c\88\92è
1651 if Dat['IfGhost'] <> '' then begin
1652 Ghost := Dat['IfGhost'];
1654 if ChannelList.Channel[Channel] <> nil then
1655 Ghost := ChannelList.Channel[Channel].Ghost;
1657 Dat['TargetGhost'] := Ghost;
1659 Event := TBottleChainBottleEvent.Create;
1662 if EventType = etScript then Event.LogType := ltBottle
1663 else Event.LogType := ltSystemLog;
1665 //
\83X
\83N
\83\8a\83v
\83g
\95Ï
\8a·
1666 Script := ScriptTransForSSTP(Dat['Script']);
1667 if Script = '' then begin
1668 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'+
1669 '
\94z
\91\97\82³
\82ê
\82Ü
\82¹
\82ñ
\82Å
\82µ
\82½
\81@
\81c '+Dat['Script']);
1674 NoDispatch := false;
1676 LogNameList := TStringList.Create;
1679 for i := 0 to BottleChainRuleList.Count-1 do begin
1680 if SkipCount > 0 then begin
1684 Rule := BottleChainRuleList[i];
1685 if not Rule.Enabled then Continue;
1686 if not Rule.Check(Event) then Continue;
1687 for j := 0 to Rule.Actions.Count-1 do begin
1688 Action := (Rule.Actions[j] as TBottleChainAction);
1689 if Action is TBottleChainAbortRuleAction then BreakFlag := true;
1690 if Action is TBottleChainSkipRuleAction then
1691 SkipCount := (Action as TBottleChainSkipRuleAction).SkipCount;
1692 if (Action is TBottleChainSoundAction) and (Sound = '') then begin
1693 Sound := (Action as TBottleChainSoundAction).SoundFile;
1694 Sound := StringReplace(Sound, '%channel%', Dat['Channel'], [rfReplaceAll]);
1695 Sound := StringReplace(Sound, '%ghost%', Dat['TargetGhost'], [rfReplaceAll]);
1697 if Action is TBottleChainNoDispatchAction then NoDispatch := true;
1698 if Action is TBottleChainLogAction then begin
1699 for k := 0 to (Action as TBottleChainLogAction).LogNames.Count-1 do begin
1700 LogName := (Action as TBottleChainLogAction).LogNames[k];
1701 LogName := StringReplace(LogName, '%channel%', Dat['Channel'], [rfReplaceAll]);
1702 LogName := StringReplace(LogName, '%ghost%', Dat['TargetGhost'], [rfReplaceAll]);
1703 LogName := StringReplace(LogName, '%date%', FormatDateTime('yy/mm/dd', Now()), [rfReplaceAll]);
1704 LogNameList.Add(LogName);
1707 if Action is TBottleChainOverrideGhostAction then begin
1708 Dat['TargetGhost'] := (Action as TBottleChainOverrideGhostAction).TargetGhost;
1710 if Action is TBottleChainQuitAction then Application.Terminate;
1712 if BreakFlag then Break;
1715 if Dat['Script'] <> '' then begin
1716 for i := 0 to LogNameList.Count-1 do
1717 frmLog.AddCurrentScriptLog(LogNameList[i], Dat['Script'], Sender, Dat['MID'], Dat['IfGhost']);
1718 if NoDispatch then begin
1719 frmLog.SetBottleState(Dat['MID'], lsOpened);
1721 Ghost := Dat['TargetGhost']; //
\83I
\81[
\83o
\81[
\83\89\83C
\83h
\82³
\82ê
\82Ä
\82¢
\82é
\89Â
\94\
\90«
\82ª
\82 \82é
1722 CueItem := TLogItem.Create(ltBottle, Dat['MID'], Dat['Channel'],
1723 Script, Ghost, Now());
1725 FBottleSstp.Push(CueItem);
1732 if Dat['DialogMessage'] <> '' then begin
1734 frmMessageBox.ShowMessage(
1735 DateTimeToStr(Now) + #13#10 +
1736 'SSTP Bottle
\83T
\81[
\83o
\82©
\82ç
\82¨
\92m
\82ç
\82¹'#13#10+Dat['DialogMessage']);
1737 for i := 0 to LogNameList.Count-1 do
1738 frmLog.AddCurrentSystemLog(LogNameList[i], Dat['DialogMessage']);
1742 if (Sound <> '') then PlaySound(Sound);
1751 function TfrmSender.SetHWndToFavoriteGhost(const Ghost: String): String;
1753 //DirectSstp.TargetHWnd
\82ð
\81A
\90\84\8f§
\82·
\82é
\83S
\81[
\83X
\83g
\82É
\90Ý
\92è
\82·
\82é
\81B
1754 //
\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
1755 SakuraSeeker.BeginDetect; //
\8dÅ
\90V
\82ÌFMO
\8eæ
\93¾
1756 if SakuraSeeker.ProcessByName[Ghost] <> nil then begin
1757 DirectSstp.TargetHWnd := SakuraSeeker.ProcessByName[Ghost].HWnd;
1759 end else if SakuraSeeker.Count > 0 then begin
1760 DirectSstp.TargetHWnd := SakuraSeeker[0].HWnd;
1761 Result := SakuraSeeker[0].Name;
1763 DirectSstp.TargetHwnd := 0;
1768 procedure TfrmSender.YenETrans;
1769 var St, Le, i: integer;
1772 St := memScript.SelStart;
1773 Le := memScript.SelLength;
1774 Orig := GetScriptText;
1775 RegExp.Subst('s/(\r\n)+$//kg', Orig);
1777 with SsParser do begin
1778 LeaveEscape := true;
1779 EscapeInvalidMeta := false;
1780 InputString := Orig;
1782 for i := 0 to SsParser.Count-1 do begin
1783 if SsParser[i] <> '\e' then Text := Text + SsParser[i];
1786 Text := Text + '\e';
1788 if Orig <> Text then memScript.Lines.Text := Text;
1789 SsParser.InputString := Text;
1791 RegExp.Subst('s/\r\n//kg', Text);
1793 memScript.SelStart := St;
1794 memScript.SelLength := Le;
1797 procedure TfrmSender.PostCommand(const Command: array of String);
1798 var PostStr: TStringList;
1803 PostStr := TStringList.Create;
1804 for i := Low(Command) to High(Command) do begin
1805 PostStr.Add(Command[i]);
1807 PostCommand(PostStr);
1813 procedure TfrmSender.PostCommand(Command: TStrings);
1814 var PostStr: String;
1817 PostStr := Command.Text;
1818 PostStr := TIdURI.ParamsEncode(PostStr);
1820 FHttp := THTTPDownloadThread.Create(BottleServer, Pref.CgiName, PostStr);
1821 if Pref.UseHttpProxy then begin
1822 FHttp.ProxyServer := Pref.ProxyAddress;
1823 FHttp.ProxyPort := Pref.ProxyPort;
1825 FHttp.OnSuccess := HttpSuccess;
1826 FHttp.OnConnectionFailed := HttpFailure;
1827 FHttp.FreeOnTerminate := true; //
\8f\9f\8eè
\82É
\8e©
\95ª
\82ÅFree
\82µ
\82Ä
\82
\82¾
\82³
\82¢
1830 on EHeapException do begin
1831 Connecting := false;
1837 procedure TfrmSender.actVoteMessageExecute(Sender: TObject);
1840 if frmLog.lvwLog.Selected = nil then Exit;
1841 Log := frmLog.SelectedBottleLog[frmLog.lvwLog.Selected.Index] as TLogItem;
1842 if Log = nil then Exit;
1843 if Log.LogType <> ltBottle then Exit;
1845 'Command: voteMessage',
1847 'LUID: ' + Pref.LUID,
1853 procedure TfrmSender.actAgreeMessageExecute(Sender: TObject);
1856 if frmLog.lvwLog.Selected = nil then Exit;
1857 Log := frmLog.SelectedBottleLog[frmLog.lvwLog.Selected.Index] as TLogItem;
1858 if Log = nil then Exit;
1859 if Log.LogType <> ltBottle then Exit;
1861 'Command: voteMessage',
1863 'LUID: ' + Pref.LUID,
1869 function TfrmSender.GhostNameToSetName(const Ghost: String): String;
1871 if SakuraSeeker.ProcessByName[Ghost] <> nil then
1872 Result := SakuraSeeker.ProcessByName[Ghost].SetName
1877 procedure TfrmSender.tabChannelContextPopup(Sender: TObject;
1878 MousePos: TPoint; var Handled: Boolean);
1881 with tabChannel do begin
1882 Tag := IndexOfTabAt(MousePos.X, MousePos.Y);
1883 if Tag < 0 then Handled := true;
1888 procedure TfrmSender.PostSetChannel(Channels: TStrings);
1889 var PostStr: TStringList;
1894 PostStr := TStringList.Create;
1895 with PostStr do begin
1896 Add('Command: setChannels');
1897 Add('Agent: ' + VersionString);
1898 Add('LUID: ' + Pref.LUID);
1899 if Channels <> nil then
1900 for i := 0 to Channels.Count-1 do begin
1901 Add(Format('Ch%d: %s'#13#10, [i+1, Channels[i]]));
1904 PostCommand(PostStr);
1910 procedure TfrmSender.mnLeaveThisChannelClick(Sender: TObject);
1914 with tabChannel do Ch := Tabs[Tag];
1917 Chs := TStringList.Create;
1918 Chs.Assign(JoinChannels);
1919 while Chs.IndexOf(Ch) >= 0 do Chs.Delete(Chs.IndexOf(Ch));
1920 PostSetChannel(Chs);
1926 procedure TfrmSender.mnGotoVoteClick(Sender: TObject);
1928 ShellExecute(Handle, 'open', PChar(Pref.VotePage), nil, nil, SW_SHOW);
1931 procedure TfrmSender.mnGotoGLogClick(Sender: TObject);
1933 ShellExecute(Handle, 'open', PChar(Pref.GLogPage), nil, nil, SW_SHOW);
1936 procedure TfrmSender.tabChannelMouseMove(Sender: TObject;
1937 Shift: TShiftState; X, Y: Integer);
1941 with tabChannel do begin
1942 Index := IndexOfTabAt(X, Y);
1944 Hint := Ch + ': ' + IntToStr(ChannelList.Channel[Ch].Members) + '
\90l';
1948 procedure TfrmSender.mnGoToHelpClick(Sender: TObject);
1950 ShellExecute(Handle, 'open', PChar(Pref.HelpPage), nil, nil, SW_SHOW);
1953 procedure TfrmSender.tabChannelMouseDown(Sender: TObject;
1954 Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
1957 with tabChannel do begin
1958 Index := IndexOfTabAt(X, Y);
1959 if Index = -1 then Exit; //
\83^
\83u
\82ª
\82È
\82¢
\82Ì
\82Å
\83h
\83\89\83b
\83O
\82Å
\82«
\82È
\82¢
1960 if Button = mbLeft then begin
1961 FDragTabIndex := Index; //
\83h
\83\89\83b
\83O
\82·
\82é
\83^
\83u
\82Ì
\83C
\83\93\83f
\83b
\83N
\83X
\82ð
\95Û
\91¶
1963 FDragTabDest := -1; //
\83h
\83\89\83b
\83O
\98g
\90ü
\95`
\89æ
\83t
\83\89\83O
\83N
\83\8a\83A
\82Ì
\82½
\82ß
1968 procedure TfrmSender.tabChannelDragOver(Sender, Source: TObject; X,
1969 Y: Integer; State: TDragState; var Accept: Boolean);
1970 var TargetRect: TRect;
1973 Accept := Source = tabChannel;
1974 if not Accept then Exit;
1975 with tabChannel do begin
1976 OldDest := FDragTabDest;
1977 FDragTabDest := IndexOfTabAt(X, Y);
1978 if FDragTabDest = -1 then begin
1979 Accept := false; //
\82±
\82Ì
\8fê
\8d\87\82Í
\83h
\83\8d\83b
\83v
\82ð
\94F
\82ß
\82È
\82¢
1982 with Canvas do begin
1986 if (OldDest <> FDragTabDest) and (OldDest >= 0) then begin
1987 //
\88È
\91O
\82Ì
\98g
\90ü
\8fÁ
\8b\8e
1988 TargetRect := TabRect(OldDest);
1989 with Canvas do begin
1990 Brush.Style := bsClear;
1991 Rectangle(TargetRect.Left, TargetRect.Top,
1992 TargetRect.Right, TargetRect.Bottom);
1995 if (OldDest <> FDragTabDest) then begin
1996 //
\90V
\82µ
\82¢
\98g
\90ü
\95`
\89æ
1997 TargetRect := TabRect(FDragTabDest);
1998 with Canvas do begin
1999 Brush.Style := bsClear;
2000 Rectangle(TargetRect.Left, TargetRect.Top,
2001 TargetRect.Right, TargetRect.Bottom);
2007 procedure TfrmSender.tabChannelDragDrop(Sender, Source: TObject; X,
2009 var DestIndex: integer;
2011 with tabChannel do begin
2012 DestIndex := IndexOfTabAt(X, Y);
2013 Tabs.Move(FDragTabIndex, DestIndex);
2017 procedure TfrmSender.tabChannelEndDrag(Sender, Target: TObject; X,
2020 //
\8b
\90§
\93I
\82É
\83^
\83u
\82ð
\8dÄ
\95`
\89æ
\82³
\82¹
\82é
\81B
\98g
\90ü
\8fÁ
\82µ
\91Î
\8dô
2021 tabChannel.Tabs.BeginUpdate;
2022 tabChannel.Tabs.EndUpdate;
2025 procedure TfrmSender.cbxTargetGhostDrawItem(Control: TWinControl;
2026 Index: Integer; Rect: TRect; State: TOwnerDrawState);
2027 var AlignRight: boolean;
2030 //
\83S
\81[
\83X
\83g
\91I
\91ð
\83{
\83b
\83N
\83X
\82Ì
\83I
\81[
\83i
\81[
\83h
\83\8d\81[
2031 with cbxTargetGhost do begin
2032 AlignRight := false;
2033 if Pref.HideGhosts and not FTargetGhostExpand and (Index = Items.Count-1) then
2035 //
\81u
\82·
\82×
\82Ä
\95\
\8e¦
\81v
2036 Canvas.Font.Color := clWindowText;
2037 Canvas.Font.Style := [];
2039 end else if (Index > 0) then
2041 //
\83S
\81[
\83X
\83g
\96¼
\82ð
\91I
\91ð
2042 if SakuraSeeker.ProcessByName[Items[Index]] = nil then
2043 Canvas.Font.Color := clRed //
\91¶
\8dÝ
\82µ
\82È
\82¢
\83S
\81[
\83X
\83g
2045 Canvas.Font.Color := clBlue; //
\91¶
\8dÝ
\82·
\82é
\83S
\81[
\83X
\83g
2046 Canvas.Font.Style := [fsBold];
2049 Canvas.Font.Color := clWindowText;
2050 Canvas.Font.Style := [];
2052 if odSelected in State then
2053 Canvas.Font.Color := clHighlightText;
2057 w := Canvas.TextWidth(cbxTargetGhost.Items[Index]);
2058 Canvas.TextRect(Rect, Rect.Right - w, Rect.Top,
2059 cbxTargetGhost.Items[Index]);
2061 Canvas.TextRect(Rect, Rect.Left, Rect.Top,
2062 cbxTargetGhost.Items[Index]);
2066 procedure TfrmSender.FormCloseQuery(Sender: TObject;
2067 var CanClose: Boolean);
2069 if not Pref.ConfirmOnExit then Exit;
2070 if MessageDlg('SSTP Bottle Client
\82ð
\8fI
\97¹
\82µ
\82Ü
\82·', mtConfirmation,
2071 mbOkCancel, 0) = mrCancel then CanClose := false;
2074 procedure TfrmSender.UpdateIfGhostBox;
2078 HiddenCount: integer;
2080 cbxTargetGhost.DropDownCount := Pref.GhostDropDownCount;
2081 Selected := cbxTargetGhost.Text;
2083 with cbxTargetGhost do begin
2086 Items.Add('(CH
\90\84\8f§)');
2087 for i := 0 to SakuraSeeker.Count-1 do begin
2088 //
\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é
2089 if Length(SakuraSeeker[i].Name) = 0 then Continue;
2090 if Pref.HideGhosts and not FTargetGhostExpand then
2091 if Pref.VisibleGhostsList.IndexOf(SakuraSeeker[i].Name) < 0 then
2096 if cbxTargetGhost.Items.IndexOf(SakuraSeeker[i].Name) < 0 then
2097 cbxTargetGhost.Items.Add(SakuraSeeker[i].Name);
2099 cbxTargetGhost.ItemIndex := 0;
2100 if (Length(Selected) > 0) and (Selected <> '(CH
\90\84\8f§)') then begin
2101 with cbxTargetGhost do begin
2102 for i := 1 to Items.Count-1 do begin
2103 if Items[i] = Selected then
2106 //
\83S
\81[
\83X
\83g
\82ª
\93Ë
\91R
\91¶
\8dÝ
\82µ
\82È
\82
\82È
\82Á
\82½
\8fê
\8d\87\91Î
\8dô
2107 if ItemIndex = 0 then begin
2108 Items.Add(Selected);
2109 ItemIndex := Items.Count - 1;
2113 if Pref.HideGhosts and not FTargetGhostExpand then
2114 Items.Add(Format('
\82·
\82×
\82Ä(%d)...', [HiddenCount]));
2119 procedure TfrmSender.HTTPFailure(Sender: TObject);
2123 ShowHintLabel('SSTP Bottle
\83T
\81[
\83o
\82Æ
\82Ì
\90Ú
\91±
\82É
\8e¸
\94s
\82µ
\82Ü
\82µ
\82½', WarningColor);
2124 ShowMessage('SSTP Bottle
\83T
\81[
\83o
\82Æ
\82Ì
\90Ú
\91±
\82É
\8e¸
\94s
\82µ
\82Ü
\82µ
\82½'#13#10 +
2125 (Sender as THTTPDownloadThread).LastErrorMessage);
2126 Connecting := false;
2129 procedure TfrmSender.actPrevGhostExecute(Sender: TObject);
2132 SakuraSeeker.BeginDetect;
2134 i := cbxTargetGhost.ItemIndex;
2138 i := cbxTargetGhost.Items.Count-1;
2139 if Pref.HideGhosts and not FTargetGhostExpand then
2142 cbxTargetGhost.ItemIndex := i;
2143 cbxTargetGhostChange(self);
2146 procedure TfrmSender.actNextGhostExecute(Sender: TObject);
2149 SakuraSeeker.BeginDetect;
2151 i := cbxTargetGhost.ItemIndex;
2153 if Pref.HideGhosts and not FTargetGhostExpand then
2155 if i > cbxTargetGhost.Items.Count-2 then i := 0;
2158 if i > cbxTargetGhost.Items.Count-1 then i := 0;
2160 cbxTargetGhost.ItemIndex := i;
2161 cbxTargetGhostChange(self);
2164 procedure TfrmSender.actResetGhostExecute(Sender: TObject);
2166 cbxTargetGhost.ItemIndex := 0; // (CH
\90\84\8f§)
\82É
\96ß
\82·
2167 FTargetGhostExpand := false;
2168 if Visible then memScript.SetFocus;
2169 cbxTargetGhostChange(self);
2172 procedure TfrmSender.timDisconnectCheckTimerTimer(Sender: TObject);
2174 if (IdSlpp20.LastReadTimeInterval > BottleServerTimeOut) then begin
2176 frmLog.AddCurrentSystemLog('SYSTEM', 'SSTP Bottle
\83T
\81[
\83o
\82Æ
\82Ì
\90Ú
\91±
\82ª
\83^
\83C
\83\80\83A
\83E
\83g
\82µ
\82Ü
\82µ
\82½');
2177 if IdSlpp20.Connected then IdSlpp20.Disconnect;
2179 if not IdSlpp20.Connected then begin
2181 Slpp20Disconnect(self); //
\82È
\82º
\82©Disconnect
\83C
\83x
\83\93\83g
\82ª
\8bN
\82±
\82ç
\82¸
\82É
\90Ø
\92f
\82µ
\82½
\8fê
\8d\87
2183 //
\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
2184 //
\82½
\82¾
\82µ
\89ñ
\90\94\90§
\8cÀ
\82 \82è
2190 procedure TfrmSender.RetryBeginConnect;
2192 if FBeginConnectFailCount < 3 then begin
2193 //
\90Ø
\92f
\82³
\82ê
\82Ä
\82¢
\82ê
\82Î
\8dÄ
\90Ú
\91±
2194 FAutoAddAfterGetChannel := true;
2196 end else if FBeginConnectFailCount = 3 then begin
2197 frmLog.AddCurrentSystemLog('SYSTEM', '
\8dÄ
\90Ú
\91±
\8e©
\93®
\83\8a\83g
\83\89\83C
\82ð
\92\86\8e~
\82µ
\82Ü
\82·');
2198 frmMessageBox.ShowMessage(
2199 'SSTP Bottle
\83T
\81[
\83o
\82É
\90Ú
\91±
\82Å
\82«
\82Ü
\82¹
\82ñ
\81B'#13#10+
2200 '
\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+
2201 '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'
2203 Inc(FBeginConnectFailCount);
2207 procedure TfrmSender.actDownloadLogExecute(Sender: TObject);
2208 var BottleLog: TBottleLogList;
2210 Cond: TBottleLogDownloadCondition;
2212 function TimeStr(Mins: integer): String;
2213 var day, hour, min: integer;
2215 day := Mins div (60 * 24);
2216 hour := (Mins div 60) mod 24;
2219 if day > 0 then Result := Result + Format('%d
\93ú', [day]);
2220 if hour > 0 then Result := Result + Format('%d
\8e\9e\8aÔ', [hour]);
2221 if (min > 0) or (Result = '') then Result := Result + Format('%d
\95ª', [min]);
2224 Application.CreateForm(TfrmLogDownload, frmLogDownload);
2226 if frmLogDownload.Execute then begin
2227 with frmLogDownload do begin
2228 if IsRange then begin
2229 if CompareDate(DateLo, DateHi) = 0 then
2230 Title := FormatDateTime('yy/mm/dd', DateLo)
2232 Title := FormatDateTime('yy/mm/dd', DateLo) + ' - ' + FormatdateTime('yy/mm/dd', DateHi);
2234 Title := Format('
\89ß
\8b\8e%s', [TimeStr(RecentCount)]);
2236 if Channel <> '' then Title := Title + '(' + Channel + ')';
2238 BottleLog := TBottleLogList.Create(Title);
2240 BottleLog.OnLoaded := frmLog.LogLoaded;
2241 BottleLog.OnLoadFailure := frmLog.LogLoadFailure;
2242 BottleLog.OnLoadWork := frmLog.LogLoadWork;
2243 with frmLogDownload do begin
2244 Cond.IsRange := IsRange;
2245 Cond.RecentCount := RecentCount;
2246 Cond.DateLo := DateLo;
2247 Cond.DateHi := DateHi;
2248 Cond.MinVote := MinVote;
2249 Cond.MinAgree := MinAgree;
2250 Cond.Channel := Channel;
2252 BottleLog.LoadFromWeb(Cond);
2254 FreeAndNil(BottleLog);
2256 if BottleLog <> nil then begin
2257 NewIndex := frmLog.BottleLogList.Add(BottleLog);
2259 frmLog.tabBottleLog.TabIndex := NewIndex;
2260 frmLog.UpdateWindow;
2264 frmLogDownload.Release;
2268 function TfrmSender.BuildMenuConditionCheck(const IfGhost,
2269 Ghost: String): boolean;
2276 Cond := Token(IfGhost, ',', i);
2277 if Cond <> '' then begin
2278 if Cond[1] = '!' then begin
2279 Cond := Copy(Cond, 2, High(integer));
2280 if Cond = Ghost then Result := false;
2282 if Cond <> Ghost then Result := false;
2289 procedure TfrmSender.BuildMenu(Root: TMenuItem; Simple: boolean);
2290 var i, j, k, count: integer;
2291 ConstData: TScriptConst;
2292 Menu1, Menu2: TMenuItem;
2295 // Simple = false
\82Ì
\8fê
\8d\87\82Í
\83\81\83j
\83\85\81[
\82ð
\8a®
\91S
\82É
\8dÄ
\8d\
\92z
\82·
\82é
\81B
2296 // 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
2297 if cbxTargetGhost.ItemIndex > 0 then Ghost := cbxTargetGhost.Text
2298 else if FNowChannel <> '' then Ghost := ChannelList.Channel[FNowChannel].Ghost;
2300 //
\8aù
\91¶
\82Ì
\83\81\83j
\83\85\81[
\8dí
\8f\9c
2301 if Simple then begin
2302 // IfGhost
\8fð
\8c\8f\95t
\82«
\83\81\83j
\83\85\81[
\82Ì
\82Ý
\8dí
\8f\9c
2303 for i := Root.Count-1 downto 0 do begin
2304 if ScriptConstList.GetMenuByID(Root.Items[i].Tag).IfGhost <> '' then
2308 //
\91S
\95\94\8dí
\8f\9c
2309 for i := Root.Count-1 downto 0 do begin
2315 for i := 0 to ScriptConstList.Count-1 do begin
2316 for j := 0 to ScriptConstList[i].Count-1 do begin
2317 //
\83S
\81[
\83X
\83g
\88á
\82¢
\82Ì
\8fê
\8d\87\82Í
\83X
\83L
\83b
\83v
2318 if not BuildMenuConditionCheck(ScriptConstList[i][j].IfGhost, Ghost) then Continue;
2320 // 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
2321 if Simple and (count < Root.Count) then
2322 if (Root.Items[count].Tag = ScriptConstList[i][j].ID) then begin
2326 Menu1 := TMenuItem.Create(Root);
2327 Menu1.Caption := ScriptConstList[i][j].Caption;
2328 Menu1.Hint := ScriptConstList[i][j].Caption;
2329 Menu1.AutoHotkeys := maManual;
2330 Menu1.Tag := ScriptConstList[i][j].ID;
2331 Menu1.OnClick := mnConstGroupClick;
2333 if not Simple then begin
2336 if count < Root.Count-1 then
2337 Root.Insert(count, Menu1)
2342 Menu1.Enabled := ScriptConstList[i][j].Count > 0;
2343 for k := 0 to ScriptConstList[i][j].Count-1 do begin
2344 ConstData := ScriptConstList[i][j][k];
2345 Menu2 := TMenuItem.Create(Root);
2346 Menu2.Caption := ConstData.Caption;
2347 Menu2.Hint := ConstData.ConstText;
2348 // if ConstData.ShortCut <> 0 then Menu2.Hint := Menu2.Hint
2349 // + ' (' + ShortCutToText(ConstData.ShortCut) + ')';
2350 //
\83T
\81[
\83t
\83B
\83X
\83v
\83\8c\83r
\83\85\81[
\8eÀ
\8c»
\82Ì
\82½
\82ß
\8fã
\8dí
\8f\9c
2351 Menu2.ShortCut := ConstData.ShortCut;
2352 Menu2.OnClick := mnConstClick;
2353 Menu2.AutoHotkeys := maManual;
2354 Menu2.Tag := ConstData.ID;
2355 if (k mod 15 = 0) and (k > 0) then Menu2.Break := mbBarBreak;
2362 procedure TfrmSender.cbxTargetGhostChange(Sender: TObject);
2364 //
\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
2365 if Pref.HideGhosts and not FTargetGhostExpand then
2367 with cbxTargetGhost do
2369 if ItemIndex = Items.Count-1 then
2371 FTargetGhostExpand := true;
2374 DroppedDown := true;
2378 //
\92è
\8c^
\8bå
\83\81\83j
\83\85\81[
\82ð
\8dÄ
\8d\
\92z
2379 ConstructMenu(true);
2380 //
\83v
\83\8c\83r
\83\85\81[
\82ª
\82 \82é
\8fê
\8d\87\82Í
\83v
\83\8c\83r
\83\85\81[
2384 procedure TfrmSender.PlaySound(const FileName: String);
2386 if Pref.SilentWhenHidden and not Application.ShowMainForm then Exit;
2388 MediaPlayer.FileName := FileName;
2392 on E: EMCIDeviceError do begin
2393 ShowMessage('
\83T
\83E
\83\93\83h
\8dÄ
\90¶
\83G
\83\89\81[:'#13#10 + FileName + #13#10#13#10 + E.Message);
2398 procedure TfrmSender.actFMOExplorerExecute(Sender: TObject);
2400 frmFMOExplorer.Show;
2403 procedure TfrmSender.SaveChainRuleList;
2404 var Str: TStringList;
2406 Str := TStringList.Create;
2408 Str.Text := ComponentToString(BottleChainRuleList);
2409 Str.SaveToFile(ExtractFileDir(Application.ExeName)+'\rule.txt');
2415 procedure TfrmSender.BottleSstpResendEnd(Sender: TObject; MID: String);
2417 frmLog.SetBottleState(MID, lsOpened);
2420 procedure TfrmSender.BottleSstpResendTrying(Sender: TObject; MID: String);
2422 frmLog.SetBottleState(MID, lsPlaying);
2425 procedure TfrmSender.actInsertCueExecute(Sender: TObject);
2426 var InsertItem: TLogItem;
2427 i, errCount: integer;
2428 Log: TBottleLogList;
2430 if FBottleSstp.CueCount > 0 then begin
2431 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'+
2432 '
\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+
2433 '
\90V
\92\85\83\81\83b
\83Z
\81[
\83W
\82Í
\82»
\82Ì
\8cã
\82É
\8dÄ
\90¶
\82³
\82ê
\82Ü
\82·
\81B', [FBottleSstp.CueCount]),
2434 mtWarning, mbOkCancel, 0) = mrCancel then Exit;
2437 frmLog.AllBottleOpened;
2438 if frmLog.lvwLog.Selected = nil then Exit;
2439 Log := frmLog.SelectedBottleLog;
2440 if Log = nil then Exit;
2441 FBottleSSTP.OnResendCountChange := nil;
2443 for i := frmLog.lvwLog.Selected.Index downto 0 do begin
2444 if (Log[i] as TLogItem).LogType <> ltBottle then Continue;
2445 InsertItem := TLogItem.Create(Log[i] as TLogItem);
2447 InsertItem.Script := ScriptTransForSSTP(InsertItem.Script);
2448 if InsertItem.Script = '' then begin
2449 raise Exception.Create('Script syntax error');
2451 if InsertItem.Ghost = '' then begin
2452 if ChannelList.Channel[InsertItem.Channel] <> nil then
2453 InsertItem.Ghost := ChannelList.Channel[InsertItem.Channel].Ghost;
2455 FBottleSSTP.Push(InsertItem);
2456 frmLog.SetBottleState(InsertItem.MID, lsUnopened);
2462 if errCount > 0 then
2463 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]));
2464 FBottleSSTP.OnResendCountChange := BottleSstpResendCountChange;
2465 BottleSstpResendCountChange(self);
2468 function TfrmSender.ScriptTransForSSTP(const Script: String): String;
2469 var TransOpt: TScriptTransOptions;
2472 if Pref.NoTransURL then
2473 TransOpt := [toConvertURL, toNoChoice, toWaitScriptEnd]
2475 TransOpt := [toConvertURL, toWaitScriptEnd];
2476 if Pref.IgnoreFrequentYenS then TransOpt := TransOpt + [toIgnoreFrequentYenS];
2477 if Pref.FixMessySurface then TransOpt := TransOpt + [toFixMessySurface];
2478 if Pref.HUTagTo01Tag then TransOpt := TransOpt + [toHUTagTo01Tag];
2480 Err := DoTrans(Result, TransOpt);
2481 if Length(Err) > 0 then Result := '';
2484 procedure TfrmSender.FormResize(Sender: TObject);
2487 //
\83G
\83f
\83B
\83^
\81[
\95\94\95ª
\82Ì
\83\8f\81[
\83h
\83\89\83b
\83v
\95\9d\82ð
\92²
\90®
\82·
\82é
2488 if memScript.ColWidth <> 0 then
2492 w := Width - LeftMargin - ColWidth div 2;
2493 if ScrollBars in [ssVertical, ssBoth] then
2494 w := w - GetSystemMetrics(SM_CYVSCROLL);
2495 WrapOption.WrapByte := w div ColWidth;
2500 procedure TfrmSender.actCopyExecute(Sender: TObject);
2502 memScript.CopyToClipboard;
2505 procedure TfrmSender.actPasteExecute(Sender: TObject);
2507 memScript.PasteFromClipboard;
2510 procedure TfrmSender.actCutExecute(Sender: TObject);
2512 memScript.CutToClipboard;
2515 procedure TfrmSender.actSelectAllExecute(Sender: TObject);
2517 memScript.SelectAll;
2520 function TfrmSender.IsSurfaceTag(const Script: String;
2521 var ID: integer): boolean;
2524 if SsParser.Match(Script, '\s%d') = 3 then
2527 ID := Ord(Script[3]) - Ord('0')
2529 else if (Length(Script) > 0) and (SsParser.Match(Script, '\s[%D]') = Length(Script)) then
2532 ID := StrToIntDef(SsParser.GetParam(Script, 1), 0);
2536 procedure TfrmSender.memScriptMouseMove(Sender: TObject;
2537 Shift: TShiftState; X, Y: Integer);
2541 //
\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[
2542 if not Pref.SurfacePreviewOnScriptPoint then
2544 token := memScript.TokenStringFromPos(Point(X, Y));
2545 if IsSurfaceTag(token, id) then
2547 DoSurfacePreview(id, spEditor);
2550 frmSurfacePreview.HideAway;
2554 procedure TfrmSender.DoSurfacePreview(Surface: integer;
2555 const Kind: TSurfacePreviewType);
2560 if cbxTargetGhost.ItemIndex > 0 then
2561 ghost := cbxTargetGhost.Text
2562 else if FNowChannel <> '' then
2563 ghost := ChannelList.Channel[FNowChannel].Ghost;
2565 //
\93ñ
\8fd
\95\
\8e¦
\82Ì
\97}
\90§
2566 if (FVisiblePreviewGhost = Ghost) and (FVisiblePreviewSurface = Surface) and
2567 not (frmSurfacePreview.IsHidden) then
2574 Bmp := TBitmap.Create;
2576 if Spps.TryGetImage(ghost, Surface, Bmp) then
2580 CPos := GetSurfacePreviewPositionHint(Bmp.Width, Bmp.Height);
2582 CPos := GetSurfacePreviewPositionScriptPoint(Bmp.Width, Bmp.Height);
2584 CPos := Point(0, 0);
2586 frmSurfacePreview.ShowPreview(Bmp, CPos.X, CPos.Y);
2587 FVisiblePreviewGhost := Ghost;
2588 FVisiblePreviewSurface := Surface;
2590 frmSurfacePreview.HideAway;
2597 function TfrmSender.GetSurfacePreviewPositionHint(w, h: integer): TPoint;
2598 {var MousePoint: TPoint;
2601 //
\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é
2602 //
\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Å
2603 //
\88Ä
\8aO
\82â
\82â
\82±
\82µ
\82¢
2604 {GetCursorPos(MousePoint);
2605 OutputDebugString(PChar(IntToStr(FVisibleMenuItem.Count)));
2606 //if GetMenuItemRect(Self.Handle, FVisibleMenuItem.Items[0].Handle, 1, MenuRect) then ;
2607 Result := Point(MenuRect.Left-10, MenuRect.Top-10);}
2608 Result := GetSurfacePreviewPositionScriptPoint(w, h);
2611 function TfrmSender.GetSurfacePreviewPositionScriptPoint(w, h: integer): TPoint;
2612 var MousePoint: TPoint;
2614 GetCursorPos(MousePoint);
2615 case Pref.SurfacePreviewOnScriptPointPosition of
2616 spspMainWindowRight:
2617 Result := Point(Self.Left + Self.Width, MousePoint.Y);
2619 Result := Point(Self.Left - w, MousePoint.Y);
2623 procedure TfrmSender.mnConstGroupClick(Sender: TObject);
2625 if (Sender is TMenuItem) then
2626 FVisibleMenuItem := Sender as TMenuItem;
2629 procedure TfrmSender.actRecallScriptBufferExecute(Sender: TObject);
2631 if FScriptBuffer.Count = 0 then
2633 memScript.Lines.Assign(FScriptBuffer[0] as TStringList);
2634 memScriptChange(Self);
2635 ShowHintLabel('
\83X
\83N
\83\8a\83v
\83g
\82ð
\8cÄ
\82Ñ
\8fo
\82µ
\82Ü
\82µ
\82½');
2638 procedure TfrmSender.EditorPreview;
2639 var Ghost, Script: String;
2641 if frmEditorTalkShow <> nil then
2642 if frmEditorTalkShow.Visible then
2644 Script := StringReplace(GetScriptText, #13#10, '', [rfReplaceAll]);
2646 if cbxTargetGhost.ItemIndex > 0 then
2647 Ghost := cbxTargetGhost.Text
2648 else if FNowChannel <> '' then
2649 Ghost := ChannelList.Channel[FNowChannel].Ghost;
2650 frmEditorTalkShow.TalkShowFrame.View(Script, Ghost);
2654 procedure TfrmSender.actEditorPreviewExecute(Sender: TObject);
2656 if frmEditorTalkShow <> nil then
2657 frmEditorTalkShow.Show
2660 Application.CreateForm(TfrmEditorTalkShow, frmEditorTalkShow);
2661 frmEditorTalkShow.Show;
2666 procedure TfrmSender.actResetPluginsExecute(Sender: TObject);
2668 Spps.ClearImagePool;
2669 Spps.LoadFromDirectory(FSppDir);
2672 procedure TfrmSender.IdSLPP20Connect(Sender: TObject);
2674 ShowHintLabel('SSTP Bottle
\83T
\81[
\83o
\82ª
\8c©
\82Â
\82©
\82è
\82Ü
\82µ
\82½');