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;
40 mnPopConst: TMenuItem;
45 mnSelectAll: TMenuItem;
47 ApplicationEvents: TApplicationEvents;
48 mnPopUpTaskTray: TPopupMenu;
49 mnTaskStart: TMenuItem;
51 mnTaskRestore: TMenuItem;
52 mnTaskNewMessage: TMenuItem;
56 mnTaskExit: TMenuItem;
65 mnPopupConst: TPopupMenu;
66 actEditConst: TAction;
68 mnShowToolBar: TMenuItem;
69 mnShowConstBar: TMenuItem;
70 ConstBarMenu: TMainMenu;
72 tbtnClear: TToolButton;
73 tbtnConfirm: TToolButton;
74 tbtnSend: TToolButton;
75 tbtnSeparator: TToolButton;
76 tbtnStart: TToolButton;
77 tbtnSeparator2: TToolButton;
78 tbtnInsertConst: TToolButton;
79 ConstMenuBar: TMenuBar;
82 mnColorScript: TMenuItem;
85 actCopyAllNoReturn: TAction;
86 mnCopyAllNoReturn: TMenuItem;
87 mnPopCopyAll: TMenuItem;
88 mnPopCopyAllNoReturn: TMenuItem;
90 tbtnSetting: TToolButton;
91 mnStayOnTop: TMenuItem;
93 actExitClient: TAction;
95 tbtnEditConst: TToolButton;
96 actClearBottles: TAction;
97 mnClearBottles: TMenuItem;
98 MediaPlayer: TMediaPlayer;
99 mnGetNewId: TMenuItem;
100 actNextChannel: TAction;
101 actPrevChannel: TAction;
103 mnNextChannel: TMenuItem;
104 mnPrevChannel: TMenuItem;
107 tbtnShowLog: TToolButton;
108 tbtnSleep: TToolButton;
112 mnTaskSleep: TMenuItem;
114 tabChannel: TTabControl;
115 memScript: TRichEdit;
118 cbxTargetGhost: TComboBox;
119 actVoteMessage: TAction;
120 mnPopUpChannelTab: TPopupMenu;
121 mnLeaveThisChannel: TMenuItem;
123 mnGotoVote: TMenuItem;
124 mnGotoGLog: TMenuItem;
125 mnGoToHelp: TMenuItem;
129 mnExitAllChannels: TMenuItem;
130 actAgreeMessage: TAction;
133 actPrevGhost: TAction;
134 actNextGhost: TAction;
135 mnPrevGhost: TMenuItem;
136 mnNextGhost: TMenuItem;
137 actResetGhost: TAction;
138 mnResetGhost: TMenuItem;
139 timDisconnectCheckTimer: TTimer;
140 DirectSstp: TDirectSstp;
141 XPManifest: TXPManifest;
142 actDownloadLog: TAction;
143 procedure actConfirmExecute(Sender: TObject);
144 procedure FormCreate(Sender: TObject);
145 procedure FormDestroy(Sender: TObject);
146 procedure actSendExecute(Sender: TObject);
147 procedure HTTPSuccess(Sender: TObject);
148 procedure HTTPFailure(Sender: TObject);
149 procedure actStartClick(Sender: TObject);
150 procedure actStopExecute(Sender: TObject);
151 procedure FormShow(Sender: TObject);
152 procedure mnAboutClick(Sender: TObject);
153 procedure actExitClientExecute(Sender: TObject);
154 procedure actClearExecute(Sender: TObject);
155 procedure memScriptChange(Sender: TObject);
156 procedure mnStayOnTopClick(Sender: TObject);
157 procedure mnColorScriptClick(Sender: TObject);
158 procedure actEditConstExecute(Sender: TObject);
159 procedure mnTaskBarClick(Sender: TObject);
160 procedure FormClose(Sender: TObject; var Action: TCloseAction);
161 procedure ApplicationEventsMinimize(Sender: TObject);
162 procedure ApplicationEventsRestore(Sender: TObject);
163 procedure mnTaskRestoreClick(Sender: TObject);
164 procedure TaskTrayDblClick(Seft: TObject; Button: TMouseButton);
165 procedure FormActivate(Sender: TObject);
166 procedure mnTaskNewMessageClick(Sender: TObject);
167 procedure ApplicationEventsHint(Sender: TObject);
168 procedure memScriptKeyDown(Sender: TObject; var Key: Word;
170 procedure mnShowToolBarClick(Sender: TObject);
171 procedure mnShowConstBarClick(Sender: TObject);
172 procedure ApplicationEventsIdle(Sender: TObject; var Done: Boolean);
173 procedure mnGoToHPClick(Sender: TObject);
174 procedure LabelTimerTimer(Sender: TObject);
175 procedure actCopyAllExecute(Sender: TObject);
176 procedure actCopyAllNoReturnExecute(Sender: TObject);
177 procedure Slpp20SlppEvent(Sender: TObject; EventType: TIdSlppEventType;
178 const Param: String);
179 procedure DirectSstpResendCountChange(Sender: TObject);
180 procedure actSettingExecute(Sender: TObject);
181 procedure memScriptKeyPress(Sender: TObject; var Key: Char);
182 procedure Slpp20Disconnect(Sender: TObject);
183 procedure actClearBottlesExecute(Sender: TObject);
184 procedure SakuraSeekerDetectResultChanged(Sender: TObject);
185 procedure mnGetNewIdClick(Sender: TObject);
186 procedure tabChannelChange(Sender: TObject);
187 procedure actPrevChannelExecute(Sender: TObject);
188 procedure actNextChannelExecute(Sender: TObject);
189 procedure cbxTargetGhostDropDown(Sender: TObject);
190 procedure DirectSstpResendTrying(Sender: TObject; ID: Integer;
191 const Script: String);
192 procedure DirectSstpResendEnd(Sender: TObject; ID: Integer;
193 const Script: String);
194 procedure actShowLogExecute(Sender: TObject);
195 procedure Slpp20Connect(Sender: TObject);
196 procedure actSleepExecute(Sender: TObject);
197 procedure tabChannelDrawTab(Control: TCustomTabControl;
198 TabIndex: Integer; const Rect: TRect; Active: Boolean);
199 procedure actVoteMessageExecute(Sender: TObject);
200 procedure tabChannelContextPopup(Sender: TObject; MousePos: TPoint;
201 var Handled: Boolean);
202 procedure mnLeaveThisChannelClick(Sender: TObject);
203 procedure mnGotoVoteClick(Sender: TObject);
204 procedure mnGotoGLogClick(Sender: TObject);
205 procedure tabChannelMouseMove(Sender: TObject; Shift: TShiftState; X,
207 procedure mnGoToHelpClick(Sender: TObject);
208 procedure tabChannelMouseDown(Sender: TObject; Button: TMouseButton;
209 Shift: TShiftState; X, Y: Integer);
210 procedure tabChannelDragOver(Sender, Source: TObject; X, Y: Integer;
211 State: TDragState; var Accept: Boolean);
212 procedure tabChannelDragDrop(Sender, Source: TObject; X, Y: Integer);
213 procedure tabChannelEndDrag(Sender, Target: TObject; X, Y: Integer);
214 procedure cbxTargetGhostDrawItem(Control: TWinControl; Index: Integer;
215 Rect: TRect; State: TOwnerDrawState);
216 procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
217 procedure actAgreeMessageExecute(Sender: TObject);
218 procedure actPrevGhostExecute(Sender: TObject);
219 procedure actNextGhostExecute(Sender: TObject);
220 procedure actResetGhostExecute(Sender: TObject);
221 procedure timDisconnectCheckTimerTimer(Sender: TObject);
222 procedure actDownloadLogExecute(Sender: TObject);
223 procedure cbxTargetGhostChange(Sender: TObject);
227 FConnecting: boolean;
229 FBooted: boolean; //
\8f\89\89ñ
\8bN
\93®
\92Ê
\90M
\97p
230 FOriginalCaption: String;
231 FAutoAddAfterGetChannel: boolean;
233 //
\83X
\83N
\83\8a\83v
\83g
\90F
\95ª
\82¯
\97p
\82Ì
\95Ï
\90\94
234 FRequireColoring: boolean;
235 FUnyuTalking: boolean;
236 FInSynchronized: boolean;
237 FLastSurfaceH: integer;
238 FLastSurfaceU: integer;
239 FColoringPos: integer; //
\90F
\95ª
\82¯
\8dÏ
\82Ý
\82Ì
\83X
\83N
\83\8a\83v
\83g
\82Ì
\83o
\83C
\83g
\90\94
240 FColoredElements: integer; //
\90F
\95ª
\82¯
\8dÏ
\82Ý
\82Ì
\83G
\83\8c\83\81\83\93\83g
\82Ì
\90\94
241 FcolorTimeLag: Int64; //
\95Ï
\8a·
\8aJ
\8en
\82Ü
\82Å
\82Ì
\83J
\83E
\83\93\83^
243 FMutex: THandle; //Mutex
\83I
\83u
\83W
\83F
\83N
\83g
\81c
\93ñ
\8fd
\8bN
\93®
\96h
\8e~
\97p
245 FNowChannel: String; //
\8c»
\8dÝ
\91I
\91ð
\82³
\82ê
\82Ä
\82¢
\82é
\83`
\83\83\83\93\83l
\83\8b
246 JoinChannelsBackup: TStringList; //
248 FDragTabIndex: integer; //
\83^
\83u
\83h
\83\89\83b
\83O
\83h
\83\8d\83b
\83v
\8aÖ
\98A
249 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)
251 FCueGhost: TID2Ghost;
253 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Ý)
254 FBeginConnectFailCount: integer; //
\89½
\93x
\82à
\90Ú
\91±
\8e¸
\94s
\82µ
\82½
\82ç
\83\8a\83g
\83\89\83C
\92\86\8e~
255 procedure SetStatusText(const Value: String);
256 procedure SetSleeping(const Value: boolean);
257 function T2C: TColor;
258 procedure ColorAgain;
260 procedure SetConnecting(const Value: boolean);
261 procedure SetAdded(const Value: boolean);
262 procedure mnConstClick(Sender: TObject);
263 property Added: boolean read FAdded write SetAdded;
264 property Sleeping: boolean read FSleeping write SetSleeping;
265 property StatusText: String read FStatusText write SetStatusText;
266 function GetScriptText: String;
267 procedure ChangeTaskIcon;
268 procedure ShowHintLabel(const Mes: String; Col: TColor = clBlue);
269 procedure UpdateLayout;
270 procedure ScriptColorChange(From, Length: integer; Col: TColor);
271 procedure DispatchBottle(EventType: TIdSlppEventType; Dat: THeadValue);
272 //
\83`
\83\83\83\93\83l
\83\8b\8aÖ
\8cW
273 procedure UpdateChannelInfo(Dat: THeadValue);
274 procedure UpdateJoinChannelList(Dat: THeadValue);
275 procedure NoLuidError;
276 procedure UpdateIfGhostBox;
277 function BuildMenuConditionCheck(const IfGhost, Ghost: String): boolean;
278 procedure BuildMenu(Root: TMenuItem; Event: TNotifyEvent; Simple: boolean);
279 procedure PlaySound(const FileName: String);
281 function DoTrans(var Script: String;
282 Options: TScriptTransOptions): String;
283 procedure BeginConnect;
284 procedure RetryBeginConnect;
285 procedure EndConnect;
286 procedure ConstructMenu(Simple: boolean);
287 property Connecting: boolean read FConnecting write SetConnecting;
288 function SetHWndToFavoriteGhost(const Ghost: String): String;
289 function GhostNameToSetName(const Ghost: String): String;
290 procedure PostCommand(const Command: array of String); overload;
291 procedure PostCommand(Command: TStrings); overload;
292 procedure PostSetChannel(Channels: TStrings);
297 frmSender: TfrmSender;
300 PanelConnecting = 0; //
\81u
\90Ú
\91±
\92\86\81v
\95\
\8e¦
\97p
301 PanelBytes = 1; //
\81\9b\81\9b\83o
\83C
\83g
302 PanelCount = 2; //Local Proxy
\81A
\8c»
\8dÝ
\81\9b\8c\8f\91Ò
\82¿
304 PanelStatus = 4; //
\93o
\98^
\82³
\82ê
\82Ä
\82¢
\82Ü
\82·
\81c
\82È
\82Ç
307 IconDisconnected = 18;
309 IconSleepDisconnected = 20;
311 WarningColor = clRed;
313 SendButtonLongHint = 'Bottle
\82Ì
\91\97\90M';
315 function Token(const Str: String; const Delimiter: char;
316 const Index: integer): String;
320 uses SendConfirm, SettingForm, ChannelListForm, LogForm,
325 //
\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
326 function Token(const Str: String; const Delimiter: char;
327 const Index: integer): String;
328 var i, c, len: integer;
334 while i <= len do begin
335 if (Str[i] = Delimiter) and (StrByteType(PChar(Str), i) <> mbTrailByte) then begin
337 if c > Index then Break;
338 end else if c = Index then Result := Result + Str[i];
345 procedure TfrmSender.actConfirmExecute(Sender: TObject);
346 var Res: TSstpResult;
347 Script, Ghost, Err: String;
348 Opt: TScriptTransOptions;
350 if Length(GetScriptText) = 0 then Exit;
352 Script := GetScriptText;
353 if Pref.IgnoreTimeCritical then Opt := [toIgnoreTimeCritical] else Opt := [];
354 if Pref.NoTransUrl then Opt := Opt + [toNoChoice];
355 Err := DoTrans(Script, Opt + [toConvertURL, toWarnMessySurface]);
356 if Err <> '' then begin
360 if cbxTargetGhost.ItemIndex > 0 then begin
361 Ghost := cbxTargetGhost.Text
363 if FNowChannel <> '' then
364 Ghost := ChannelList.Channel[FNowChannel].Ghost;
366 Ghost := SetHWndToFavoriteGhost(Ghost);
367 DirectSstp.SstpSender := 'SSTP Bottle -
\81y
\8am
\94F
\81z';
369 Res := DirectSstp.SstpSEND(Script, [soNoTranslate], GhostNameToSetName(Ghost));
370 if Res <> srOk then begin
371 ShowHintLabel('
\91\97\90M
\8e¸
\94s:' + DirectSstp.RecvLog, WarningColor);
372 end else ShowHintLabel('');
375 procedure TfrmSender.FormCreate(Sender: TObject);
376 var Str: TStringList;
378 SakuraSeeker.OnDetectResultChanged := SakuraSeekerDetectResultChanged;
379 FConstDir := ExtractFileDir(Application.ExeName)+'\consts';
380 ScriptConstList.LoadFromDir(FConstDir);
381 ConstructMenu(false);
383 Str := TStringList.Create;
386 Str.LoadFromFile(ExtractFilePath(Application.ExeName)+'rule.txt');
387 BottleChainRuleList := StringToComponent(Str.Text) as TBottleChainRuleList;
390 Str.LoadFromFile(ExtractFilePath(Application.ExeName)+'defrule.txt');
391 BottleChainRuleList := StringToComponent(Str.Text) as TBottleChainRuleList;
393 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');
394 Application.Terminate;
395 Application.ProcessMessages;
403 FOriginalCaption := Self.Caption;
406 FMutex := OpenMutex(MUTEX_ALL_ACCESS, false, 'SSTPBottleClient2');
407 if FMutex <> 0 then begin
409 ShowMessage('SSTP Bottle Client
\82Í
\93ñ
\8fd
\8bN
\93®
\82Å
\82«
\82Ü
\82¹
\82ñ');
411 Application.Terminate;
412 Application.ProcessMessages; //WM_QUIT
\82ð
\97¬
\82·
415 FMutex := CreateMutex(nil, false, 'SSTPBottleClient2');
417 ShowMessage('
\93ñ
\8fd
\8bN
\93®
\8b\96\89Â
\83o
\81[
\83W
\83\87\83\93\82Å
\82·
\81B'#13#10 + VersionString);
421 mnShowToolBar.Checked := Pref.ShowToolBar;
422 mnShowConstBar.Checked := Pref.ShowConstBar;
423 if Pref.StayOnTop then begin
424 FormStyle := fsStayOnTop;
425 mnStayOnTop.Checked := true;
427 FormStyle := fsNormal;
428 mnStayOnTop.Checked := false;
430 mnColorScript.Checked := Pref.ColorScript;
432 mnGoToHP.Hint := Pref.HomePage;
433 mnGotoGlog.Hint := Pref.GLogPage;
434 mnGotoVote.Hint := Pref.VotePage;
435 mnGotoHelp.Hint := Pref.HelpPage;
437 mnGetNewId.Enabled := (Pref.LUID = '');
440 SsParser.TagPattern.LoadFromFile(ExtractFilePath(Application.Exename) + 'tagpat.txt');
441 SsParser.MetaPattern.LoadFromFile(ExtractFilePath(Application.ExeName) + 'metapat.txt');
443 ShowMessage('tagpat.txt, metapat.txt
\82ª
\8c©
\82Â
\82©
\82è
\82Ü
\82¹
\82ñ
\81B');
444 Application.Terminate;
447 with Pref.SenderWindowPosition do begin
450 Self.Width := Right - Left + 1;
451 Self.Height := Bottom - Top + 1;
454 //
\83`
\83\83\83\93\83l
\83\8b\83\8a\83X
\83g
455 FCueGhost := TID2Ghost.Create;
457 actClearExecute(Sender);
458 ApplicationEvents.OnIdle := ApplicationEventsIdle;
460 UpdateJoinChannelList(nil);
463 procedure TfrmSender.FormDestroy(Sender: TObject);
464 var Str: TStringList;
466 with Pref.SenderWindowPosition do begin
469 Right := Self.Left + Self.Width - 1;
470 Bottom := Self.Top + Self.Height - 1;
473 if JoinChannelsBackup <> nil then JoinChannelsBackup.Free;
474 if FCueGhost <> nil then FCueGhost.Free;
476 ScriptConstList.Save;
478 Str := TStringList.Create;
480 Str.Text := ComponentToString(BottleChainRuleList);
481 Str.SaveToFile(ExtractFileDir(Application.ExeName)+'\rule.txt');
485 BottleChainRuleList.Free;
488 ReleaseMutex(FMutex);
493 procedure TfrmSender.SetConnecting(const Value: boolean);
495 FConnecting := Value;
497 StatusBar.Panels[PanelConnecting].Text := '
\92Ê
\90M
\92\86';
498 actStart.Enabled := false;
499 actStop.Enabled := false;
500 actSend.Enabled := false;
501 actVoteMessage.Enabled := false;
502 actAgreeMessage.Enabled := false;
503 mnGetNewId.Enabled := false;
504 Screen.Cursor := crAppStart;
506 StatusBar.Panels[PanelConnecting].Text := '';
507 actStart.Enabled := true;
508 actStop.Enabled := true;
509 actSend.Enabled := true;
510 //actVoteMessage.Enabled := true;
511 //actAgreeMessage.Enabled := true;
512 frmLog.lvwLogChange(Self, nil, ctState);
513 mnGetNewId.Enabled := Pref.LUID = '';
514 Screen.Cursor := crDefault;
518 procedure TfrmSender.actSendExecute(Sender: TObject);
519 var Talk, Ghost: String;
520 Command: TStringList;
524 if Length(GetScriptText) = 0 then begin
525 ShowMessage('
\83X
\83N
\83\8a\83v
\83g
\82ª
\8bó
\82Å
\82·
\81B');
529 if Pref.LUID = '' then begin
533 if tabChannel.TabIndex < 0 then begin
534 ShowMessage('
\83`
\83\83\83\93\83l
\83\8b\82É
\8eQ
\89Á
\82µ
\82Ä
\82¢
\82Ü
\82¹
\82ñ
\81B'#13#10+
535 '
\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');
538 if ChannelList.Channel[FNowChannel].NoPost then begin
540 ShowMessage(FNowChannel + '
\82Í
\8eó
\90M
\90ê
\97p
\82Å
\82·');
543 if not Pref.NoConfirm then begin
544 if not SendConfirmDialog(FNowChannel, cbxTargetGhost.Text) then Exit;
548 Talk := GetScriptText;
549 Err := DoTrans(Talk, [toWarnMessySurface]);
550 if Err <> '' then begin
551 MessageDlg(Err, mtWarning, [mbOk], 0);
556 if cbxTargetGhost.ItemIndex > 0 then Ghost := cbxTargetGhost.Text;
558 Command := TStringList.Create;
559 with Command do begin
560 Add('Command: sendBroadcast');
561 Add('Channel: ' + FNowChannel);
562 Add('LUID: ' + Pref.LUID);
563 Add('Agent: ' + VersionString);
564 if Ghost <> '' then Add('Ghost: ' + Ghost);
565 Add('Talk: ' + Talk);
567 PostCommand(Command);
572 //
\91\97\90M
\83\8d\83O
\95Û
\91¶
573 AssignFile(F, ExtractFilePath(Application.ExeName) + SentLogFile);
574 if FileExists(ExtractFilePath(Application.ExeName) + SentLogFile) then
578 WriteLn(F, Format('%s,%s,%s,%s', [FNowChannel, Ghost, FormatDateTime('yy/mm/dd hh:nn:ss', Now), Talk]));
583 procedure TfrmSender.BeginConnect;
585 if Pref.LUID = '' then begin
589 IdSlpp20.LUID := Pref.LUID;
590 self.Cursor := crHourGlass;
592 if IdSlpp20.Connected then IdSlpp20.Disconnect;
593 if Pref.UseHttpProxy then begin
594 IdSlpp20.Host := Pref.ProxyAddress;
595 IdSlpp20.Port := Pref.ProxyPort;
596 IdSlpp20.ProxyMode := true;
598 IdSlpp20.Host := 'bottle.mikage.to';
599 IdSlpp20.Port := 9871;
600 IdSlpp20.ProxyMode := false;
604 on EIdException do begin
606 if FBeginConnectFailCount = 0 then begin
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: 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 if SsParser[i] = '\h' then begin
1159 UnyuTalking := false;
1160 if QuickSection then begin
1161 //Result := '
\83N
\83C
\83b
\83N
\83Z
\83N
\83V
\83\87\83\93\92\86\82É"\h", "\u"
\82Í
\8eg
\82¦
\82Ü
\82¹
\82ñ
\81B';
1164 end else if SsParser[i] = '\u' then begin
1165 UnyuTalking := true;
1166 if QuickSection then begin
1167 //Result := '
\83N
\83C
\83b
\83N
\83Z
\83N
\83V
\83\87\83\93\92\86\82É"\h", "\u"
\82Í
\8eg
\82¦
\82Ü
\82¹
\82ñ
\81B';
1170 end else if SsParser[i] = '\_q' then begin
1171 QuickSection := not QuickSection;
1172 end else if SsParser.Match(SsParser[i], '\s%b') > 0 then begin
1173 if UnyuTalking then begin
1174 LastSurfaceU := StrToIntDef(SsParser.GetParam(SsParser[i], 1),
1177 LastSurfaceH := StrToIntDef(SsParser.GetParam(SsParser[i], 1),
1180 end else if SsParser.Match(SsParser[i], '\s%d') > 0 then begin
1181 if UnyuTalking then begin
1182 LastSurfaceU := StrToIntDef(SsParser[i][3], LastSurfaceU);
1184 LastSurfaceH := StrToIntDef(SsParser[i][3], LastSurfaceH);
1187 Script := Script + SsParser[i];
1190 if UrlCount > 0 then begin
1191 Script := Script + '\h\n';
1192 if not (toNoChoice in Options) then begin
1193 for i := 0 to UrlCount-1 do begin
1194 Script := Script + Format('\q%d[%s][%s]',
1195 [i, SsParser.EscapeParam(Url[i]), UrlName[i]]);
1197 Script := Script + Format('\q%d[#cancel][%s]', [UrlCount, UrlCancel]);
1198 //Script := Script + '\z'; //
\8dÅ
\90Vphase
\82Å
\82Í
\8dí
\8f\9c
1200 Script := Script + '\h';
1201 for i := 0 to UrlCount-1 do begin
1202 Script := Script + Format('\n{%s}(%s)', [UrlName[i], Url[i]]);
1203 Script := Script + Format('\n{%s}', [UrlCancel]);
1207 //
\83X
\83N
\83\8a\83v
\83g
\82Ì
\8dÅ
\8cã
\82É
\83E
\83F
\83C
\83g
\91}
\93ü
1208 if toWaitScriptEnd in Options then begin
1209 i := Pref.WaitScriptEnd;
1210 while i > 0 do begin
1212 Script := Script + '\w9';
1215 Script := Script + '\w' + IntToStr(i);
1221 Script := Script + '\e';
1222 RegExp.Subst('s/\r\n//gk', Script);
1224 //
\83^
\83O
\83`
\83F
\83b
\83N
\8aÖ
\98A
1225 for i := 0 to SsParser.Count-1 do begin
1226 if SsParser.MarkUpType[i] = mtTagErr then begin
1227 Result := '"' + SsParser[i] + '"'#13#10 +
1228 '
\82Í
\81ASSTP Bottle
\82Å
\94F
\82ß
\82ç
\82ê
\82È
\82¢
\82©
\81A
\94F
\8e¯
\82Å
\82«
\82È
\82¢
\83^
\83O
\82Å
\82·
\81B';
1232 SsParser.InputString := Orig;
1235 procedure TfrmSender.mnGoToHPClick(Sender: TObject);
1237 ShellExecute(Handle, 'open', PChar(Pref.HomePage), nil, nil, SW_SHOW);
1240 procedure TfrmSender.ShowHintLabel(const Mes: String; Col: TColor);
1242 lblMessage.Caption := Mes;
1243 lblMessage.Font.Color := Col;
1244 lblMessage.Visible := true;
1245 LabelTimer.Enabled := false;
1246 LabelTimer.Enabled := true;
1249 procedure TfrmSender.LabelTimerTimer(Sender: TObject);
1251 LabelTimer.Enabled := false;
1252 lblmessage.Visible := false;
1255 procedure TfrmSender.ScriptColorChange(From, Length: integer; Col: TColor);
1256 //var Fmt: TCharFormat;
1258 memScript.SelStart := From;
1259 memScript.SelLength := Length;
1260 memScript.SelAttributes.Color := Col;
1263 procedure TfrmSender.actCopyAllExecute(Sender: TObject);
1267 Str := memScript.Text;
1268 Clip := ClipBoard();
1269 Clip.SetTextBuf(PChar(Str));
1272 procedure TfrmSender.actCopyAllNoReturnExecute(Sender: TObject);
1276 Str := memScript.Text;
1277 RegExp.Subst('s/\r\n//gk', Str);
1278 Clip := ClipBoard();
1279 Clip.SetTextBuf(PChar(Str));
1282 procedure TfrmSender.Slpp20SlppEvent(Sender: TObject; EventType: TIdSlppEventType;
1283 const Param: String);
1284 var HeadValue: THeadValue;
1288 HeadValue := THeadValue.Create(Param);
1290 etScript, etForceBroadcast, etUnicast: begin
1291 //
\83\81\83b
\83Z
\81[
\83W
\8eó
\90M
1292 HeadValue := THeadValue.Create(Param);
1293 DispatchBottle(EventType, HeadValue);
1295 etMemberCount: begin
1296 StatusBar.Panels[PanelMembers].Text := HeadValue['Num'] + '
\90l'
1298 etChannelCount: begin
1300 ChannelList.Channel[HeadValue['Channel']].Members := StrToInt(HeadValue['Num']);
1305 ShowHintLabel('SSTP Bottle
\83T
\81[
\83o
\82Æ
\92Ê
\90M
\8am
\97§
\81B');
1306 FBeginConnectFailCount := 0;
1307 //
\83`
\83\83\83\93\83l
\83\8b\8e©
\93®
\93o
\98^
1308 if not Connecting then
1309 PostCommand(['Command: getChannels']);
1311 etChannelList: begin
1312 UpdateJoinChannelList(HeadValue);
1313 //
\8dÅ
\8cã
\82É
\8eQ
\89Á
\82µ
\82Ä
\82¢
\82½
\83`
\83\83\83\93\83l
\83\8b\82ð
\8bL
\98^
\82·
\82é
1314 if JoinChannelsBackup = nil then JoinChannelsBackup := TStringList.Create;
1315 JoinChannelsBackup.Assign(JoinChannels);
1317 etCloseChannel: begin
1318 with JoinChannels do
1319 if IndexOf(HeadValue['Channel']) >= 0 then
1320 Delete(IndexOf(HeadValue['Channel']));
1321 with tabChannel do begin
1322 if Tabs.IndexOf(HeadValue['Channel']) >= 0 then
1323 Tabs.Delete(Tabs.IndexOf(HeadValue['Channel']));
1324 if Tabs.Count > 0 then TabIndex := 0 else TabIndex := -1;
1325 tabChannelChange(self);
1327 ShowHintLabel(HeadValue['Channel'] + '
\83`
\83\83\83\93\83l
\83\8b\82Í
\94p
\8e~
\82³
\82ê
\82Ü
\82µ
\82½',
1329 frmLog.AddCurrentSystemLog('SYSTEM', HeadValue['Channel'] + '
\83`
\83\83\83\93\83l
\83\8b\82Í
\94p
\8e~
\82³
\82ê
\82Ü
\82µ
\82½');
1330 frmMessageBox.ShowMessage(HeadValue['Channel'] + '
\83`
\83\83\83\93\83l
\83\8b\82Í
\94p
\8e~
\82³
\82ê
\82Ü
\82µ
\82½');
1332 etForceBroadcastInformation: begin
1333 if HeadValue['Type'] = 'Vote' then begin
1334 frmLog.VoteLog(HeadValue['MID'], StrToIntDef(HeadValue['Num'], 0));
1335 end else if HeadValue['Type'] = 'Agree' then begin
1336 frmLog.AgreeLog(HeadValue['MID'], StrToIntDef(HeadValue['Num'], 0));
1345 procedure TfrmSender.DirectSstpResendCountChange(Sender: TObject);
1347 StatusBar.Panels[PanelCount].Text := IntToStr(DirectSstp.CueCount) + '
\8c\8f';
1348 TaskTray.TipString := 'SSTP Bottle Client (' +
1349 IntToStr(DirectSstp.CueCount) + '
\8c\8f)';
1350 actClearBottles.Enabled := (DirectSstp.CueCount > 0);
1353 procedure TfrmSender.actSettingExecute(Sender: TObject);
1355 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;
1395 frmLog.AllBottleOpened;
1396 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 Err := DoTrans(Script, TransOpt);
1644 if Err <> '' then begin
1645 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'+
1646 '
\94z
\91\97\82³
\82ê
\82Ü
\82¹
\82ñ
\82Å
\82µ
\82½
\81@
\81c '+Dat['Script']);
1651 NoDispatch := false;
1653 LogNameList := TStringList.Create;
1656 for i := 0 to BottleChainRuleList.Count-1 do begin
1657 if SkipCount > 0 then begin
1661 Rule := BottleChainRuleList[i];
1662 if not Rule.Enabled then Continue;
1663 if not Rule.Check(Event) then Continue;
1664 for j := 0 to Rule.Actions.Count-1 do begin
1665 Action := (Rule.Actions[j] as TBottleChainAction);
1666 if Action is TBottleChainAbortRuleAction then BreakFlag := true;
1667 if Action is TBottleChainSkipRuleAction then
1668 SkipCount := (Action as TBottleChainSkipRuleAction).SkipCount;
1669 if (Action is TBottleChainSoundAction) and (Sound = '') then
1670 Sound := (Action as TBottleChainSoundAction).SoundFile;
1671 if Action is TBottleChainNoDispatchAction then NoDispatch := true;
1672 if Action is TBottleChainLogAction then begin
1673 for k := 0 to (Action as TBottleChainLogAction).LogNames.Count-1 do begin
1674 LogName := (Action as TBottleChainLogAction).LogNames[k];
1675 LogName := StringReplace(LogName, '%channel%', Dat['Channel'], [rfReplaceAll]);
1676 LogName := StringReplace(LogName, '%ghost%', Dat['TargetGhost'], [rfReplaceAll]);
1677 LogName := StringReplace(LogName, '%date%', FormatDateTime('yy/mm/dd', Now()), [rfReplaceAll]);
1678 LogNameList.Add(LogName);
1681 if Action is TBottleChainOverrideGhostAction then begin
1682 Dat['TargetGhost'] := (Action as TBottleChainOverrideGhostAction).TargetGhost;
1684 if Action is TBottleChainQuitAction then Application.Terminate;
1686 if BreakFlag then Break;
1689 if Dat['Script'] <> '' then begin
1690 for i := 0 to LogNameList.Count-1 do
1691 frmLog.AddCurrentScriptLog(LogNameList[i], Dat['Script'], Sender, Dat['MID'], Dat['IfGhost']);
1692 if NoDispatch then begin
1693 frmLog.SetBottleStatusToOpened(Dat['MID']);
1695 Ghost := Dat['TargetGhost']; //
\83I
\81[
\83o
\81[
\83\89\83C
\83h
\82³
\82ê
\82Ä
\82¢
\82é
\89Â
\94\
\90«
\82ª
\82 \82é
1696 CueID := DirectSstp.SstpSENDCue(Script, false, Opt, GhostNameToSetName(Ghost));
1697 if Dat['IfGhost'] <> '' then Sender := Sender + '/' + Ghost; // Dat['IfGhost'];
1698 FCueGhost.AddIdGhost(CueID, Ghost, Sender, Dat['MID']);
1702 if Dat['DialogMessage'] <> '' then begin
1704 frmMessageBox.ShowMessage(
1705 DateTimeToStr(Now) + #13#10 +
1706 'SSTP Bottle
\83T
\81[
\83o
\82©
\82ç
\82¨
\92m
\82ç
\82¹'#13#10+Dat['DialogMessage']);
1707 for i := 0 to LogNameList.Count-1 do
1708 frmLog.AddCurrentSystemLog(LogNameList[i], Dat['DialogMessage']);
1712 if (Sound <> '') then PlaySound(Sound);
1718 function TfrmSender.SetHWndToFavoriteGhost(const Ghost: String): String;
1720 //DirectSstp.TargetHWnd
\82ð
\81A
\90\84\8f§
\82·
\82é
\83S
\81[
\83X
\83g
\82É
\90Ý
\92è
\82·
\82é
\81B
1721 //
\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
1722 SakuraSeeker.BeginDetect; //
\8dÅ
\90V
\82ÌFMO
\8eæ
\93¾
1723 if SakuraSeeker.ProcessByName[Ghost] <> nil then begin
1724 DirectSstp.TargetHWnd := SakuraSeeker.ProcessByName[Ghost].HWnd;
1726 end else if SakuraSeeker.Count > 0 then begin
1727 DirectSstp.TargetHWnd := SakuraSeeker[0].HWnd;
1728 Result := SakuraSeeker[0].Name;
1730 DirectSstp.TargetHwnd := 0;
1735 procedure TfrmSender.YenETrans;
1736 var St, Le, i: integer;
1739 St := memScript.SelStart;
1740 Le := memScript.SelLength;
1741 Orig := GetScriptText;
1742 RegExp.Subst('s/(\r\n)+$//kg', Orig);
1744 if SsParser.InputString <> Orig then begin
1745 //
\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é
1746 SsParser.InputString := Orig
1748 for i := 0 to SsParser.Count-1 do begin
1749 if SsParser[i] <> '\e' then Text := Text + SsParser[i];
1752 Text := Text + '\e';
1754 if Orig <> Text then memScript.Lines.Text := Text;
1755 SsParser.InputString := Text;
1757 RegExp.Subst('s/\r\n//kg', Text);
1759 memScript.SelStart := St;
1760 memScript.SelLength := Le;
1763 procedure TfrmSender.PostCommand(const Command: array of String);
1764 var PostStr: TStringList;
1769 PostStr := TStringList.Create;
1770 for i := Low(Command) to High(Command) do begin
1771 PostStr.Add(Command[i]);
1773 PostCommand(PostStr);
1779 procedure TfrmSender.PostCommand(Command: TStrings);
1780 var PostStr: String;
1783 PostStr := Command.Text;
1784 PostStr := TIdURI.ParamsEncode(PostStr);
1786 FHttp := THTTPDownloadThread.Create(BottleServer, Pref.CgiName, PostStr);
1787 if Pref.UseHttpProxy then begin
1788 FHttp.ProxyServer := Pref.ProxyAddress;
1789 FHttp.ProxyPort := Pref.ProxyPort;
1791 FHttp.OnSuccess := HttpSuccess;
1792 FHttp.OnConnectionFailed := HttpFailure;
1793 FHttp.FreeOnTerminate := true; //
\8f\9f\8eè
\82É
\8e©
\95ª
\82ÅFree
\82µ
\82Ä
\82
\82¾
\82³
\82¢
1796 on EHeapException do begin
1797 Connecting := false;
1803 procedure TfrmSender.tabChannelDrawTab(Control: TCustomTabControl;
1804 TabIndex: Integer; const Rect: TRect; Active: Boolean);
1807 with tabChannel.Canvas do begin
1809 if Active then begin
1810 Font.Color := clBlue;
1812 Font.Style := Font.Style - [fsBold];
1813 Font.Color := clWindowText;
1815 X := (Rect.Left + Rect.Right) div 2;
1816 X := X - TextWidth(tabChannel.Tabs[TabIndex]) div 2;
1817 if tabChannel.TabPosition = tpTop then
1820 Y := Rect.Bottom - 15;
1821 TextOut(X, Y, tabChannel.Tabs[TabIndex]);
1825 procedure TfrmSender.actVoteMessageExecute(Sender: TObject);
1828 if frmLog.lvwLog.Selected = nil then Exit;
1829 Log := frmLog.SelectedBottleLog[frmLog.lvwLog.Selected.Index] as TLogItem;
1830 if Log = nil then Exit;
1831 if Log.LogType <> ltBottle then Exit;
1833 'Command: voteMessage',
1835 'LUID: ' + Pref.LUID,
1841 procedure TfrmSender.actAgreeMessageExecute(Sender: TObject);
1844 if frmLog.lvwLog.Selected = nil then Exit;
1845 Log := frmLog.SelectedBottleLog[frmLog.lvwLog.Selected.Index] as TLogItem;
1846 if Log = nil then Exit;
1847 if Log.LogType <> ltBottle then Exit;
1849 'Command: voteMessage',
1851 'LUID: ' + Pref.LUID,
1857 function TfrmSender.GhostNameToSetName(const Ghost: String): String;
1859 if SakuraSeeker.ProcessByName[Ghost] <> nil then
1860 Result := SakuraSeeker.ProcessByName[Ghost].SetName
1865 procedure TfrmSender.tabChannelContextPopup(Sender: TObject;
1866 MousePos: TPoint; var Handled: Boolean);
1869 with tabChannel do begin
1870 Tag := IndexOfTabAt(MousePos.X, MousePos.Y);
1871 if Tag < 0 then Handled := true;
1876 procedure TfrmSender.PostSetChannel(Channels: TStrings);
1877 var PostStr: TStringList;
1882 PostStr := TStringList.Create;
1883 with PostStr do begin
1884 Add('Command: setChannels');
1885 Add('Agent: ' + VersionString);
1886 Add('LUID: ' + Pref.LUID);
1887 if Channels <> nil then
1888 for i := 0 to Channels.Count-1 do begin
1889 Add(Format('Ch%d: %s'#13#10, [i+1, Channels[i]]));
1892 PostCommand(PostStr);
1898 procedure TfrmSender.mnLeaveThisChannelClick(Sender: TObject);
1902 with tabChannel do Ch := Tabs[Tag];
1905 Chs := TStringList.Create;
1906 Chs.Assign(JoinChannels);
1907 while Chs.IndexOf(Ch) >= 0 do Chs.Delete(Chs.IndexOf(Ch));
1908 PostSetChannel(Chs);
1914 procedure TfrmSender.mnGotoVoteClick(Sender: TObject);
1916 ShellExecute(Handle, 'open', PChar(Pref.VotePage), nil, nil, SW_SHOW);
1919 procedure TfrmSender.mnGotoGLogClick(Sender: TObject);
1921 ShellExecute(Handle, 'open', PChar(Pref.GLogPage), nil, nil, SW_SHOW);
1924 procedure TfrmSender.tabChannelMouseMove(Sender: TObject;
1925 Shift: TShiftState; X, Y: Integer);
1929 with tabChannel do begin
1930 Index := IndexOfTabAt(X, Y);
1932 Hint := Ch + ': ' + IntToStr(ChannelList.Channel[Ch].Members) + '
\90l';
1936 procedure TfrmSender.mnGoToHelpClick(Sender: TObject);
1938 ShellExecute(Handle, 'open', PChar(Pref.HelpPage), nil, nil, SW_SHOW);
1941 procedure TfrmSender.tabChannelMouseDown(Sender: TObject;
1942 Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
1945 with tabChannel do begin
1946 Index := IndexOfTabAt(X, Y);
1947 if Index = -1 then Exit; //
\83^
\83u
\82ª
\82È
\82¢
\82Ì
\82Å
\83h
\83\89\83b
\83O
\82Å
\82«
\82È
\82¢
1948 if Button = mbLeft then begin
1949 FDragTabIndex := Index; //
\83h
\83\89\83b
\83O
\82·
\82é
\83^
\83u
\82Ì
\83C
\83\93\83f
\83b
\83N
\83X
\82ð
\95Û
\91¶
1951 FDragTabDest := -1; //
\83h
\83\89\83b
\83O
\98g
\90ü
\95`
\89æ
\83t
\83\89\83O
\83N
\83\8a\83A
\82Ì
\82½
\82ß
1956 procedure TfrmSender.tabChannelDragOver(Sender, Source: TObject; X,
1957 Y: Integer; State: TDragState; var Accept: Boolean);
1958 var TargetRect: TRect;
1961 Accept := Source = tabChannel;
1962 if not Accept then Exit;
1963 with tabChannel do begin
1964 OldDest := FDragTabDest;
1965 FDragTabDest := IndexOfTabAt(X, Y);
1966 if FDragTabDest = -1 then begin
1967 Accept := false; //
\82±
\82Ì
\8fê
\8d\87\82Í
\83h
\83\8d\83b
\83v
\82ð
\94F
\82ß
\82È
\82¢
1970 with Canvas do begin
1974 if (OldDest <> FDragTabDest) and (OldDest >= 0) then begin
1975 //
\88È
\91O
\82Ì
\98g
\90ü
\8fÁ
\8b\8e
1976 TargetRect := TabRect(OldDest);
1977 with Canvas do begin
1978 Brush.Style := bsClear;
1979 Rectangle(TargetRect.Left, TargetRect.Top,
1980 TargetRect.Right, TargetRect.Bottom);
1983 if (OldDest <> FDragTabDest) then begin
1984 //
\90V
\82µ
\82¢
\98g
\90ü
\95`
\89æ
1985 TargetRect := TabRect(FDragTabDest);
1986 with Canvas do begin
1987 Brush.Style := bsClear;
1988 Rectangle(TargetRect.Left, TargetRect.Top,
1989 TargetRect.Right, TargetRect.Bottom);
1995 procedure TfrmSender.tabChannelDragDrop(Sender, Source: TObject; X,
1997 var DestIndex: integer;
1999 with tabChannel do begin
2000 DestIndex := IndexOfTabAt(X, Y);
2001 Tabs.Move(FDragTabIndex, DestIndex);
2005 procedure TfrmSender.tabChannelEndDrag(Sender, Target: TObject; X,
2008 //
\8b
\90§
\93I
\82É
\83^
\83u
\82ð
\8dÄ
\95`
\89æ
\82³
\82¹
\82é
\81B
\98g
\90ü
\8fÁ
\82µ
\91Î
\8dô
2009 tabChannel.Tabs.BeginUpdate;
2010 tabChannel.Tabs.EndUpdate;
2013 procedure TfrmSender.cbxTargetGhostDrawItem(Control: TWinControl;
2014 Index: Integer; Rect: TRect; State: TOwnerDrawState);
2016 with cbxTargetGhost do begin
2017 if Index > 0 then begin
2018 if SakuraSeeker.ProcessByName[Items[Index]] = nil then
2019 Canvas.Font.Color := clRed
2021 Canvas.Font.Color := clBlue;
2022 Canvas.Font.Style := [fsBold];
2024 Canvas.Font.Color := clWindowText;
2025 Canvas.Font.Style := [];
2027 if odSelected in State then
2028 Canvas.Font.Color := clHighlightText;
2029 cbxTargetGhost.Canvas.TextRect(Rect, Rect.Left, Rect.Top,
2030 cbxTargetGhost.Items[Index]);
2034 procedure TfrmSender.FormCloseQuery(Sender: TObject;
2035 var CanClose: Boolean);
2037 if not Pref.ConfirmOnExit then Exit;
2038 if MessageDlg('SSTP Bottle Client
\82ð
\8fI
\97¹
\82µ
\82Ü
\82·', mtConfirmation,
2039 mbOkCancel, 0) = mrCancel then CanClose := false;
2042 procedure TfrmSender.UpdateIfGhostBox;
2047 cbxTargetGhost.DropDownCount := Pref.GhostDropDownCount;
2048 Selected := cbxTargetGhost.Text;
2049 with cbxTargetGhost do begin
2052 Items.Add('(CH
\90\84\8f§)');
2053 for i := 0 to SakuraSeeker.Count-1 do begin
2054 //
\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é
2055 if Length(SakuraSeeker[i].Name) = 0 then Continue;
2056 if cbxTargetGhost.Items.IndexOf(SakuraSeeker[i].Name) < 0 then
2057 cbxTargetGhost.Items.Add(SakuraSeeker[i].Name);
2060 cbxTargetGhost.ItemIndex := 0;
2061 if (Length(Selected) > 0) and (Selected <> '(CH
\90\84\8f§)') then begin
2062 with cbxTargetGhost do begin
2063 for i := 1 to Items.Count-1 do begin
2064 if Items[i] = Selected then
2067 //
\83S
\81[
\83X
\83g
\82ª
\93Ë
\91R
\91¶
\8dÝ
\82µ
\82È
\82
\82È
\82Á
\82½
\8fê
\8d\87\91Î
\8dô
2068 if ItemIndex = 0 then begin
2069 Items.Add(Selected);
2070 ItemIndex := Items.Count - 1;
2078 procedure TfrmSender.HTTPFailure(Sender: TObject);
2082 ShowHintLabel('SSTP Bottle
\83T
\81[
\83o
\82Æ
\82Ì
\90Ú
\91±
\82É
\8e¸
\94s
\82µ
\82Ü
\82µ
\82½', WarningColor);
2083 ShowMessage((Sender as THTTPDownloadThread).LastErrorMessage);
2084 Connecting := false;
2087 procedure TfrmSender.actPrevGhostExecute(Sender: TObject);
2090 SakuraSeeker.BeginDetect;
2092 i := cbxTargetGhost.ItemIndex;
2094 if i <= -1 then i := cbxTargetGhost.Items.Count-1;
2095 cbxTargetGhost.ItemIndex := i;
2096 cbxTargetGhostChange(self);
2099 procedure TfrmSender.actNextGhostExecute(Sender: TObject);
2102 SakuraSeeker.BeginDetect;
2104 i := cbxTargetGhost.ItemIndex;
2106 if i > cbxTargetGhost.Items.Count-1 then i := 0;
2107 cbxTargetGhost.ItemIndex := i;
2108 cbxTargetGhostChange(self);
2111 procedure TfrmSender.actResetGhostExecute(Sender: TObject);
2113 cbxTargetGhost.ItemIndex := 0; // (CH
\90\84\8f§)
\82É
\96ß
\82·
2114 if Visible then memScript.SetFocus;
2115 cbxTargetGhostChange(self);
2118 procedure TfrmSender.timDisconnectCheckTimerTimer(Sender: TObject);
2120 if (IdSlpp20.LastReadTimeInterval > BottleServerTimeOut) then begin
2122 frmLog.AddCurrentSystemLog('SYSTEM', 'SSTP Bottle
\83T
\81[
\83o
\82Æ
\82Ì
\90Ú
\91±
\82ª
\83^
\83C
\83\80\83A
\83E
\83g
\82µ
\82Ü
\82µ
\82½');
2123 if IdSlpp20.Connected then IdSlpp20.Disconnect;
2125 if not IdSlpp20.Connected then begin
2127 Slpp20Disconnect(self); //
\82È
\82º
\82©Disconnect
\83C
\83x
\83\93\83g
\82ª
\8bN
\82±
\82ç
\82¸
\82É
\90Ø
\92f
\82µ
\82½
\8fê
\8d\87
2129 //
\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
2130 //
\82½
\82¾
\82µ
\89ñ
\90\94\90§
\8cÀ
\82 \82è
2136 procedure TfrmSender.RetryBeginConnect;
2138 if FBeginConnectFailCount < 3 then begin
2139 //
\90Ø
\92f
\82³
\82ê
\82Ä
\82¢
\82ê
\82Î
\8dÄ
\90Ú
\91±
2140 FAutoAddAfterGetChannel := true;
2142 end else if FBeginConnectFailCount = 3 then begin
2143 frmLog.AddCurrentSystemLog('SYSTEM', '
\8dÄ
\90Ú
\91±
\8e©
\93®
\83\8a\83g
\83\89\83C
\82ð
\92\86\8e~
\82µ
\82Ü
\82·');
2144 frmMessageBox.ShowMessage(
2145 'SSTP Bottle
\83T
\81[
\83o
\82É
\90Ú
\91±
\82Å
\82«
\82Ü
\82¹
\82ñ
\81B'#13#10+
2146 '
\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+
2147 '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'
2149 Inc(FBeginConnectFailCount);
2153 procedure TfrmSender.actDownloadLogExecute(Sender: TObject);
2154 var BottleLog: TBottleLogList;
2156 Cond: TBottleLogDownloadCondition;
2158 function TimeStr(Mins: integer): String;
2159 var day, hour, min: integer;
2161 day := Mins div (60 * 24);
2162 hour := (Mins div 60) mod 24;
2165 if day > 0 then Result := Result + Format('%d
\93ú', [day]);
2166 if hour > 0 then Result := Result + Format('%d
\8e\9e\8aÔ', [hour]);
2167 if (min > 0) or (Result = '') then Result := Result + Format('%d
\95ª', [min]);
2170 Application.CreateForm(TfrmLogDownload, frmLogDownload);
2172 if frmLogDownload.Execute then begin
2173 with frmLogDownload do begin
2174 if IsRange then begin
2175 if CompareDate(DateLo, DateHi) = 0 then
2176 Title := FormatDateTime('yy/mm/dd', DateLo)
2178 Title := FormatDateTime('yy/mm/dd', DateLo) + ' - ' + FormatdateTime('yy/mm/dd', DateHi);
2180 Title := Format('
\89ß
\8b\8e%s', [TimeStr(RecentCount)]);
2182 if Channel <> '' then Title := Title + '(' + Channel + ')';
2185 BottleLog := TBottleLogList.Create(Title);
2186 BottleLog.OnLoaded := frmLog.LogLoaded;
2187 BottleLog.OnLoadFailure := frmLog.LogLoadFailure;
2188 BottleLog.OnLoadWork := frmLog.LogLoadWork;
2189 with frmLogDownload do begin
2190 Cond.IsRange := IsRange;
2191 Cond.RecentCount := RecentCount;
2192 Cond.DateLo := DateLo;
2193 Cond.DateHi := DateHi;
2194 Cond.MinVote := MinVote;
2195 Cond.MinAgree := MinAgree;
2196 Cond.Channel := Channel;
2198 BottleLog.LoadFromWeb(Cond);
2200 FreeAndNil(BottleLog);
2202 if BottleLog <> nil then begin
2203 NewIndex := frmLog.BottleLogList.Add(BottleLog);
2205 frmLog.tabBottleLog.TabIndex := NewIndex;
2206 frmLog.UpdateWindow;
2210 frmLogDownload.Release;
2214 function TfrmSender.BuildMenuConditionCheck(const IfGhost,
2215 Ghost: String): boolean;
2222 Cond := Token(IfGhost, ',', i);
2223 if Cond <> '' then begin
2224 if Cond[1] = '!' then begin
2225 Cond := Copy(Cond, 2, High(integer));
2226 if Cond = Ghost then Result := false;
2228 if Cond <> Ghost then Result := false;
2235 procedure TfrmSender.BuildMenu(Root: TMenuItem; Event: TNotifyEvent; Simple: boolean);
2236 var i, j, k, count: integer;
2237 ConstData: TScriptConst;
2238 Menu1, Menu2: TMenuItem;
2241 // Simple = false
\82Ì
\8fê
\8d\87\82Í
\83\81\83j
\83\85\81[
\82ð
\8a®
\91S
\82É
\8dÄ
\8d\
\92z
\82·
\82é
\81B
2242 // 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
2243 if cbxTargetGhost.ItemIndex > 0 then Ghost := cbxTargetGhost.Text
2244 else if FNowChannel <> '' then Ghost := ChannelList.Channel[FNowChannel].Ghost;
2246 //
\8aù
\91¶
\82Ì
\83\81\83j
\83\85\81[
\8dí
\8f\9c
2247 if Simple then begin
2248 // IfGhost
\8fð
\8c\8f\95t
\82«
\83\81\83j
\83\85\81[
\82Ì
\82Ý
\8dí
\8f\9c
2249 for i := Root.Count-1 downto 0 do begin
2250 if ScriptConstList.GetMenuByID(Root.Items[i].Tag).IfGhost <> '' then
2254 //
\91S
\95\94\8dí
\8f\9c
2255 for i := Root.Count-1 downto 0 do begin
2261 for i := 0 to ScriptConstList.Count-1 do begin
2262 for j := 0 to ScriptConstList[i].Count-1 do begin
2263 //
\83S
\81[
\83X
\83g
\88á
\82¢
\82Ì
\8fê
\8d\87\82Í
\83X
\83L
\83b
\83v
2264 if not BuildMenuConditionCheck(ScriptConstList[i][j].IfGhost, Ghost) then Continue;
2266 // 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
2267 if Simple and (count < Root.Count) then
2268 if (Root.Items[count].Tag = ScriptConstList[i][j].ID) then begin
2272 Menu1 := TMenuItem.Create(Root);
2273 Menu1.Caption := ScriptConstList[i][j].Caption;
2274 Menu1.Hint := ScriptConstList[i][j].Caption;
2275 Menu1.AutoHotkeys := maManual;
2276 Menu1.Tag := ScriptConstList[i][j].ID;
2278 if not Simple then begin
2281 if count < Root.Count-1 then
2282 Root.Insert(count, Menu1)
2287 Menu1.Enabled := ScriptConstList[i][j].Count > 0;
2288 for k := 0 to ScriptConstList[i][j].Count-1 do begin
2289 ConstData := ScriptConstList[i][j][k];
2290 Menu2 := TMenuItem.Create(Root);
2291 Menu2.Caption := ConstData.Caption;
2292 Menu2.Hint := ConstData.ConstText;
2293 if ConstData.ShortCut <> 0 then Menu2.Hint := Menu2.Hint
2294 + ' (' + ShortCutToText(ConstData.ShortCut) + ')';
2295 Menu2.ShortCut := ConstData.ShortCut;
2296 Menu2.OnClick := Event;
2297 Menu2.AutoHotkeys := maManual;
2298 Menu2.Tag := ConstData.ID;
2299 if (k mod 15 = 0) and (k > 0) then Menu2.Break := mbBarBreak;
2306 procedure TfrmSender.cbxTargetGhostChange(Sender: TObject);
2308 ConstructMenu(true);
2311 procedure TfrmSender.PlaySound(const FileName: String);
2313 if Pref.SilentWhenHidden and not Application.ShowMainForm then Exit;
2315 MediaPlayer.FileName := FileName;
2319 on E: EMCIDeviceError do begin
2320 ShowMessage('
\83T
\83E
\83\93\83h
\8dÄ
\90¶
\83G
\83\89\81[:'#13#10 + E.Message);