6 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
7 Menus, StdCtrls, ComCtrls, BRegExp, BottleDef,
8 IniFiles, ExtCtrls, ShellAPI, StdActns, ActnList,
9 ConstEditor, AppEvnts, TaskTray, ImgList, ToolWin, Buttons, MenuBar,
10 RichEdit, Clipbrd, SsParser, MPlayer,
12 IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdSLPP20,
13 IdException, HttpThread, IdHTTP, IdURI, DirectSstp, XPMan, LogDownload,
14 ScriptConsts, DateUtils, BottleChainRule, BottleChainEvent, SakuraSeekerInstance;
17 TfrmSender = class(TForm)
21 mnRegister: TMenuItem;
24 StatusBar: TStatusBar;
27 mnEditConst: TMenuItem;
28 ActionList: TActionList;
29 actEditCopy: TEditCopy;
31 actEditPaste: TEditPaste;
32 actEditSelectAll: TEditSelectAll;
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;
114 memScript: TRichEdit;
117 cbxTargetGhost: TComboBox;
118 actVoteMessage: TAction;
119 mnPopUpChannelTab: TPopupMenu;
120 mnLeaveThisChannel: TMenuItem;
122 mnGotoVote: TMenuItem;
123 mnGotoGLog: TMenuItem;
124 mnGoToHelp: TMenuItem;
128 mnExitAllChannels: TMenuItem;
129 actAgreeMessage: TAction;
132 actPrevGhost: TAction;
133 actNextGhost: TAction;
134 mnPrevGhost: TMenuItem;
135 mnNextGhost: TMenuItem;
136 actResetGhost: TAction;
137 mnResetGhost: TMenuItem;
138 timDisconnectCheckTimer: TTimer;
139 DirectSstp: TDirectSstp;
140 XPManifest: TXPManifest;
141 actDownloadLog: TAction;
142 actFMOExplorer: TAction;
143 tbtnFMOExplorer: TToolButton;
144 mnFMOExplorer: TMenuItem;
146 procedure actConfirmExecute(Sender: TObject);
147 procedure FormCreate(Sender: TObject);
148 procedure FormDestroy(Sender: TObject);
149 procedure actSendExecute(Sender: TObject);
150 procedure HTTPSuccess(Sender: TObject);
151 procedure HTTPFailure(Sender: TObject);
152 procedure actStartClick(Sender: TObject);
153 procedure actStopExecute(Sender: TObject);
154 procedure FormShow(Sender: TObject);
155 procedure mnAboutClick(Sender: TObject);
156 procedure actExitClientExecute(Sender: TObject);
157 procedure actClearExecute(Sender: TObject);
158 procedure memScriptChange(Sender: TObject);
159 procedure mnStayOnTopClick(Sender: TObject);
160 procedure mnColorScriptClick(Sender: TObject);
161 procedure actEditConstExecute(Sender: TObject);
162 procedure mnTaskBarClick(Sender: TObject);
163 procedure FormClose(Sender: TObject; var Action: TCloseAction);
164 procedure ApplicationEventsMinimize(Sender: TObject);
165 procedure ApplicationEventsRestore(Sender: TObject);
166 procedure mnTaskRestoreClick(Sender: TObject);
167 procedure TaskTrayDblClick(Seft: TObject; Button: TMouseButton);
168 procedure FormActivate(Sender: TObject);
169 procedure mnTaskNewMessageClick(Sender: TObject);
170 procedure ApplicationEventsHint(Sender: TObject);
171 procedure memScriptKeyDown(Sender: TObject; var Key: Word;
173 procedure mnShowToolBarClick(Sender: TObject);
174 procedure mnShowConstBarClick(Sender: TObject);
175 procedure ApplicationEventsIdle(Sender: TObject; var Done: Boolean);
176 procedure mnGoToHPClick(Sender: TObject);
177 procedure LabelTimerTimer(Sender: TObject);
178 procedure actCopyAllExecute(Sender: TObject);
179 procedure actCopyAllNoReturnExecute(Sender: TObject);
180 procedure Slpp20SlppEvent(Sender: TObject; EventType: TIdSlppEventType;
181 const Param: String);
182 procedure DirectSstpResendCountChange(Sender: TObject);
183 procedure actSettingExecute(Sender: TObject);
184 procedure memScriptKeyPress(Sender: TObject; var Key: Char);
185 procedure Slpp20Disconnect(Sender: TObject);
186 procedure actClearBottlesExecute(Sender: TObject);
187 procedure SakuraSeekerDetectResultChanged(Sender: TObject);
188 procedure mnGetNewIdClick(Sender: TObject);
189 procedure tabChannelChange(Sender: TObject);
190 procedure actPrevChannelExecute(Sender: TObject);
191 procedure actNextChannelExecute(Sender: TObject);
192 procedure cbxTargetGhostDropDown(Sender: TObject);
193 procedure DirectSstpResendTrying(Sender: TObject; ID: Integer;
194 const Script: String);
195 procedure DirectSstpResendEnd(Sender: TObject; ID: Integer;
196 const Script: String);
197 procedure actShowLogExecute(Sender: TObject);
198 procedure Slpp20Connect(Sender: TObject);
199 procedure actSleepExecute(Sender: TObject);
200 procedure tabChannelDrawTab(Control: TCustomTabControl;
201 TabIndex: Integer; const Rect: TRect; Active: Boolean);
202 procedure actVoteMessageExecute(Sender: TObject);
203 procedure tabChannelContextPopup(Sender: TObject; MousePos: TPoint;
204 var Handled: Boolean);
205 procedure mnLeaveThisChannelClick(Sender: TObject);
206 procedure mnGotoVoteClick(Sender: TObject);
207 procedure mnGotoGLogClick(Sender: TObject);
208 procedure tabChannelMouseMove(Sender: TObject; Shift: TShiftState; X,
210 procedure mnGoToHelpClick(Sender: TObject);
211 procedure tabChannelMouseDown(Sender: TObject; Button: TMouseButton;
212 Shift: TShiftState; X, Y: Integer);
213 procedure tabChannelDragOver(Sender, Source: TObject; X, Y: Integer;
214 State: TDragState; var Accept: Boolean);
215 procedure tabChannelDragDrop(Sender, Source: TObject; X, Y: Integer);
216 procedure tabChannelEndDrag(Sender, Target: TObject; X, Y: Integer);
217 procedure cbxTargetGhostDrawItem(Control: TWinControl; Index: Integer;
218 Rect: TRect; State: TOwnerDrawState);
219 procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
220 procedure actAgreeMessageExecute(Sender: TObject);
221 procedure actPrevGhostExecute(Sender: TObject);
222 procedure actNextGhostExecute(Sender: TObject);
223 procedure actResetGhostExecute(Sender: TObject);
224 procedure timDisconnectCheckTimerTimer(Sender: TObject);
225 procedure actDownloadLogExecute(Sender: TObject);
226 procedure cbxTargetGhostChange(Sender: TObject);
227 procedure actFMOExplorerExecute(Sender: TObject);
231 FConnecting: boolean;
233 FBooted: boolean; //
\8f\89\89ñ
\8bN
\93®
\92Ê
\90M
\97p
234 FOriginalCaption: String;
235 FAutoAddAfterGetChannel: boolean;
237 //
\83X
\83N
\83\8a\83v
\83g
\90F
\95ª
\82¯
\97p
\82Ì
\95Ï
\90\94
238 FRequireColoring: boolean;
239 FUnyuTalking: boolean;
240 FInSynchronized: boolean;
241 FLastSurfaceH: integer;
242 FLastSurfaceU: integer;
243 FColoringPos: integer; //
\90F
\95ª
\82¯
\8dÏ
\82Ý
\82Ì
\83X
\83N
\83\8a\83v
\83g
\82Ì
\83o
\83C
\83g
\90\94
244 FColoredElements: integer; //
\90F
\95ª
\82¯
\8dÏ
\82Ý
\82Ì
\83G
\83\8c\83\81\83\93\83g
\82Ì
\90\94
245 FcolorTimeLag: Int64; //
\95Ï
\8a·
\8aJ
\8en
\82Ü
\82Å
\82Ì
\83J
\83E
\83\93\83^
247 FMutex: THandle; //Mutex
\83I
\83u
\83W
\83F
\83N
\83g
\81c
\93ñ
\8fd
\8bN
\93®
\96h
\8e~
\97p
249 FNowChannel: String; //
\8c»
\8dÝ
\91I
\91ð
\82³
\82ê
\82Ä
\82¢
\82é
\83`
\83\83\83\93\83l
\83\8b
250 JoinChannelsBackup: TStringList; //
252 FDragTabIndex: integer; //
\83^
\83u
\83h
\83\89\83b
\83O
\83h
\83\8d\83b
\83v
\8aÖ
\98A
253 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)
255 FCueGhost: TID2Ghost;
257 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Ý)
258 FBeginConnectFailCount: integer; //
\89½
\93x
\82à
\90Ú
\91±
\8e¸
\94s
\82µ
\82½
\82ç
\83\8a\83g
\83\89\83C
\92\86\8e~
259 procedure SetStatusText(const Value: String);
260 procedure SetSleeping(const Value: boolean);
261 function T2C: TColor;
262 procedure ColorAgain;
264 procedure SetConnecting(const Value: boolean);
265 procedure SetAdded(const Value: boolean);
266 procedure mnConstClick(Sender: TObject);
267 property Added: boolean read FAdded write SetAdded;
268 property Sleeping: boolean read FSleeping write SetSleeping;
269 property StatusText: String read FStatusText write SetStatusText;
270 function GetScriptText: String;
271 procedure ChangeTaskIcon;
272 procedure ShowHintLabel(const Mes: String; Col: TColor = clBlue);
273 procedure UpdateLayout;
274 procedure ScriptColorChange(From, Length: integer; Col: TColor);
275 procedure DispatchBottle(EventType: TIdSlppEventType; Dat: THeadValue);
276 //
\83`
\83\83\83\93\83l
\83\8b\8aÖ
\8cW
277 procedure UpdateChannelInfo(Dat: THeadValue);
278 procedure UpdateJoinChannelList(Dat: THeadValue);
279 procedure NoLuidError;
280 procedure UpdateIfGhostBox;
281 function BuildMenuConditionCheck(const IfGhost, Ghost: String): boolean;
282 procedure BuildMenu(Root: TMenuItem; Event: TNotifyEvent; Simple: boolean);
283 procedure PlaySound(const FileName: String);
285 function DoTrans(var Script: String;
286 Options: TScriptTransOptions): String;
287 procedure BeginConnect;
288 procedure RetryBeginConnect;
289 procedure EndConnect;
290 procedure ConstructMenu(Simple: boolean);
291 property Connecting: boolean read FConnecting write SetConnecting;
292 function SetHWndToFavoriteGhost(const Ghost: String): String;
293 function GhostNameToSetName(const Ghost: String): String;
294 procedure PostCommand(const Command: array of String); overload;
295 procedure PostCommand(Command: TStrings); overload;
296 procedure PostSetChannel(Channels: TStrings);
297 procedure SaveChainRuleList;
302 frmSender: TfrmSender;
305 PanelConnecting = 0; //
\81u
\90Ú
\91±
\92\86\81v
\95\
\8e¦
\97p
306 PanelBytes = 1; //
\81\9b\81\9b\83o
\83C
\83g
307 PanelCount = 2; //Local Proxy
\81A
\8c»
\8dÝ
\81\9b\8c\8f\91Ò
\82¿
309 PanelStatus = 4; //
\93o
\98^
\82³
\82ê
\82Ä
\82¢
\82Ü
\82·
\81c
\82È
\82Ç
312 IconDisconnected = 18;
314 IconSleepDisconnected = 20;
316 WarningColor = clRed;
318 SendButtonLongHint = 'Bottle
\82Ì
\91\97\90M';
320 function Token(const Str: String; const Delimiter: char;
321 const Index: integer): String;
325 uses SendConfirm, SettingForm, ChannelListForm, LogForm,
326 MessageBox, FMOExplorer;
330 //
\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
331 function Token(const Str: String; const Delimiter: char;
332 const Index: integer): String;
333 var i, c, len: integer;
339 while i <= len do begin
340 if (Str[i] = Delimiter) and (StrByteType(PChar(Str), i) <> mbTrailByte) then begin
342 if c > Index then Break;
343 end else if c = Index then Result := Result + Str[i];
350 procedure TfrmSender.actConfirmExecute(Sender: TObject);
351 var Res: TSstpResult;
352 Script, Ghost, Err: String;
353 Opt: TScriptTransOptions;
355 if Length(GetScriptText) = 0 then Exit;
357 Script := GetScriptText;
358 if Pref.IgnoreTimeCritical then Opt := [toIgnoreTimeCritical] else Opt := [];
359 if Pref.NoTransUrl then Opt := Opt + [toNoChoice];
360 if Pref.HUTagTo01Tag then Opt := Opt + [toHUTagTo01Tag];
361 Err := DoTrans(Script, Opt + [toConvertURL, toWarnMessySurface]);
362 if Err <> '' then begin
366 if cbxTargetGhost.ItemIndex > 0 then begin
367 Ghost := cbxTargetGhost.Text
369 if FNowChannel <> '' then
370 Ghost := ChannelList.Channel[FNowChannel].Ghost;
372 Ghost := SetHWndToFavoriteGhost(Ghost);
373 DirectSstp.SstpSender := 'SSTP Bottle -
\81y
\8am
\94F
\81z';
375 Res := DirectSstp.SstpSEND(Script, [soNoTranslate], GhostNameToSetName(Ghost));
376 if Res <> srOk then begin
377 ShowHintLabel('
\91\97\90M
\8e¸
\94s:' + DirectSstp.RecvLog, WarningColor);
378 end else ShowHintLabel('');
381 procedure TfrmSender.FormCreate(Sender: TObject);
382 var Str: TStringList;
384 SakuraSeeker.OnDetectResultChanged := SakuraSeekerDetectResultChanged;
385 FConstDir := ExtractFileDir(Application.ExeName)+'\consts';
386 ScriptConstList.LoadFromDir(FConstDir);
387 ConstructMenu(false);
389 Str := TStringList.Create;
392 Str.LoadFromFile(ExtractFilePath(Application.ExeName)+'rule.txt');
393 BottleChainRuleList := StringToComponent(Str.Text) as TBottleChainRuleList;
396 Str.LoadFromFile(ExtractFilePath(Application.ExeName)+'defrule.txt');
397 BottleChainRuleList := StringToComponent(Str.Text) as TBottleChainRuleList;
399 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');
400 Application.Terminate;
401 Application.ProcessMessages;
409 FOriginalCaption := Self.Caption;
412 FMutex := OpenMutex(MUTEX_ALL_ACCESS, false, 'SSTPBottleClient2');
413 if FMutex <> 0 then begin
415 ShowMessage('SSTP Bottle Client
\82Í
\93ñ
\8fd
\8bN
\93®
\82Å
\82«
\82Ü
\82¹
\82ñ');
417 Application.Terminate;
418 Application.ProcessMessages; //WM_QUIT
\82ð
\97¬
\82·
421 FMutex := CreateMutex(nil, false, 'SSTPBottleClient2');
423 ShowMessage('
\93ñ
\8fd
\8bN
\93®
\8b\96\89Â
\83o
\81[
\83W
\83\87\83\93\82Å
\82·
\81B'#13#10 + VersionString);
427 mnShowToolBar.Checked := Pref.ShowToolBar;
428 mnShowConstBar.Checked := Pref.ShowConstBar;
429 if Pref.StayOnTop then begin
430 FormStyle := fsStayOnTop;
431 mnStayOnTop.Checked := true;
433 FormStyle := fsNormal;
434 mnStayOnTop.Checked := false;
436 mnColorScript.Checked := Pref.ColorScript;
438 mnGoToHP.Hint := Pref.HomePage;
439 mnGotoGlog.Hint := Pref.GLogPage;
440 mnGotoVote.Hint := Pref.VotePage;
441 mnGotoHelp.Hint := Pref.HelpPage;
443 mnGetNewId.Enabled := (Pref.LUID = '');
446 SsParser.TagPattern.LoadFromFile(ExtractFilePath(Application.Exename) + 'tagpat.txt');
447 SsParser.MetaPattern.LoadFromFile(ExtractFilePath(Application.ExeName) + 'metapat.txt');
449 ShowMessage('tagpat.txt, metapat.txt
\82ª
\8c©
\82Â
\82©
\82è
\82Ü
\82¹
\82ñ
\81B');
450 Application.Terminate;
453 with Pref.SenderWindowPosition do begin
456 Self.Width := Right - Left + 1;
457 Self.Height := Bottom - Top + 1;
460 //
\83`
\83\83\83\93\83l
\83\8b\83\8a\83X
\83g
461 FCueGhost := TID2Ghost.Create;
463 actClearExecute(Sender);
464 ApplicationEvents.OnIdle := ApplicationEventsIdle;
466 UpdateJoinChannelList(nil);
469 procedure TfrmSender.FormDestroy(Sender: TObject);
471 with Pref.SenderWindowPosition do begin
474 Right := Self.Left + Self.Width - 1;
475 Bottom := Self.Top + Self.Height - 1;
478 if JoinChannelsBackup <> nil then JoinChannelsBackup.Free;
479 if FCueGhost <> nil then FCueGhost.Free;
481 ScriptConstList.Save;
484 BottleChainRuleList.Free;
487 ReleaseMutex(FMutex);
492 procedure TfrmSender.SetConnecting(const Value: boolean);
494 FConnecting := Value;
496 StatusBar.Panels[PanelConnecting].Text := '
\92Ê
\90M
\92\86';
497 actStart.Enabled := false;
498 actStop.Enabled := false;
499 actSend.Enabled := false;
500 actVoteMessage.Enabled := false;
501 actAgreeMessage.Enabled := false;
502 mnGetNewId.Enabled := false;
503 Screen.Cursor := crAppStart;
505 StatusBar.Panels[PanelConnecting].Text := '';
506 actStart.Enabled := true;
507 actStop.Enabled := true;
508 actSend.Enabled := true;
509 //actVoteMessage.Enabled := true;
510 //actAgreeMessage.Enabled := true;
511 frmLog.lvwLogChange(Self, nil, ctState);
512 mnGetNewId.Enabled := Pref.LUID = '';
513 Screen.Cursor := crDefault;
517 procedure TfrmSender.actSendExecute(Sender: TObject);
518 var Talk, Ghost: String;
519 Command: TStringList;
523 if Length(GetScriptText) = 0 then begin
524 ShowMessage('
\83X
\83N
\83\8a\83v
\83g
\82ª
\8bó
\82Å
\82·
\81B');
528 if Pref.LUID = '' then begin
532 if tabChannel.TabIndex < 0 then begin
533 ShowMessage('
\83`
\83\83\83\93\83l
\83\8b\82É
\8eQ
\89Á
\82µ
\82Ä
\82¢
\82Ü
\82¹
\82ñ
\81B'#13#10+
534 '
\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');
537 if ChannelList.Channel[FNowChannel].NoPost then begin
539 ShowMessage(FNowChannel + '
\82Í
\8eó
\90M
\90ê
\97p
\82Å
\82·');
542 if not Pref.NoConfirm then begin
543 if not SendConfirmDialog(FNowChannel, cbxTargetGhost.Text) then Exit;
547 Talk := GetScriptText;
548 Err := DoTrans(Talk, [toWarnMessySurface]);
549 if Err <> '' then begin
550 MessageDlg(Err, mtWarning, [mbOk], 0);
555 if cbxTargetGhost.ItemIndex > 0 then Ghost := cbxTargetGhost.Text;
557 Command := TStringList.Create;
558 with Command do begin
559 Add('Command: sendBroadcast');
560 Add('Channel: ' + FNowChannel);
561 Add('LUID: ' + Pref.LUID);
562 Add('Agent: ' + VersionString);
563 if Ghost <> '' then Add('Ghost: ' + Ghost);
564 Add('Talk: ' + Talk);
566 PostCommand(Command);
571 //
\91\97\90M
\83\8d\83O
\95Û
\91¶
572 AssignFile(F, ExtractFilePath(Application.ExeName) + SentLogFile);
573 if FileExists(ExtractFilePath(Application.ExeName) + SentLogFile) then
577 WriteLn(F, Format('%s,%s,%s,%s', [FNowChannel, Ghost, FormatDateTime('yy/mm/dd hh:nn:ss', Now), Talk]));
582 procedure TfrmSender.BeginConnect;
584 if Pref.LUID = '' then begin
588 IdSlpp20.LUID := Pref.LUID;
589 self.Cursor := crHourGlass;
591 if IdSlpp20.Connected then IdSlpp20.Disconnect;
592 if Pref.UseHttpProxy then begin
593 IdSlpp20.Host := Pref.ProxyAddress;
594 IdSlpp20.Port := Pref.ProxyPort;
595 IdSlpp20.ProxyMode := true;
597 IdSlpp20.Host := 'bottle.mikage.to';
598 IdSlpp20.Port := 9871;
599 IdSlpp20.ProxyMode := false;
603 on EIdException do begin
605 if FBeginConnectFailCount = 0 then begin
606 Inc(FBeginConnectFailCount);
608 if Pref.UseHttpProxy then
609 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 +
610 '
\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 +
611 '
\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')
613 ShowMessage('SSTP Bottle
\83T
\81[
\83o
\82É
\90Ú
\91±
\82Å
\82«
\82Ü
\82¹
\82ñ
\82Å
\82µ
\82½
\81B'#13#10 +
614 '
\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 +
615 '
\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');
617 Inc(FBeginConnectFailCount);
620 self.Cursor := crDefault;
623 procedure TfrmSender.EndConnect;
625 IdSlpp20.OnDisconnect := nil;
629 procedure TfrmSender.SetAdded(const Value: boolean);
631 if FAdded = Value then Exit;
634 StatusText := 'SSTP Bottle
\83T
\81[
\83o
\82É
\90Ú
\91±
\82³
\82ê
\82Ä
\82¢
\82Ü
\82·';
636 ShowHintLabel('SSTP Bottle
\83T
\81[
\83o
\82ª
\8c©
\82Â
\82©
\82è
\82Ü
\82µ
\82½');
638 StatusText := '
\83T
\81[
\83o
\82Æ
\82Ì
\90Ú
\91±
\82ª
\90Ø
\82ê
\82Ä
\82¢
\82Ü
\82·!';
640 ShowHintLabel('SSTP Bottle
\83T
\81[
\83o
\82©
\82ç
\90Ø
\92f
\82³
\82ê
\82Ü
\82µ
\82½!', WarningColor);
644 procedure TfrmSender.HTTPSuccess(Sender: TObject);
645 var Str, ResStr, Command: String;
646 HeadValue: THeadValue;
648 SetChannel: TStringList;
651 Str := (Sender as THttpDownloadThread).RecvString;
655 HeadValue := THeadValue.Create(Str);
657 ShowMessage('SSTP Bottle
\83T
\81[
\83o
\82ª
\89ð
\90Í
\82Å
\82«
\82È
\82¢
\83G
\83\89\81[
\82ð
\95Ô
\82µ
\82Ü
\82µ
\82½
\81B');
660 Command := HeadValue['Command'];
661 ResStr := HeadValue['Result'];
662 if ResStr = 'Err' then begin
663 if HeadValue['ExtraMessage'] <> '' then begin
665 ShowMessage('SSTP Bottle
\83T
\81[
\83o
\82ª
\8e\9f\82Ì
\83G
\83\89\81[
\82ð
\95Ô
\82µ
\82Ü
\82µ
\82½:'#13#10 +
666 HeadValue['ExtraMessage']);
669 ShowMessage('SSTP Bottle
\83T
\81[
\83o
\82ª
\89½
\82ç
\82©
\82Ì
\83G
\83\89\81[
\82ð
\95Ô
\82µ
\82Ü
\82µ
\82½
\81B');
672 if (Command = 'sendBroadcast') and (ResStr = 'OK') then begin
673 ShowHintLabel(HeadValue['Channel'] + '
\82Ì ' + HeadValue['SentNum'] +
674 '
\90l
\82É
\91\97\90M
\82µ
\82Ü
\82µ
\82½');
675 //
\83S
\81[
\83X
\83g
\82ð
\83f
\83t
\83H
\83\8b\83g
\82É
\96ß
\82·
676 if Pref.ResetIfGhostAfterSend then begin
677 cbxTargetGhost.ItemIndex := 0;
679 //
\83X
\83N
\83\8a\83v
\83g
\82ð
\83N
\83\8a\83A
680 if Pref.ClearAfterSend then begin
683 end else if (Command = 'sendBroadcast') and (ResStr <> 'OK') then begin
684 ShowHintLabel('
\83\81\83b
\83Z
\81[
\83W
\82ð
\91\97\90M
\82Å
\82«
\82Ü
\82¹
\82ñ
\82Å
\82µ
\82½', WarningColor);
686 if (Command = 'getNewId') then begin
687 if ResStr = 'OK' then begin
688 Pref.LUID := HeadValue['NewID'];
689 ShowHintLabel('LUID
\8eæ
\93¾
\8a®
\97¹
\81B');
690 mnGetNewId.Enabled := false;
693 ShowHintLabel('LUID
\8eæ
\93¾
\82É
\8e¸
\94s
\82µ
\82Ü
\82µ
\82½');
696 if (Command = 'voteMessage') then begin
697 if ResStr = 'OK' then begin
698 ShowHintLabel('
\83\81\83b
\83Z
\81[
\83W
\82É
\93\8a\95[/
\93¯
\88Ó
\82µ
\82Ü
\82µ
\82½
\81B
\95[
\90\94: ' + HeadValue['Votes']);
701 if (Command = 'getChannels') and (ResStr = 'OK') then begin
702 UpdateChannelInfo(HeadValue);
705 if FAutoAddAfterGetChannel then begin
706 SetChannel := TStringList.Create;
707 if JoinChannelsBackup <> nil then begin
708 //
\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
709 SetChannel.Assign(JoinChannelsBackup);
711 //
\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¾
712 for i := 0 to Pref.AutoJoinChannels.Count-1 do begin
713 if ChannelList.Channel[Pref.AutoJoinChannels[i]] <> nil then
714 SetChannel.Add(Pref.AutoJoinChannels[i]);
718 if frmChannelList.Execute(ChannelList, JoinChannels) then begin
719 SetChannel := TStringList.Create;
720 SetChannel.Assign(frmChannelList.JoinList);
723 if SetChannel <> nil then PostSetChannel(SetChannel);
725 if SetChannel <> nil then FreeAndNil(SetChannel);
728 if (Command = 'setChannels') then begin
729 if ResStr <> 'OK' then begin
731 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¢');
732 ShowHintLabel('
\83`
\83\83\83\93\83l
\83\8b\90Ý
\92è
\82É
\8e¸
\94s
\82µ
\82Ü
\82µ
\82½', WarningColor);
735 if HeadValue['ExtraTip'] <> '' then ShowHintLabel(HeadValue['ExtraTip']);
741 procedure TfrmSender.actStartClick(Sender: TObject);
743 if Pref.LUID = '' then begin
747 if not IdSlpp20.Connected then begin
748 FBeginConnectFailCount := 0; //
\8e©
\93®
\8dÄ
\90Ú
\91±
\83J
\83E
\83\93\83^
\83\8a\83Z
\83b
\83g
752 FAutoAddAfterGetChannel := false;
753 PostCommand(['Command: getChannels']);
757 procedure TfrmSender.actStopExecute(Sender: TObject);
759 //
\8b
\90§
\8dÄ
\90Ú
\91±
\82ð
\8ds
\82¤
760 IdSlpp20.OnDisconnect := nil;
761 if IdSlpp20.Connected then IdSlpp20.Disconnect;
762 FAutoAddAfterGetChannel := true;
764 IdSlpp20.OnDisconnect := Slpp20Disconnect;
767 procedure TfrmSender.FormShow(Sender: TObject);
769 if FBooted or Application.Terminated then Exit;
770 //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
771 if Pref.LUID <> '' then BeginConnect
772 else mnGetNewIdClick(Self);
773 FAutoAddAfterGetChannel := Pref.AutoStart;
777 SakuraSeekerDetectResultChanged(Self);
780 procedure TfrmSender.mnAboutClick(Sender: TObject);
782 frmMessageBox.ShowMessage(VersionString + #13#10 + BottleDisclaimer);
785 procedure TfrmSender.actExitClientExecute(Sender: TObject);
790 procedure TfrmSender.actClearExecute(Sender: TObject);
791 var TmpScript: String;
794 TmpScript := Pref.DefaultScript;
795 if RegExp.Match('m/^((.|\s)*)\|/', TmpScript) then begin
796 Pos := length(RegExp[1]);
798 RegExp.Subst('s/\|//', TmpScript);
800 memScript.Lines.Text := TmpScript;
801 memScript.Text := TmpScript;
803 if Visible then memScript.SetFocus;
804 memScript.SelStart := Pos;
808 procedure TfrmSender.memScriptChange(Sender: TObject);
811 Script := StringReplace(GetScriptText, #13#10, '', [rfReplaceAll]);
812 StatusBar.Panels[PanelBytes].Text := IntToStr(length(Script)) + '
\83o
\83C
\83g';
815 procedure TfrmSender.mnStayOnTopClick(Sender: TObject);
817 Pref.StayOnTop := not Pref.StayOnTop;
818 mnStayOnTop.Checked := Pref.StayOnTop;
819 if Pref.StayOnTop then begin
820 FormStyle := fsStayOnTop;
822 FormStyle := fsNormal;
827 function TfrmSender.GetScriptText: String;
829 with memScript do begin
834 procedure TfrmSender.mnColorScriptClick(Sender: TObject);
836 mnColorScript.Checked := not mnColorScript.Checked;
837 Pref.ColorScript := mnColorScript.Checked;
842 procedure TfrmSender.mnConstClick(Sender: TObject);
845 i := (Sender as TMenuItem).Tag;
846 memScript.SelText := ScriptConstList.GetConstByID(i).ConstText;
849 procedure TfrmSender.actEditConstExecute(Sender: TObject);
851 ScriptConstList.LoadFromDir(FConstDir);
853 Application.CreateForm(TfrmConstEditor, frmConstEditor);
854 frmConstEditor.Execute;
855 ScriptConstList.Save;
857 frmConstEditor.Release;
859 ConstructMenu(false);
862 procedure TfrmSender.mnTaskBarClick(Sender: TObject);
864 Application.Minimize;
865 WindowState := wsNormal;
868 procedure TfrmSender.FormClose(Sender: TObject; var Action: TCloseAction);
873 procedure TfrmSender.ApplicationEventsMinimize(Sender: TObject);
876 Application.ShowMainForm := false;
877 ShowWindow(Application.Handle, SW_HIDE);
880 procedure TfrmSender.ApplicationEventsRestore(Sender: TObject);
882 Application.ShowMainForm := true;
886 procedure TfrmSender.mnTaskRestoreClick(Sender: TObject);
891 procedure TfrmSender.TaskTrayDblClick(Seft: TObject; Button: TMouseButton);
896 procedure TfrmSender.FormActivate(Sender: TObject);
901 procedure TfrmSender.mnTaskNewMessageClick(Sender: TObject);
904 actClearExecute(Sender);
907 procedure TfrmSender.ChangeTaskIcon;
912 if Sleeping then IcoNum := IconSleep else IcoNum := IconConnected;
914 if Sleeping then IcoNum := IconSleepDisconnected
915 else IcoNum := IconDisconnected;
919 imgIcon.GetIcon(IcoNum, Ico);
920 TaskTray.Icon := Ico;
921 TaskTray.Registered := true;
927 procedure TfrmSender.SetStatusText(const Value: String);
929 FStatusText := Value;
930 StatusBar.Panels[PanelStatus].Text := Value;
933 procedure TfrmSender.ApplicationEventsHint(Sender: TObject);
935 if Length(Application.Hint) > 0 then begin
936 StatusBar.Panels[PanelStatus].Text := GetLongHint(Application.Hint);
937 Application.HintColor := clInfoBk;
938 if (Application.Hint = SendButtonLongHint)
939 and (FNowChannel <> '') then begin
940 //
\91\97\90M
\83{
\83^
\83\93\82Ì
\8fê
\8d\87\82Í
\91¬
\8dU
\8fo
\82·
941 Application.HintColor := clYellow;
942 Application.ActivateHint(Mouse.CursorPos);
945 StatusBar.Panels[PanelStatus].Text := FStatusText;
948 procedure TfrmSender.ConstructMenu(Simple: boolean);
950 BuildMenu(mnPopConst, mnConstClick, Simple);
951 BuildMenu(mnPopUpConst.Items, mnConstClick, Simple);
952 BuildMenu(ConstBarMenu.Items, mnConstClick, Simple);
953 //ConstMenuBar.Menu := nil;
954 ConstMenuBar.AutoSize := false;
955 ConstMenuBar.Width := 1000;
956 ConstMenuBar.Menu := ConstBarMenu;
957 ConstMenuBar.AutoSize := true;
960 procedure TfrmSender.memScriptKeyDown(Sender: TObject; var Key: Word;
963 Func: TReturnKeyFunction;
965 if (Key = VK_RETURN) then begin
966 if (ssShift in Shift) then
967 Func := Pref.WhenShiftReturn
968 else if (ssCtrl in Shift) then
969 Func := Pref.WhenCtrlReturn
971 Func := Pref.WhenReturn;
974 with tbtnInsertConst do
975 Pos := tbtnInsertConst.ClientToScreen(Point(0, Height));
976 mnPopUpConst.Popup(Pos.X, Pos.Y);
979 memScript.SelText := '\n';
983 memScript.SelText := '\n'#13#10;
986 memScript.SelText := #13#10
992 procedure TfrmSender.mnShowToolBarClick(Sender: TObject);
994 mnShowToolBar.Checked := not mnShowToolBar.Checked;
995 Pref.ShowToolBar := mnShowToolBar.Checked;
999 procedure TfrmSender.mnShowConstBarClick(Sender: TObject);
1001 mnShowConstBar.Checked := not mnShowConstBar.Checked;
1002 Pref.ShowConstBar := mnShowConstBar.Checked;
1006 procedure TfrmSender.UpdateLayout;
1008 ToolBar.Visible := Pref.ShowToolBar;
1009 ConstMenuBar.Visible := Pref.ShowConstBar;
1012 with tabChannel do begin
1013 TabPosition := Pref.TabPosition;
1014 case Pref.TabPosition of
1015 tpTop: Align := alTop;
1016 tpBottom: Align := alBottom;
1021 function TfrmSender.T2C: TColor;
1023 if FInSynchronized then Result := Pref.TalkColorS
1024 else if FUnyuTalking then Result := Pref.TalkColorU else Result := Pref.TalkColorH;
1028 procedure TfrmSender.ApplicationEventsIdle(Sender: TObject;
1030 var St, Le: integer;
1032 i: integer; //
\83_
\83~
\81[
\83J
\83E
\83\93\83^
1034 if not Pref.ColorScript then Exit;
1035 if memScript.Modified and mnColorScript.Checked then begin
1036 FColorTimeLag := GetTickCount;
1037 memScript.Modified := false;
1039 if (FcolorTimeLag <> 0) and
1040 (FColorTimeLag + Pref.ColorTimeLagValue < GetTickCount) then begin
1044 if not FRequireColoring then Exit;
1045 memScript.Lines.BeginUpdate;
1046 St := memScript.SelStart;
1047 Le := memScript.SelLength;
1048 for i := 1 to Pref.ColorSpeed do begin
1049 if FColoredElements >= SsParser.Count then Break;
1050 if SsParser[FColoredElements] = '\u' then FUnyuTalking := true;
1051 if SsParser[FColoredElements] = '\h' then FUnyuTalking := false;
1052 if SsParser[FColoredElements] = '\_s' then FInSynchronized := not FInSynchronized;
1053 case SsParser.MarkUpType[FColoredElements] of
1054 mtTag: Col := Pref.MarkUpColor;
1055 mtTagErr: Col := Pref.MarkErrorColor;
1056 mtMeta: Col := Pref.MetaWordColor;
1060 ScriptColorChange(FColoringPos, Length(SsParser[FColoredElements]), Col);
1061 Inc(FColoringPos, Length(SsParser[FColoredElements]));
1062 Inc(FColoredElements);
1064 memScript.SelStart := St;
1065 memScript.SelLength := Le;
1066 memScript.Lines.EndUpdate;
1067 memScript.Modified := false;
1068 if FColoredElements >= SsParser.Count then FRequireColoring := false;
1072 procedure TfrmSender.ColorAgain;
1073 var St, Le: integer;
1075 if Pref.ColorScript then begin
1077 FColoredElements := 0;
1078 FUnyuTalking := false;
1079 FInSynchronized := false;
1081 FLastSurfaceU := 10;
1082 FRequireColoring := true;
1083 SsParser.InputString := memScript.Text;
1084 memScript.Modified := false;
1085 memScript.Color := Pref.BgColor;
1087 with memScript do begin
1091 SelLength := Length(Lines.Text);
1092 SelAttributes.Color := clWindowText;
1096 FRequireColoring := false;
1103 function TfrmSender.DoTrans(var Script: String;
1104 Options: TScriptTransOptions): String;
1105 var Orig, UrlCancel, Mark: String;
1106 Url, UrlName: array[0..6] of String;
1107 i, j, u, UrlCount: integer;
1108 LastSurfaceH, LastSurfaceU: integer;
1109 UnyuTalking: boolean;
1110 QuickSection: boolean;
1115 UnyuTalking := false;
1116 QuickSection := false;
1117 Orig := SsParser.InputString;
1118 SsParser.InputString := Script;
1120 for i := 0 to SsParser.Count-1 do begin
1121 if SsParser[i] = '\t' then begin
1122 if not(toIgnoreTimeCritical in Options) then
1123 Script := Script + '\t';
1124 end else if SsParser[i] = '\e' then begin
1126 end else if (SsParser.Match(SsParser[i], '\URL%b') > 0) then begin
1127 if toConvertURL in Options then begin
1128 UrlCount := 0; //
\91O
\82ÌURL
\83^
\83O
\82Ì
\89e
\8b¿
\82ð
\96³
\8e\8b\81B
1129 for u := 7 downto 1 do begin
1130 if (SsParser.Match(SsParser[i],
1131 '\URL%b'+StringReplace(StringOfChar('-', u*2),
1132 '-', '%b', [rfReplaceAll]))) > 0 then begin
1133 for j := 1 to u do begin
1134 Url[UrlCount] := SsParser.GetParam(SsParser[i], UrlCount*2+2);
1135 UrlName[UrlCount] := SsParser.GetParam(SsParser[i], UrlCount*2+3);
1136 if UrlName[UrlCount] = '' then UrlName[UrlCount] := Url[UrlCount];
1137 if Pos('http://', Url[UrlCount]) > 0 then Inc(UrlCount);
1140 if UrlCount > 0 then UrlCancel := SsParser.GetParam(SsParser[i], 1);
1141 if UrlCancel = '' then UrlCancel := '
\8ds
\82©
\82È
\82¢
\81@
\81@
\81@
\81@';
1143 if SsParser.Match(SsParser[i], '\URL%b%b') = 0 then begin //
\8aÈ
\88Õ
\94ÅURL
\95Ï
\8a·
1144 //
\8aÈ
\88Õ
\8c`
\8e®\URL
\83^
\83O
\95Ï
\8a·
1145 Url[0] := SsParser.GetParam(SsParser[i], 1);
1146 UrlName[0] := '
\8ds
\82
\81@
\81@
\81@
\81@
\81@
\81@';
1147 UrlCancel := '
\8ds
\82©
\82È
\82¢
\81@
\81@
\81@
\81@';
1148 if Pos('http://', Url[0]) > 0 then begin
1150 if not QuickSection then
1151 Script := Script + '\_q' + Url[0] + '\_q'
1153 Script := Script + Url[0];
1156 end else Script := Script + SsParser[i];
1158 Mark := SsParser[i];
1159 if Mark = '\h' then begin
1160 UnyuTalking := false;
1161 if toHUTagTo01Tag in Options then Mark := '\0';
1162 end else if Mark = '\u' then begin
1163 UnyuTalking := true;
1164 if toHUTagTo01Tag in Options then Mark := '\1';
1165 end else if Mark = '\_q' then begin
1166 QuickSection := not QuickSection;
1167 end else if SsParser.Match(Mark, '\s%b') > 0 then begin
1168 if UnyuTalking then begin
1169 LastSurfaceU := StrToIntDef(SsParser.GetParam(Mark, 1),
1172 LastSurfaceH := StrToIntDef(SsParser.GetParam(Mark, 1),
1175 end else if SsParser.Match(Mark, '\s%d') > 0 then begin
1176 if UnyuTalking then begin
1177 LastSurfaceU := StrToIntDef(Mark[3], LastSurfaceU);
1179 LastSurfaceH := StrToIntDef(Mark[3], LastSurfaceH);
1182 Script := Script + Mark;
1185 if UrlCount > 0 then begin
1186 Script := Script + '\h\n';
1187 if not (toNoChoice in Options) then begin
1188 for i := 0 to UrlCount-1 do begin
1189 Script := Script + Format('\q%d[%s][%s]',
1190 [i, SsParser.EscapeParam(Url[i]), UrlName[i]]);
1192 Script := Script + Format('\q%d[#cancel][%s]', [UrlCount, UrlCancel]);
1193 //Script := Script + '\z'; //
\8dÅ
\90Vphase
\82Å
\82Í
\8dí
\8f\9c
1195 Script := Script + '\h';
1196 for i := 0 to UrlCount-1 do begin
1197 Script := Script + Format('\n{%s}(%s)', [UrlName[i], Url[i]]);
1198 Script := Script + Format('\n{%s}', [UrlCancel]);
1202 //
\83X
\83N
\83\8a\83v
\83g
\82Ì
\8dÅ
\8cã
\82É
\83E
\83F
\83C
\83g
\91}
\93ü
1203 if toWaitScriptEnd in Options then begin
1204 i := Pref.WaitScriptEnd;
1205 while i > 0 do begin
1207 Script := Script + '\w9';
1210 Script := Script + '\w' + IntToStr(i);
1216 Script := Script + '\e';
1217 RegExp.Subst('s/\r\n//gk', Script);
1219 //
\83^
\83O
\83`
\83F
\83b
\83N
\8aÖ
\98A
1220 for i := 0 to SsParser.Count-1 do begin
1221 if SsParser.MarkUpType[i] = mtTagErr then begin
1222 Result := '"' + SsParser[i] + '"'#13#10 +
1223 '
\82Í
\81ASSTP Bottle
\82Å
\94F
\82ß
\82ç
\82ê
\82È
\82¢
\82©
\81A
\94F
\8e¯
\82Å
\82«
\82È
\82¢
\83^
\83O
\82Å
\82·
\81B';
1227 SsParser.InputString := Orig;
1230 procedure TfrmSender.mnGoToHPClick(Sender: TObject);
1232 ShellExecute(Handle, 'open', PChar(Pref.HomePage), nil, nil, SW_SHOW);
1235 procedure TfrmSender.ShowHintLabel(const Mes: String; Col: TColor);
1237 lblMessage.Caption := Mes;
1238 lblMessage.Font.Color := Col;
1239 lblMessage.Visible := true;
1240 LabelTimer.Enabled := false;
1241 LabelTimer.Enabled := true;
1244 procedure TfrmSender.LabelTimerTimer(Sender: TObject);
1246 LabelTimer.Enabled := false;
1247 lblmessage.Visible := false;
1250 procedure TfrmSender.ScriptColorChange(From, Length: integer; Col: TColor);
1251 //var Fmt: TCharFormat;
1253 memScript.SelStart := From;
1254 memScript.SelLength := Length;
1255 memScript.SelAttributes.Color := Col;
1258 procedure TfrmSender.actCopyAllExecute(Sender: TObject);
1262 Str := memScript.Text;
1263 Clip := ClipBoard();
1264 Clip.SetTextBuf(PChar(Str));
1267 procedure TfrmSender.actCopyAllNoReturnExecute(Sender: TObject);
1271 Str := memScript.Text;
1272 RegExp.Subst('s/\r\n//gk', Str);
1273 Clip := ClipBoard();
1274 Clip.SetTextBuf(PChar(Str));
1277 procedure TfrmSender.Slpp20SlppEvent(Sender: TObject; EventType: TIdSlppEventType;
1278 const Param: String);
1279 var HeadValue: THeadValue;
1283 HeadValue := THeadValue.Create(Param);
1285 etScript, etForceBroadcast, etUnicast: begin
1286 //
\83\81\83b
\83Z
\81[
\83W
\8eó
\90M
1287 HeadValue := THeadValue.Create(Param);
1288 DispatchBottle(EventType, HeadValue);
1290 etMemberCount: begin
1291 StatusBar.Panels[PanelMembers].Text := HeadValue['Num'] + '
\90l'
1293 etChannelCount: begin
1295 ChannelList.Channel[HeadValue['Channel']].Members := StrToInt(HeadValue['Num']);
1300 ShowHintLabel('SSTP Bottle
\83T
\81[
\83o
\82Æ
\92Ê
\90M
\8am
\97§
\81B');
1301 FBeginConnectFailCount := 0;
1302 //
\83`
\83\83\83\93\83l
\83\8b\8e©
\93®
\93o
\98^
1303 if not Connecting then
1304 PostCommand(['Command: getChannels']);
1306 etChannelList: begin
1307 UpdateJoinChannelList(HeadValue);
1308 //
\8dÅ
\8cã
\82É
\8eQ
\89Á
\82µ
\82Ä
\82¢
\82½
\83`
\83\83\83\93\83l
\83\8b\82ð
\8bL
\98^
\82·
\82é
1309 if JoinChannelsBackup = nil then JoinChannelsBackup := TStringList.Create;
1310 JoinChannelsBackup.Assign(JoinChannels);
1312 etCloseChannel: begin
1313 with JoinChannels do
1314 if IndexOf(HeadValue['Channel']) >= 0 then
1315 Delete(IndexOf(HeadValue['Channel']));
1316 with tabChannel do begin
1317 if Tabs.IndexOf(HeadValue['Channel']) >= 0 then
1318 Tabs.Delete(Tabs.IndexOf(HeadValue['Channel']));
1319 if Tabs.Count > 0 then TabIndex := 0 else TabIndex := -1;
1320 tabChannelChange(self);
1322 ShowHintLabel(HeadValue['Channel'] + '
\83`
\83\83\83\93\83l
\83\8b\82Í
\94p
\8e~
\82³
\82ê
\82Ü
\82µ
\82½',
1324 frmLog.AddCurrentSystemLog('SYSTEM', HeadValue['Channel'] + '
\83`
\83\83\83\93\83l
\83\8b\82Í
\94p
\8e~
\82³
\82ê
\82Ü
\82µ
\82½');
1325 frmMessageBox.ShowMessage(HeadValue['Channel'] + '
\83`
\83\83\83\93\83l
\83\8b\82Í
\94p
\8e~
\82³
\82ê
\82Ü
\82µ
\82½');
1327 etForceBroadcastInformation: begin
1328 if HeadValue['Type'] = 'Vote' then begin
1329 frmLog.VoteLog(HeadValue['MID'], StrToIntDef(HeadValue['Num'], 0));
1330 end else if HeadValue['Type'] = 'Agree' then begin
1331 frmLog.AgreeLog(HeadValue['MID'], StrToIntDef(HeadValue['Num'], 0));
1340 procedure TfrmSender.DirectSstpResendCountChange(Sender: TObject);
1342 StatusBar.Panels[PanelCount].Text := IntToStr(DirectSstp.CueCount) + '
\8c\8f';
1343 TaskTray.TipString := 'SSTP Bottle Client (' +
1344 IntToStr(DirectSstp.CueCount) + '
\8c\8f)';
1345 actClearBottles.Enabled := (DirectSstp.CueCount > 0);
1348 procedure TfrmSender.actSettingExecute(Sender: TObject);
1350 Application.CreateForm(TfrmSetting, frmSetting);
1360 mnColorScript.Checked := Pref.ColorScript;
1364 frmLog.UpdateWindow;
1367 procedure TfrmSender.memScriptKeyPress(Sender: TObject; var Key: Char);
1369 if (Key = #13) or (Key = #10) then Key := Char(0);
1372 procedure TfrmSender.Slpp20Disconnect(Sender: TObject);
1375 UpdateJoinChannelList(nil);
1376 frmLog.AddCurrentSystemLog('SYSTEM', '
\83T
\81[
\83o
\82©
\82ç
\90Ø
\92f
\82³
\82ê
\82Ü
\82µ
\82½');
1377 if not Application.Terminated then RetryBeginConnect;
1380 procedure TfrmSender.SetSleeping(const Value: boolean);
1383 DirectSstp.Sleep := Value;
1387 procedure TfrmSender.actClearBottlesExecute(Sender: TObject);
1390 Re := MessageDlg(Format('
\96¢
\94z
\91\97\82Ì%d
\8c\8f\82ÌBottle
\82ð
\91S
\95\94\83N
\83\8a\83A
\82µ
\82Ü
\82·', [DirectSstp.CueCount]),
1391 mtWarning, mbOkCancel, 0);
1392 if Re = mrOk then begin
1393 DirectSstp.ClearCue;
1394 frmLog.AllBottleOpened;
1395 frmLog.UpdateWindow;
1399 procedure TfrmSender.SakuraSeekerDetectResultChanged(Sender: TObject);
1402 Http: THTTPDownloadThread;
1405 UpdateIfGhostBox; //
\83h
\83\8d\83b
\83v
\83_
\83E
\83\93\82Ì
\92\86\90g
\82ð
\8f\91\82«
\8a·
\82¦
\82é
1406 //
\8d\91\90¨
\92²
\8d¸
\82É
\8eQ
\89Á
1407 if FBooted and not Pref.NoSendGhostList and (SakuraSeeker.Count > 0) then begin
1408 GhostList := 'CCC=' + TIdURI.ParamsEncode('
\88¤');
1409 GhostList := GhostList + '&LUID=' + Pref.LUID;
1411 for i := 0 to SakuraSeeker.Count-1 do begin
1412 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¤
1413 GhostList := GhostList + '&GHOST=' + TIdURI.ParamsEncode(SakuraSeeker[i].SetName);
1417 if SendOk then begin
1418 Http := THTTPDownloadThread.Create(BottleServer, Pref.CgiNameGhost, GhostList);
1419 if Pref.UseHttpProxy then begin
1420 Http.ProxyServer := Pref.ProxyAddress;
1421 Http.ProxyPort := Pref.ProxyPort;
1423 Http.FreeOnTerminate := true;
1429 procedure TfrmSender.UpdateChannelInfo(Dat: THeadValue);
1431 Ch: TChannelListItem;
1434 for i := 1 to Dat.IntData['Count'] do begin
1435 Ch := TChannelListItem.Create;
1436 Ch.Name := Dat[Format('CH%d_name', [i])];
1437 Ch.Ghost := Dat[Format('CH%d_ghost', [i])];
1438 Ch.Info := Dat[Format('CH%d_info', [i])];
1439 Ch.NoPost := Dat[Format('CH%d_nopost', [i])] = '1';
1440 Ch.Members := Dat.IntData[Format('CH%d_count', [i])];
1441 Ch.WarnPost:= Dat[Format('CH%d_warnpost', [i])] = '1';
1442 ChannelList.Add(Ch);
1447 procedure TfrmSender.mnGetNewIdClick(Sender: TObject);
1449 PostCommand(['Command: getNewId', 'Agent: ' + VersionString]);
1452 procedure TfrmSender.NoLuidError;
1455 ShowMessage('SSTP Bottle ID
\82Ì
\8eæ
\93¾
\82ª
\82Ü
\82¾
\8a®
\97¹
\82µ
\82Ä
\82¢
\82Ü
\82¹
\82ñ
\81B'#13#10+
1456 '
\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+
1457 '
\82±
\82Ì
\91\80\8dì
\82ÍClient
\8f\89\89ñ
\8bN
\93®
\8e\9e\82É1
\89ñ
\82¾
\82¯
\95K
\97v
\82Å
\82·
\81B');
1460 procedure TfrmSender.tabChannelChange(Sender: TObject);
1462 if tabChannel.TabIndex >= 0 then begin
1463 FNowChannel := tabChannel.Tabs[tabChannel.TabIndex];
1464 actSend.Hint := Format('
\81u%s
\81v
\82É
\91\97\90M|%s', [FNowChannel, SendButtonLongHint]);
1469 tabChannel.Repaint; //
\82±
\82ê
\82ª
\82È
\82¢
\82Æ
\90F
\82ª
\95Ï
\82í
\82ç
\82È
\82¢
\82±
\82Æ
\82ª
\82 \82é
1470 ConstructMenu(true);
1473 procedure TfrmSender.actPrevChannelExecute(Sender: TObject);
1475 with tabChannel do begin
1476 if Tabs.Count = 0 then Exit;
1477 if TabIndex=0 then TabIndex := Tabs.Count-1
1478 else TabIndex := TabIndex-1;
1480 tabChannelChange(Self);
1483 procedure TfrmSender.actNextChannelExecute(Sender: TObject);
1485 with tabChannel do begin
1486 if Tabs.Count = 0 then Exit;
1487 if TabIndex=Tabs.Count-1 then TabIndex := 0
1488 else TabIndex := TabIndex+1;
1490 tabChannelChange(Self);
1493 procedure TfrmSender.UpdateJoinChannelList(Dat: THeadValue);
1497 nodat := Dat = nil; //nil
\82È
\82ç
\83`
\83\83\83\93\83l
\83\8b\91S
\89ð
\8f\9c
1498 if nodat then Dat := THeadValue.Create('');
1500 for i := 0 to Dat.Count-1 do
1501 if Dat.KeyAt[i] = 'Entry' then begin
1502 if RegExp.Match('m/^(.+?) \((\d+?)\)$/', Dat.ValueAt[i]) then
1503 JoinChannels.Add(RegExp[1]);
1505 with tabChannel do begin
1510 for i := 0 to JoinChannels.Count-1 do begin
1511 //
\8eó
\90M
\90ê
\97p
\83`
\83\83\83\93\83l
\83\8b\82Í
\95\
\8e¦
\82µ
\82È
\82¢
1512 if not ChannelList.Channel[JoinChannels[i]].NoPost then
1513 Tabs.Add(JoinChannels[i]);
1517 for i := 0 to Tabs.Count-1 do
1518 if Tabs[i] = FNowChannel then TabIndex := i;
1519 if Tabs.Count > 0 then begin
1520 FNowChannel := Tabs[TabIndex];
1521 actSend.Hint := Format('
\81u%s
\81v
\82É
\91\97\90M|%s', [FNowChannel, SendButtonLongHint]);
1524 actSend.Hint := Format('
\91\97\90M|%s', [SendButtonLongHint]);
1526 Visible := Tabs.Count > 0;
1527 if Tabs.Count > 1 then begin
1528 actNextChannel.Enabled := true;
1529 actPrevChannel.Enabled := true;
1531 actNextChannel.Enabled := false;
1532 actPrevChannel.Enabled := false;
1534 OnChange := tabChannelChange;
1536 if nodat then Dat.Free;
1537 if JoinChannels.Count = 0 then begin
1538 Self.Caption := FOriginalCaption + ' -
\83`
\83\83\83\93\83l
\83\8b\82É
\8eQ
\89Á
\82µ
\82Ä
\82¢
\82Ü
\82¹
\82ñ';
1539 actSend.Enabled := false;
1541 Self.Caption := FOriginalCaption;
1542 actSend.Enabled := true;
1546 procedure TfrmSender.cbxTargetGhostDropDown(Sender: TObject);
1548 SakuraSeeker.BeginDetect;
1552 procedure TfrmSender.DirectSstpResendTrying(Sender: TObject; ID: Integer;
1553 const Script: String);
1554 var Ghost, Channel, MID: String;
1556 //
\83\81\83b
\83Z
\81[
\83WID
\82É
\89\9e\82¶
\82ÄSender, TargeHWnd
\82ð
\95Ï
\8dX
\82·
\82é
1557 FCueGhost.GetIdGhost(ID, Ghost, Channel, MID);
1558 frmLog.SetBottleStatusToPlaying(MID);
1559 DirectSstp.SstpSender := 'SSTP Bottle / ' + Channel;
1560 SetHWndToFavoriteGhost(Ghost);
1563 procedure TfrmSender.DirectSstpResendEnd(Sender: TObject; ID: Integer;
1564 const Script: String);
1565 var Ghost, Channel, MID: String;
1567 FCueGhost.GetIdGhost(ID, Ghost, Channel, MID);
1568 frmLog.SetBottleStatusToOpened(MID);
1569 FCueGhost.DeleteIdGhost(ID);
1572 procedure TfrmSender.actShowLogExecute(Sender: TObject);
1575 if frmLog.WindowState = wsMinimized then frmLog.WindowState := wsNormal;
1578 procedure TfrmSender.Slpp20Connect(Sender: TObject);
1583 procedure TfrmSender.actSleepExecute(Sender: TObject);
1585 if actSleep.Checked then begin
1586 actSleep.Checked := false;
1587 ShowHintLabel('
\83X
\83\8a\81[
\83v
\82ð
\89ð
\8f\9c\82µ
\82Ü
\82µ
\82½');
1589 actSleep.Checked := true;
1590 ShowHintLabel('
\83X
\83\8a\81[
\83v
\82ð
\90Ý
\92è
\82µ
\82Ü
\82µ
\82½');
1592 Sleeping := actSleep.Checked;
1597 procedure TfrmSender.DispatchBottle(EventType: TIdSlppEventType;
1599 var Opt: TSstpSendOptions;
1600 TransOpt: TScriptTransOptions;
1601 Event: TBottleChainBottleEvent;
1602 Script, Sender, Ghost, Channel, Err: String;
1604 BreakFlag, NoDispatch: boolean;
1605 Sound, LogName: String;
1606 i, j, k, SkipCount: integer;
1607 Rule: TBottleChainRule;
1608 Action: TBottleChainAction;
1609 LogNameList: TStringList;
1612 if Pref.NoTranslate then Opt := Opt + [soNoTranslate];
1613 if Pref.NoDescript then Opt := Opt + [soNoDescript];
1614 Channel := Dat['Channel'];
1616 etScript: Sender := Channel;
1617 etForceBroadcast: Sender := '
\81y
\82¨
\92m
\82ç
\82¹
\81z';
1618 etUnicast: Sender := Dat['SenderUID'];
1621 //
\96Ú
\95W
\83S
\81[
\83X
\83g
\8c\88\92è
1622 if Dat['IfGhost'] <> '' then begin
1623 Ghost := Dat['IfGhost'];
1625 if ChannelList.Channel[Channel] <> nil then
1626 Ghost := ChannelList.Channel[Channel].Ghost;
1628 Dat['TargetGhost'] := Ghost;
1630 Event := TBottleChainBottleEvent.Create;
1632 if EventType = etScript then Event.LogType := ltBottle
1633 else Event.LogType := ltSystemLog;
1635 //
\83X
\83N
\83\8a\83v
\83g
\95Ï
\8a·
1636 Script := Dat['Script'];
1637 if Pref.NoTransURL then
1638 TransOpt := [toConvertURL, toNoChoice, toWaitScriptEnd]
1640 TransOpt := [toConvertURL, toWaitScriptEnd];
1641 if Pref.IgnoreFrequentYenS then TransOpt := TransOpt + [toIgnoreFrequentYenS];
1642 if Pref.FixMessySurface then TransOpt := TransOpt + [toFixMessySurface];
1643 if Pref.HUTagTo01Tag then TransOpt := TransOpt + [toHUTagTo01Tag];
1644 Err := DoTrans(Script, TransOpt);
1645 if Err <> '' then begin
1646 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'+
1647 '
\94z
\91\97\82³
\82ê
\82Ü
\82¹
\82ñ
\82Å
\82µ
\82½
\81@
\81c '+Dat['Script']);
1652 NoDispatch := false;
1654 LogNameList := TStringList.Create;
1657 for i := 0 to BottleChainRuleList.Count-1 do begin
1658 if SkipCount > 0 then begin
1662 Rule := BottleChainRuleList[i];
1663 if not Rule.Enabled then Continue;
1664 if not Rule.Check(Event) then Continue;
1665 for j := 0 to Rule.Actions.Count-1 do begin
1666 Action := (Rule.Actions[j] as TBottleChainAction);
1667 if Action is TBottleChainAbortRuleAction then BreakFlag := true;
1668 if Action is TBottleChainSkipRuleAction then
1669 SkipCount := (Action as TBottleChainSkipRuleAction).SkipCount;
1670 if (Action is TBottleChainSoundAction) and (Sound = '') then begin
1671 Sound := (Action as TBottleChainSoundAction).SoundFile;
1672 Sound := StringReplace(Sound, '%channel%', Dat['Channel'], [rfReplaceAll]);
1673 Sound := StringReplace(Sound, '%ghost%', Dat['TargetGhost'], [rfReplaceAll]);
1675 if Action is TBottleChainNoDispatchAction then NoDispatch := true;
1676 if Action is TBottleChainLogAction then begin
1677 for k := 0 to (Action as TBottleChainLogAction).LogNames.Count-1 do begin
1678 LogName := (Action as TBottleChainLogAction).LogNames[k];
1679 LogName := StringReplace(LogName, '%channel%', Dat['Channel'], [rfReplaceAll]);
1680 LogName := StringReplace(LogName, '%ghost%', Dat['TargetGhost'], [rfReplaceAll]);
1681 LogName := StringReplace(LogName, '%date%', FormatDateTime('yy/mm/dd', Now()), [rfReplaceAll]);
1682 LogNameList.Add(LogName);
1685 if Action is TBottleChainOverrideGhostAction then begin
1686 Dat['TargetGhost'] := (Action as TBottleChainOverrideGhostAction).TargetGhost;
1688 if Action is TBottleChainQuitAction then Application.Terminate;
1690 if BreakFlag then Break;
1693 if Dat['Script'] <> '' then begin
1694 for i := 0 to LogNameList.Count-1 do
1695 frmLog.AddCurrentScriptLog(LogNameList[i], Dat['Script'], Sender, Dat['MID'], Dat['IfGhost']);
1696 if NoDispatch then begin
1697 frmLog.SetBottleStatusToOpened(Dat['MID']);
1699 Ghost := Dat['TargetGhost']; //
\83I
\81[
\83o
\81[
\83\89\83C
\83h
\82³
\82ê
\82Ä
\82¢
\82é
\89Â
\94\
\90«
\82ª
\82 \82é
1700 CueID := DirectSstp.SstpSENDCue(Script, false, Opt, GhostNameToSetName(Ghost));
1701 if Dat['IfGhost'] <> '' then Sender := Sender + '/' + Ghost; // Dat['IfGhost'];
1702 FCueGhost.AddIdGhost(CueID, Ghost, Sender, Dat['MID']);
1706 if Dat['DialogMessage'] <> '' then begin
1708 frmMessageBox.ShowMessage(
1709 DateTimeToStr(Now) + #13#10 +
1710 'SSTP Bottle
\83T
\81[
\83o
\82©
\82ç
\82¨
\92m
\82ç
\82¹'#13#10+Dat['DialogMessage']);
1711 for i := 0 to LogNameList.Count-1 do
1712 frmLog.AddCurrentSystemLog(LogNameList[i], Dat['DialogMessage']);
1716 if (Sound <> '') then PlaySound(Sound);
1722 function TfrmSender.SetHWndToFavoriteGhost(const Ghost: String): String;
1724 //DirectSstp.TargetHWnd
\82ð
\81A
\90\84\8f§
\82·
\82é
\83S
\81[
\83X
\83g
\82É
\90Ý
\92è
\82·
\82é
\81B
1725 //
\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
1726 SakuraSeeker.BeginDetect; //
\8dÅ
\90V
\82ÌFMO
\8eæ
\93¾
1727 if SakuraSeeker.ProcessByName[Ghost] <> nil then begin
1728 DirectSstp.TargetHWnd := SakuraSeeker.ProcessByName[Ghost].HWnd;
1730 end else if SakuraSeeker.Count > 0 then begin
1731 DirectSstp.TargetHWnd := SakuraSeeker[0].HWnd;
1732 Result := SakuraSeeker[0].Name;
1734 DirectSstp.TargetHwnd := 0;
1739 procedure TfrmSender.YenETrans;
1740 var St, Le, i: integer;
1743 St := memScript.SelStart;
1744 Le := memScript.SelLength;
1745 Orig := GetScriptText;
1746 RegExp.Subst('s/(\r\n)+$//kg', Orig);
1748 if SsParser.InputString <> Orig then begin
1749 //
\90F
\95ª
\82¯
\92x
\89\84\82Ì
\90Ý
\92è
\82É
\82æ
\82Á
\82Ä
\82Í
\82±
\82Ì2
\82Â
\82ª
\90H
\82¢
\88á
\82¤
\89Â
\94\
\90«
\82ª
\82 \82é
1750 SsParser.InputString := Orig
1752 for i := 0 to SsParser.Count-1 do begin
1753 if SsParser[i] <> '\e' then Text := Text + SsParser[i];
1756 Text := Text + '\e';
1758 if Orig <> Text then memScript.Lines.Text := Text;
1759 SsParser.InputString := Text;
1761 RegExp.Subst('s/\r\n//kg', Text);
1763 memScript.SelStart := St;
1764 memScript.SelLength := Le;
1767 procedure TfrmSender.PostCommand(const Command: array of String);
1768 var PostStr: TStringList;
1773 PostStr := TStringList.Create;
1774 for i := Low(Command) to High(Command) do begin
1775 PostStr.Add(Command[i]);
1777 PostCommand(PostStr);
1783 procedure TfrmSender.PostCommand(Command: TStrings);
1784 var PostStr: String;
1787 PostStr := Command.Text;
1788 PostStr := TIdURI.ParamsEncode(PostStr);
1790 FHttp := THTTPDownloadThread.Create(BottleServer, Pref.CgiName, PostStr);
1791 if Pref.UseHttpProxy then begin
1792 FHttp.ProxyServer := Pref.ProxyAddress;
1793 FHttp.ProxyPort := Pref.ProxyPort;
1795 FHttp.OnSuccess := HttpSuccess;
1796 FHttp.OnConnectionFailed := HttpFailure;
1797 FHttp.FreeOnTerminate := true; //
\8f\9f\8eè
\82É
\8e©
\95ª
\82ÅFree
\82µ
\82Ä
\82
\82¾
\82³
\82¢
1800 on EHeapException do begin
1801 Connecting := false;
1807 procedure TfrmSender.tabChannelDrawTab(Control: TCustomTabControl;
1808 TabIndex: Integer; const Rect: TRect; Active: Boolean);
1811 with tabChannel.Canvas do begin
1813 if Active then begin
1814 Font.Color := clBlue;
1816 Font.Style := Font.Style - [fsBold];
1817 Font.Color := clWindowText;
1819 X := (Rect.Left + Rect.Right) div 2;
1820 X := X - TextWidth(tabChannel.Tabs[TabIndex]) div 2;
1821 if tabChannel.TabPosition = tpTop then
1824 Y := Rect.Bottom - 15;
1825 TextOut(X, Y, tabChannel.Tabs[TabIndex]);
1829 procedure TfrmSender.actVoteMessageExecute(Sender: TObject);
1832 if frmLog.lvwLog.Selected = nil then Exit;
1833 Log := frmLog.SelectedBottleLog[frmLog.lvwLog.Selected.Index] as TLogItem;
1834 if Log = nil then Exit;
1835 if Log.LogType <> ltBottle then Exit;
1837 'Command: voteMessage',
1839 'LUID: ' + Pref.LUID,
1845 procedure TfrmSender.actAgreeMessageExecute(Sender: TObject);
1848 if frmLog.lvwLog.Selected = nil then Exit;
1849 Log := frmLog.SelectedBottleLog[frmLog.lvwLog.Selected.Index] as TLogItem;
1850 if Log = nil then Exit;
1851 if Log.LogType <> ltBottle then Exit;
1853 'Command: voteMessage',
1855 'LUID: ' + Pref.LUID,
1861 function TfrmSender.GhostNameToSetName(const Ghost: String): String;
1863 if SakuraSeeker.ProcessByName[Ghost] <> nil then
1864 Result := SakuraSeeker.ProcessByName[Ghost].SetName
1869 procedure TfrmSender.tabChannelContextPopup(Sender: TObject;
1870 MousePos: TPoint; var Handled: Boolean);
1873 with tabChannel do begin
1874 Tag := IndexOfTabAt(MousePos.X, MousePos.Y);
1875 if Tag < 0 then Handled := true;
1880 procedure TfrmSender.PostSetChannel(Channels: TStrings);
1881 var PostStr: TStringList;
1886 PostStr := TStringList.Create;
1887 with PostStr do begin
1888 Add('Command: setChannels');
1889 Add('Agent: ' + VersionString);
1890 Add('LUID: ' + Pref.LUID);
1891 if Channels <> nil then
1892 for i := 0 to Channels.Count-1 do begin
1893 Add(Format('Ch%d: %s'#13#10, [i+1, Channels[i]]));
1896 PostCommand(PostStr);
1902 procedure TfrmSender.mnLeaveThisChannelClick(Sender: TObject);
1906 with tabChannel do Ch := Tabs[Tag];
1909 Chs := TStringList.Create;
1910 Chs.Assign(JoinChannels);
1911 while Chs.IndexOf(Ch) >= 0 do Chs.Delete(Chs.IndexOf(Ch));
1912 PostSetChannel(Chs);
1918 procedure TfrmSender.mnGotoVoteClick(Sender: TObject);
1920 ShellExecute(Handle, 'open', PChar(Pref.VotePage), nil, nil, SW_SHOW);
1923 procedure TfrmSender.mnGotoGLogClick(Sender: TObject);
1925 ShellExecute(Handle, 'open', PChar(Pref.GLogPage), nil, nil, SW_SHOW);
1928 procedure TfrmSender.tabChannelMouseMove(Sender: TObject;
1929 Shift: TShiftState; X, Y: Integer);
1933 with tabChannel do begin
1934 Index := IndexOfTabAt(X, Y);
1936 Hint := Ch + ': ' + IntToStr(ChannelList.Channel[Ch].Members) + '
\90l';
1940 procedure TfrmSender.mnGoToHelpClick(Sender: TObject);
1942 ShellExecute(Handle, 'open', PChar(Pref.HelpPage), nil, nil, SW_SHOW);
1945 procedure TfrmSender.tabChannelMouseDown(Sender: TObject;
1946 Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
1949 with tabChannel do begin
1950 Index := IndexOfTabAt(X, Y);
1951 if Index = -1 then Exit; //
\83^
\83u
\82ª
\82È
\82¢
\82Ì
\82Å
\83h
\83\89\83b
\83O
\82Å
\82«
\82È
\82¢
1952 if Button = mbLeft then begin
1953 FDragTabIndex := Index; //
\83h
\83\89\83b
\83O
\82·
\82é
\83^
\83u
\82Ì
\83C
\83\93\83f
\83b
\83N
\83X
\82ð
\95Û
\91¶
1955 FDragTabDest := -1; //
\83h
\83\89\83b
\83O
\98g
\90ü
\95`
\89æ
\83t
\83\89\83O
\83N
\83\8a\83A
\82Ì
\82½
\82ß
1960 procedure TfrmSender.tabChannelDragOver(Sender, Source: TObject; X,
1961 Y: Integer; State: TDragState; var Accept: Boolean);
1962 var TargetRect: TRect;
1965 Accept := Source = tabChannel;
1966 if not Accept then Exit;
1967 with tabChannel do begin
1968 OldDest := FDragTabDest;
1969 FDragTabDest := IndexOfTabAt(X, Y);
1970 if FDragTabDest = -1 then begin
1971 Accept := false; //
\82±
\82Ì
\8fê
\8d\87\82Í
\83h
\83\8d\83b
\83v
\82ð
\94F
\82ß
\82È
\82¢
1974 with Canvas do begin
1978 if (OldDest <> FDragTabDest) and (OldDest >= 0) then begin
1979 //
\88È
\91O
\82Ì
\98g
\90ü
\8fÁ
\8b\8e
1980 TargetRect := TabRect(OldDest);
1981 with Canvas do begin
1982 Brush.Style := bsClear;
1983 Rectangle(TargetRect.Left, TargetRect.Top,
1984 TargetRect.Right, TargetRect.Bottom);
1987 if (OldDest <> FDragTabDest) then begin
1988 //
\90V
\82µ
\82¢
\98g
\90ü
\95`
\89æ
1989 TargetRect := TabRect(FDragTabDest);
1990 with Canvas do begin
1991 Brush.Style := bsClear;
1992 Rectangle(TargetRect.Left, TargetRect.Top,
1993 TargetRect.Right, TargetRect.Bottom);
1999 procedure TfrmSender.tabChannelDragDrop(Sender, Source: TObject; X,
2001 var DestIndex: integer;
2003 with tabChannel do begin
2004 DestIndex := IndexOfTabAt(X, Y);
2005 Tabs.Move(FDragTabIndex, DestIndex);
2009 procedure TfrmSender.tabChannelEndDrag(Sender, Target: TObject; X,
2012 //
\8b
\90§
\93I
\82É
\83^
\83u
\82ð
\8dÄ
\95`
\89æ
\82³
\82¹
\82é
\81B
\98g
\90ü
\8fÁ
\82µ
\91Î
\8dô
2013 tabChannel.Tabs.BeginUpdate;
2014 tabChannel.Tabs.EndUpdate;
2017 procedure TfrmSender.cbxTargetGhostDrawItem(Control: TWinControl;
2018 Index: Integer; Rect: TRect; State: TOwnerDrawState);
2020 with cbxTargetGhost do begin
2021 if Index > 0 then begin
2022 if SakuraSeeker.ProcessByName[Items[Index]] = nil then
2023 Canvas.Font.Color := clRed
2025 Canvas.Font.Color := clBlue;
2026 Canvas.Font.Style := [fsBold];
2028 Canvas.Font.Color := clWindowText;
2029 Canvas.Font.Style := [];
2031 if odSelected in State then
2032 Canvas.Font.Color := clHighlightText;
2033 cbxTargetGhost.Canvas.TextRect(Rect, Rect.Left, Rect.Top,
2034 cbxTargetGhost.Items[Index]);
2038 procedure TfrmSender.FormCloseQuery(Sender: TObject;
2039 var CanClose: Boolean);
2041 if not Pref.ConfirmOnExit then Exit;
2042 if MessageDlg('SSTP Bottle Client
\82ð
\8fI
\97¹
\82µ
\82Ü
\82·', mtConfirmation,
2043 mbOkCancel, 0) = mrCancel then CanClose := false;
2046 procedure TfrmSender.UpdateIfGhostBox;
2051 cbxTargetGhost.DropDownCount := Pref.GhostDropDownCount;
2052 Selected := cbxTargetGhost.Text;
2053 with cbxTargetGhost do begin
2056 Items.Add('(CH
\90\84\8f§)');
2057 for i := 0 to SakuraSeeker.Count-1 do begin
2058 //
\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é
2059 if Length(SakuraSeeker[i].Name) = 0 then Continue;
2060 if cbxTargetGhost.Items.IndexOf(SakuraSeeker[i].Name) < 0 then
2061 cbxTargetGhost.Items.Add(SakuraSeeker[i].Name);
2064 cbxTargetGhost.ItemIndex := 0;
2065 if (Length(Selected) > 0) and (Selected <> '(CH
\90\84\8f§)') then begin
2066 with cbxTargetGhost do begin
2067 for i := 1 to Items.Count-1 do begin
2068 if Items[i] = Selected then
2071 //
\83S
\81[
\83X
\83g
\82ª
\93Ë
\91R
\91¶
\8dÝ
\82µ
\82È
\82
\82È
\82Á
\82½
\8fê
\8d\87\91Î
\8dô
2072 if ItemIndex = 0 then begin
2073 Items.Add(Selected);
2074 ItemIndex := Items.Count - 1;
2082 procedure TfrmSender.HTTPFailure(Sender: TObject);
2086 ShowHintLabel('SSTP Bottle
\83T
\81[
\83o
\82Æ
\82Ì
\90Ú
\91±
\82É
\8e¸
\94s
\82µ
\82Ü
\82µ
\82½', WarningColor);
2087 ShowMessage((Sender as THTTPDownloadThread).LastErrorMessage);
2088 Connecting := false;
2091 procedure TfrmSender.actPrevGhostExecute(Sender: TObject);
2094 SakuraSeeker.BeginDetect;
2096 i := cbxTargetGhost.ItemIndex;
2098 if i <= -1 then i := cbxTargetGhost.Items.Count-1;
2099 cbxTargetGhost.ItemIndex := i;
2100 cbxTargetGhostChange(self);
2103 procedure TfrmSender.actNextGhostExecute(Sender: TObject);
2106 SakuraSeeker.BeginDetect;
2108 i := cbxTargetGhost.ItemIndex;
2110 if i > cbxTargetGhost.Items.Count-1 then i := 0;
2111 cbxTargetGhost.ItemIndex := i;
2112 cbxTargetGhostChange(self);
2115 procedure TfrmSender.actResetGhostExecute(Sender: TObject);
2117 cbxTargetGhost.ItemIndex := 0; // (CH
\90\84\8f§)
\82É
\96ß
\82·
2118 if Visible then memScript.SetFocus;
2119 cbxTargetGhostChange(self);
2122 procedure TfrmSender.timDisconnectCheckTimerTimer(Sender: TObject);
2124 if (IdSlpp20.LastReadTimeInterval > BottleServerTimeOut) then begin
2126 frmLog.AddCurrentSystemLog('SYSTEM', 'SSTP Bottle
\83T
\81[
\83o
\82Æ
\82Ì
\90Ú
\91±
\82ª
\83^
\83C
\83\80\83A
\83E
\83g
\82µ
\82Ü
\82µ
\82½');
2127 if IdSlpp20.Connected then IdSlpp20.Disconnect;
2129 if not IdSlpp20.Connected then begin
2131 Slpp20Disconnect(self); //
\82È
\82º
\82©Disconnect
\83C
\83x
\83\93\83g
\82ª
\8bN
\82±
\82ç
\82¸
\82É
\90Ø
\92f
\82µ
\82½
\8fê
\8d\87
2133 //
\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
2134 //
\82½
\82¾
\82µ
\89ñ
\90\94\90§
\8cÀ
\82 \82è
2140 procedure TfrmSender.RetryBeginConnect;
2142 if FBeginConnectFailCount < 3 then begin
2143 //
\90Ø
\92f
\82³
\82ê
\82Ä
\82¢
\82ê
\82Î
\8dÄ
\90Ú
\91±
2144 FAutoAddAfterGetChannel := true;
2146 end else if FBeginConnectFailCount = 3 then begin
2147 frmLog.AddCurrentSystemLog('SYSTEM', '
\8dÄ
\90Ú
\91±
\8e©
\93®
\83\8a\83g
\83\89\83C
\82ð
\92\86\8e~
\82µ
\82Ü
\82·');
2148 frmMessageBox.ShowMessage(
2149 'SSTP Bottle
\83T
\81[
\83o
\82É
\90Ú
\91±
\82Å
\82«
\82Ü
\82¹
\82ñ
\81B'#13#10+
2150 '
\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+
2151 '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'
2153 Inc(FBeginConnectFailCount);
2157 procedure TfrmSender.actDownloadLogExecute(Sender: TObject);
2158 var BottleLog: TBottleLogList;
2160 Cond: TBottleLogDownloadCondition;
2162 function TimeStr(Mins: integer): String;
2163 var day, hour, min: integer;
2165 day := Mins div (60 * 24);
2166 hour := (Mins div 60) mod 24;
2169 if day > 0 then Result := Result + Format('%d
\93ú', [day]);
2170 if hour > 0 then Result := Result + Format('%d
\8e\9e\8aÔ', [hour]);
2171 if (min > 0) or (Result = '') then Result := Result + Format('%d
\95ª', [min]);
2174 Application.CreateForm(TfrmLogDownload, frmLogDownload);
2176 if frmLogDownload.Execute then begin
2177 with frmLogDownload do begin
2178 if IsRange then begin
2179 if CompareDate(DateLo, DateHi) = 0 then
2180 Title := FormatDateTime('yy/mm/dd', DateLo)
2182 Title := FormatDateTime('yy/mm/dd', DateLo) + ' - ' + FormatdateTime('yy/mm/dd', DateHi);
2184 Title := Format('
\89ß
\8b\8e%s', [TimeStr(RecentCount)]);
2186 if Channel <> '' then Title := Title + '(' + Channel + ')';
2189 BottleLog := TBottleLogList.Create(Title);
2190 BottleLog.OnLoaded := frmLog.LogLoaded;
2191 BottleLog.OnLoadFailure := frmLog.LogLoadFailure;
2192 BottleLog.OnLoadWork := frmLog.LogLoadWork;
2193 with frmLogDownload do begin
2194 Cond.IsRange := IsRange;
2195 Cond.RecentCount := RecentCount;
2196 Cond.DateLo := DateLo;
2197 Cond.DateHi := DateHi;
2198 Cond.MinVote := MinVote;
2199 Cond.MinAgree := MinAgree;
2200 Cond.Channel := Channel;
2202 BottleLog.LoadFromWeb(Cond);
2204 FreeAndNil(BottleLog);
2206 if BottleLog <> nil then begin
2207 NewIndex := frmLog.BottleLogList.Add(BottleLog);
2209 frmLog.tabBottleLog.TabIndex := NewIndex;
2210 frmLog.UpdateWindow;
2214 frmLogDownload.Release;
2218 function TfrmSender.BuildMenuConditionCheck(const IfGhost,
2219 Ghost: String): boolean;
2226 Cond := Token(IfGhost, ',', i);
2227 if Cond <> '' then begin
2228 if Cond[1] = '!' then begin
2229 Cond := Copy(Cond, 2, High(integer));
2230 if Cond = Ghost then Result := false;
2232 if Cond <> Ghost then Result := false;
2239 procedure TfrmSender.BuildMenu(Root: TMenuItem; Event: TNotifyEvent; Simple: boolean);
2240 var i, j, k, count: integer;
2241 ConstData: TScriptConst;
2242 Menu1, Menu2: TMenuItem;
2245 // Simple = false
\82Ì
\8fê
\8d\87\82Í
\83\81\83j
\83\85\81[
\82ð
\8a®
\91S
\82É
\8dÄ
\8d\
\92z
\82·
\82é
\81B
2246 // 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
2247 if cbxTargetGhost.ItemIndex > 0 then Ghost := cbxTargetGhost.Text
2248 else if FNowChannel <> '' then Ghost := ChannelList.Channel[FNowChannel].Ghost;
2250 //
\8aù
\91¶
\82Ì
\83\81\83j
\83\85\81[
\8dí
\8f\9c
2251 if Simple then begin
2252 // IfGhost
\8fð
\8c\8f\95t
\82«
\83\81\83j
\83\85\81[
\82Ì
\82Ý
\8dí
\8f\9c
2253 for i := Root.Count-1 downto 0 do begin
2254 if ScriptConstList.GetMenuByID(Root.Items[i].Tag).IfGhost <> '' then
2258 //
\91S
\95\94\8dí
\8f\9c
2259 for i := Root.Count-1 downto 0 do begin
2265 for i := 0 to ScriptConstList.Count-1 do begin
2266 for j := 0 to ScriptConstList[i].Count-1 do begin
2267 //
\83S
\81[
\83X
\83g
\88á
\82¢
\82Ì
\8fê
\8d\87\82Í
\83X
\83L
\83b
\83v
2268 if not BuildMenuConditionCheck(ScriptConstList[i][j].IfGhost, Ghost) then Continue;
2270 // 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
2271 if Simple and (count < Root.Count) then
2272 if (Root.Items[count].Tag = ScriptConstList[i][j].ID) then begin
2276 Menu1 := TMenuItem.Create(Root);
2277 Menu1.Caption := ScriptConstList[i][j].Caption;
2278 Menu1.Hint := ScriptConstList[i][j].Caption;
2279 Menu1.AutoHotkeys := maManual;
2280 Menu1.Tag := ScriptConstList[i][j].ID;
2282 if not Simple then begin
2285 if count < Root.Count-1 then
2286 Root.Insert(count, Menu1)
2291 Menu1.Enabled := ScriptConstList[i][j].Count > 0;
2292 for k := 0 to ScriptConstList[i][j].Count-1 do begin
2293 ConstData := ScriptConstList[i][j][k];
2294 Menu2 := TMenuItem.Create(Root);
2295 Menu2.Caption := ConstData.Caption;
2296 Menu2.Hint := ConstData.ConstText;
2297 if ConstData.ShortCut <> 0 then Menu2.Hint := Menu2.Hint
2298 + ' (' + ShortCutToText(ConstData.ShortCut) + ')';
2299 Menu2.ShortCut := ConstData.ShortCut;
2300 Menu2.OnClick := Event;
2301 Menu2.AutoHotkeys := maManual;
2302 Menu2.Tag := ConstData.ID;
2303 if (k mod 15 = 0) and (k > 0) then Menu2.Break := mbBarBreak;
2310 procedure TfrmSender.cbxTargetGhostChange(Sender: TObject);
2312 ConstructMenu(true);
2315 procedure TfrmSender.PlaySound(const FileName: String);
2317 if Pref.SilentWhenHidden and not Application.ShowMainForm then Exit;
2319 MediaPlayer.FileName := FileName;
2323 on E: EMCIDeviceError do begin
2324 ShowMessage('
\83T
\83E
\83\93\83h
\8dÄ
\90¶
\83G
\83\89\81[:'#13#10 + FileName + #13#10#13#10 + E.Message);
2329 procedure TfrmSender.actFMOExplorerExecute(Sender: TObject);
2331 frmFMOExplorer.Show;
2334 procedure TfrmSender.SaveChainRuleList;
2335 var Str: TStringList;
2337 Str := TStringList.Create;
2339 Str.Text := ComponentToString(BottleChainRuleList);
2340 Str.SaveToFile(ExtractFileDir(Application.ExeName)+'\rule.txt');