6 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
7 Menus, StdCtrls, ComCtrls, BRegExp, BottleDef, BottleSstp,
8 DirectSstp, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
9 IdSLPP20, SsParser, ImgList, AppEvnts, TaskTray, StdActns,
10 ActnList, MPlayer, MenuBar, ToolWin,
11 IniFiles, ExtCtrls, ShellAPI,
12 ConstEditor, Buttons, Clipbrd, HeadValue, Logs,
13 IdException, HttpThread, IdHTTP, IdURI, LogDownload,
14 ScriptConsts, DateUtils, BottleChainRule, BottleChainEvent,
15 SakuraSeekerInstance, HEditor, heClasses, heFountain,
16 SakuraScriptFountain, SppTypes, SppList, SurfacePreview;
19 TfrmSender = class(TForm)
23 mnRegister: TMenuItem;
26 StatusBar: TStatusBar;
29 mnEditConst: TMenuItem;
30 ActionList: TActionList;
32 mnPopPaste: TMenuItem;
35 mnPopSelectAll: TMenuItem;
37 mnPopConst: TMenuItem;
42 mnSelectAll: TMenuItem;
44 ApplicationEvents: TApplicationEvents;
45 mnPopUpTaskTray: TPopupMenu;
46 mnTaskStart: TMenuItem;
48 mnTaskRestore: TMenuItem;
49 mnTaskNewMessage: TMenuItem;
53 mnTaskExit: TMenuItem;
62 mnPopupConst: TPopupMenu;
63 actEditConst: TAction;
65 mnShowToolBar: TMenuItem;
66 mnShowConstBar: TMenuItem;
67 ConstBarMenu: TMainMenu;
69 tbtnClear: TToolButton;
70 tbtnConfirm: TToolButton;
71 tbtnSend: TToolButton;
72 tbtnSeparator: TToolButton;
73 tbtnStart: TToolButton;
74 tbtnSeparator2: TToolButton;
75 tbtnInsertConst: TToolButton;
76 ConstMenuBar: TMenuBar;
79 mnColorScript: TMenuItem;
82 actCopyAllNoReturn: TAction;
83 mnCopyAllNoReturn: TMenuItem;
84 mnPopCopyAll: TMenuItem;
85 mnPopCopyAllNoReturn: TMenuItem;
87 tbtnSetting: TToolButton;
88 mnStayOnTop: TMenuItem;
90 actExitClient: TAction;
92 tbtnEditConst: TToolButton;
93 actClearBottles: TAction;
94 mnClearBottles: TMenuItem;
95 MediaPlayer: TMediaPlayer;
96 mnGetNewId: TMenuItem;
97 actNextChannel: TAction;
98 actPrevChannel: TAction;
100 mnNextChannel: TMenuItem;
101 mnPrevChannel: TMenuItem;
104 tbtnShowLog: TToolButton;
105 tbtnSleep: TToolButton;
109 mnTaskSleep: TMenuItem;
111 tabChannel: TTabControl;
114 cbxTargetGhost: TComboBox;
115 actVoteMessage: TAction;
116 mnPopUpChannelTab: TPopupMenu;
117 mnLeaveThisChannel: TMenuItem;
119 mnGotoVote: TMenuItem;
120 mnGotoGLog: TMenuItem;
121 mnGoToHelp: TMenuItem;
125 mnExitAllChannels: TMenuItem;
126 actAgreeMessage: TAction;
129 actPrevGhost: TAction;
130 actNextGhost: TAction;
131 mnPrevGhost: TMenuItem;
132 mnNextGhost: TMenuItem;
133 actResetGhost: TAction;
134 mnResetGhost: TMenuItem;
135 timDisconnectCheckTimer: TTimer;
136 DirectSstp: TDirectSstp;
137 actDownloadLog: TAction;
138 actFMOExplorer: TAction;
139 tbtnFMOExplorer: TToolButton;
140 mnFMOExplorer: TMenuItem;
142 actInsertCue: TAction;
143 SakuraScriptFountain: TSakuraScriptFountain;
148 actSelectAll: TAction;
149 actEditCopy: TEditCopy;
150 procedure actConfirmExecute(Sender: TObject);
151 procedure FormCreate(Sender: TObject);
152 procedure FormDestroy(Sender: TObject);
153 procedure actSendExecute(Sender: TObject);
154 procedure HTTPSuccess(Sender: TObject);
155 procedure HTTPFailure(Sender: TObject);
156 procedure actStartClick(Sender: TObject);
157 procedure actStopExecute(Sender: TObject);
158 procedure FormShow(Sender: TObject);
159 procedure mnAboutClick(Sender: TObject);
160 procedure actExitClientExecute(Sender: TObject);
161 procedure actClearExecute(Sender: TObject);
162 procedure memScriptChange(Sender: TObject);
163 procedure mnStayOnTopClick(Sender: TObject);
164 procedure actEditConstExecute(Sender: TObject);
165 procedure mnTaskBarClick(Sender: TObject);
166 procedure FormClose(Sender: TObject; var Action: TCloseAction);
167 procedure ApplicationEventsMinimize(Sender: TObject);
168 procedure ApplicationEventsRestore(Sender: TObject);
169 procedure mnTaskRestoreClick(Sender: TObject);
170 procedure TaskTrayDblClick(Seft: TObject; Button: TMouseButton);
171 procedure FormActivate(Sender: TObject);
172 procedure mnTaskNewMessageClick(Sender: TObject);
173 procedure ApplicationEventsHint(Sender: TObject);
174 procedure memScriptKeyDown(Sender: TObject; var Key: Word;
176 procedure mnShowToolBarClick(Sender: TObject);
177 procedure mnShowConstBarClick(Sender: TObject);
178 procedure mnGoToHPClick(Sender: TObject);
179 procedure LabelTimerTimer(Sender: TObject);
180 procedure actCopyAllExecute(Sender: TObject);
181 procedure actCopyAllNoReturnExecute(Sender: TObject);
182 procedure Slpp20SlppEvent(Sender: TObject; EventType: TIdSlppEventType;
183 const Param: String);
184 procedure actSettingExecute(Sender: TObject);
185 procedure memScriptKeyPress(Sender: TObject; var Key: Char);
186 procedure Slpp20Disconnect(Sender: TObject);
187 procedure actClearBottlesExecute(Sender: TObject);
188 procedure SakuraSeekerDetectResultChanged(Sender: TObject);
189 procedure mnGetNewIdClick(Sender: TObject);
190 procedure tabChannelChange(Sender: TObject);
191 procedure actPrevChannelExecute(Sender: TObject);
192 procedure actNextChannelExecute(Sender: TObject);
193 procedure cbxTargetGhostDropDown(Sender: TObject);
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);
224 procedure actFMOExplorerExecute(Sender: TObject);
225 procedure actInsertCueExecute(Sender: TObject);
226 procedure FormResize(Sender: TObject);
227 procedure actCopyExecute(Sender: TObject);
228 procedure actPasteExecute(Sender: TObject);
229 procedure actCutExecute(Sender: TObject);
230 procedure actSelectAllExecute(Sender: TObject);
231 procedure memScriptMouseMove(Sender: TObject; Shift: TShiftState; X,
236 FConnecting: boolean;
238 FBooted: boolean; //
\8f\89\89ñ
\8bN
\93®
\92Ê
\90M
\97p
239 FOriginalCaption: String;
240 FAutoAddAfterGetChannel: boolean;
244 FMutex: THandle; //Mutex
\83I
\83u
\83W
\83F
\83N
\83g
\81c
\93ñ
\8fd
\8bN
\93®
\96h
\8e~
\97p
246 FNowChannel: String; //
\8c»
\8dÝ
\91I
\91ð
\82³
\82ê
\82Ä
\82¢
\82é
\83`
\83\83\83\93\83l
\83\8b
247 JoinChannelsBackup: TStringList; //
249 FScriptModified: boolean; //
\83X
\83N
\83\8a\83v
\83g
\82ª
\95Ï
\8dX
\82³
\82ê
\82Ä
\82¢
\82é
\82©
\82Ç
\82¤
\82©
\81B
250 //
\83\8d\81[
\83J
\83\8b\8am
\94F
\8b
\90§
\97p
\83t
\83\89\83O
\81B
251 // TRichEdit.Modified
\82Í
\95Ê
\82Ì
\97p
\93r
\82Å
\8eg
\82Á
\82Ä
\82¢
\82é
\82Ì
\82Å
\8eg
\82¦
\82È
\82¢
253 FDragTabIndex: integer; //
\83^
\83u
\83h
\83\89\83b
\83O
\83h
\83\8d\83b
\83v
\8aÖ
\98A
254 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)
256 FBottleSstp: TBottleSstp; //
\83X
\83\8c\83b
\83h
\94Å
\8dÄ
\91\97\83v
\83\8d\83O
\83\89\83\80
258 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Ý)
259 FBeginConnectFailCount: integer; //
\89½
\93x
\82à
\90Ú
\91±
\8e¸
\94s
\82µ
\82½
\82ç
\83\8a\83g
\83\89\83C
\92\86\8e~
261 FVisiblePreviewGhost: String;
262 FVisiblePreviewSurface: integer; //
\83T
\81[
\83t
\83B
\83X
\83v
\83\8c\83r
\83\85\81[
\82Å
\8c©
\82¦
\82Ä
\82¢
\82é
\82à
\82Ì
264 procedure SetStatusText(const Value: String);
265 procedure SetSleeping(const Value: boolean);
267 procedure SetConnecting(const Value: boolean);
268 procedure SetAdded(const Value: boolean);
269 procedure mnConstClick(Sender: TObject);
270 property Added: boolean read FAdded write SetAdded;
271 property Sleeping: boolean read FSleeping write SetSleeping;
272 property StatusText: String read FStatusText write SetStatusText;
273 function GetScriptText: String;
274 procedure ChangeTaskIcon;
275 procedure ShowHintLabel(const Mes: String; Col: TColor = clBlue);
276 procedure UpdateLayout;
277 procedure DispatchBottle(EventType: TIdSlppEventType; Dat: THeadValue);
278 //
\83`
\83\83\83\93\83l
\83\8b\8aÖ
\8cW
279 procedure UpdateChannelInfo(Dat: THeadValue);
280 procedure UpdateJoinChannelList(Dat: THeadValue);
281 procedure NoLuidError;
282 procedure UpdateIfGhostBox;
283 function BuildMenuConditionCheck(const IfGhost, Ghost: String): boolean;
284 procedure BuildMenu(Root: TMenuItem; Event: TNotifyEvent; Simple: boolean);
285 procedure PlaySound(const FileName: String);
286 //TBottleSstp
\8aÖ
\8cW
\83C
\83x
\83\93\83g
\83n
\83\93\83h
\83\89
287 procedure BottleSstpResendCountChange(Sender: TObject);
288 procedure BottleSstpResendTrying(Sender: TObject; MID: String);
289 procedure BottleSstpResendEnd(Sender: TObject; MID: String);
290 function IsSurfaceTag(const Script: String; var ID: integer): boolean;
291 procedure DoSurfacePreview(Surface: integer);
293 function DoTrans(var Script: String;
294 Options: TScriptTransOptions): String;
295 function ScriptTransForSSTP(const Script: String): String;
296 procedure BeginConnect;
297 procedure RetryBeginConnect;
298 procedure EndConnect;
299 procedure ConstructMenu(Simple: boolean);
300 property Connecting: boolean read FConnecting write SetConnecting;
301 function SetHWndToFavoriteGhost(const Ghost: String): String;
302 function GhostNameToSetName(const Ghost: String): String;
303 procedure PostCommand(const Command: array of String); overload;
304 procedure PostCommand(Command: TStrings); overload;
305 procedure PostSetChannel(Channels: TStrings);
306 procedure SaveChainRuleList;
311 frmSender: TfrmSender;
314 PanelConnecting = 0; //
\81u
\90Ú
\91±
\92\86\81v
\95\
\8e¦
\97p
315 PanelBytes = 1; //
\81\9b\81\9b\83o
\83C
\83g
316 PanelCount = 2; //Local Proxy
\81A
\8c»
\8dÝ
\81\9b\8c\8f\91Ò
\82¿
318 PanelStatus = 4; //
\93o
\98^
\82³
\82ê
\82Ä
\82¢
\82Ü
\82·
\81c
\82È
\82Ç
321 IconDisconnected = 18;
323 IconSleepDisconnected = 20;
325 WarningColor = clRed;
327 SendButtonLongHint = 'Bottle
\82Ì
\91\97\90M';
329 function Token(const Str: String; const Delimiter: char;
330 const Index: integer): String;
334 uses SendConfirm, SettingForm, ChannelListForm, LogForm,
335 MessageBox, FMOExplorer;
339 //
\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
340 function Token(const Str: String; const Delimiter: char;
341 const Index: integer): String;
342 var i, c, len: integer;
348 while i <= len do begin
349 if (Str[i] = Delimiter) and (StrByteType(PChar(Str), i) <> mbTrailByte) then begin
351 if c > Index then Break;
352 end else if c = Index then Result := Result + Str[i];
359 procedure TfrmSender.actConfirmExecute(Sender: TObject);
360 var Res: TSstpResult;
361 Script, Ghost, Err: String;
362 Opt: TScriptTransOptions;
364 if Length(GetScriptText) = 0 then Exit;
366 Script := GetScriptText;
367 if Pref.IgnoreTimeCritical then
368 Opt := [toIgnoreTimeCritical, toWarnCheck]
370 Opt := [toWarnCheck];
371 if Pref.NoTransUrl then Opt := Opt + [toNoChoice];
372 if Pref.HUTagTo01Tag then Opt := Opt + [toHUTagTo01Tag];
373 Err := DoTrans(Script, Opt + [toConvertURL, toWarnMessySurface]);
374 if Err <> '' then begin
378 if cbxTargetGhost.ItemIndex > 0 then begin
379 Ghost := cbxTargetGhost.Text
381 if FNowChannel <> '' then
382 Ghost := ChannelList.Channel[FNowChannel].Ghost;
384 Ghost := SetHWndToFavoriteGhost(Ghost);
385 DirectSstp.SstpSender := 'SSTP Bottle -
\81y
\8am
\94F
\81z';
387 Res := DirectSstp.SstpSEND(Script, [soNoTranslate], GhostNameToSetName(Ghost));
388 if Res <> srOk then begin
389 ShowHintLabel('
\91\97\90M
\8e¸
\94s:' + DirectSstp.RecvLog, WarningColor);
392 FScriptModified := false;
396 procedure TfrmSender.FormCreate(Sender: TObject);
397 var Str: TStringList;
399 SakuraSeeker.OnDetectResultChanged := SakuraSeekerDetectResultChanged;
400 FConstDir := ExtractFileDir(Application.ExeName)+'\consts';
401 ScriptConstList.LoadFromDir(FConstDir);
402 FSppDir := ExtractFileDir(Application.ExeName)+'\spp';
403 Spps.LoadFromDirectory(FSppDir);
404 ConstructMenu(false);
406 Str := TStringList.Create;
409 Str.LoadFromFile(ExtractFilePath(Application.ExeName)+'rule.txt');
410 BottleChainRuleList := StringToComponent(Str.Text) as TBottleChainRuleList;
413 Str.LoadFromFile(ExtractFilePath(Application.ExeName)+'defrule.txt');
414 BottleChainRuleList := StringToComponent(Str.Text) as TBottleChainRuleList;
416 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');
417 Application.Terminate;
418 Application.ProcessMessages;
426 FOriginalCaption := Self.Caption;
429 ShowMessage('
\93ñ
\8fd
\8bN
\93®
\8b\96\89Â
\83o
\81[
\83W
\83\87\83\93\82Å
\82·
\81B'#13#10 + VersionString);
431 FMutex := OpenMutex(MUTEX_ALL_ACCESS, false, 'SSTPBottleClient2');
432 if FMutex <> 0 then begin
434 ShowMessage('SSTP Bottle Client
\82Í
\93ñ
\8fd
\8bN
\93®
\82Å
\82«
\82Ü
\82¹
\82ñ');
436 Application.Terminate;
437 Application.ProcessMessages; //WM_QUIT
\82ð
\97¬
\82·
440 FMutex := CreateMutex(nil, false, 'SSTPBottleClient2');
444 mnShowToolBar.Checked := Pref.ShowToolBar;
445 mnShowConstBar.Checked := Pref.ShowConstBar;
446 if Pref.StayOnTop then begin
447 FormStyle := fsStayOnTop;
448 mnStayOnTop.Checked := true;
450 FormStyle := fsNormal;
451 mnStayOnTop.Checked := false;
454 mnGoToHP.Hint := Pref.HomePage;
455 mnGotoGlog.Hint := Pref.GLogPage;
456 mnGotoVote.Hint := Pref.VotePage;
457 mnGotoHelp.Hint := Pref.HelpPage;
459 mnGetNewId.Enabled := (Pref.LUID = '');
462 SsParser.TagPattern.LoadFromFile(ExtractFilePath(Application.Exename) + 'tagpat.txt');
463 SsParser.MetaPattern.LoadFromFile(ExtractFilePath(Application.ExeName) + 'metapat.txt');
465 ShowMessage('tagpat.txt, metapat.txt
\82ª
\8c©
\82Â
\82©
\82è
\82Ü
\82¹
\82ñ
\81B');
466 Application.Terminate;
469 with Pref.SenderWindowPosition do begin
472 Self.Width := Right - Left + 1;
473 Self.Height := Bottom - Top + 1;
476 actClearExecute(Sender);
478 UpdateJoinChannelList(nil);
480 // SSTP
\8dÄ
\91\97\83I
\83u
\83W
\83F
\83N
\83g
481 FBottleSstp := TBottleSstp.Create(false);
482 with FBottleSstp do begin
483 OnResendCountChange := BottleSstpResendCountChange;
484 OnResendTrying := BottleSstpResendTrying;
485 OnResendEnd := BottleSstpResendEnd;
489 procedure TfrmSender.FormDestroy(Sender: TObject);
491 if FBottleSstp <> nil then begin
492 FBottleSstp.Terminate;
497 with Pref.SenderWindowPosition do begin
500 Right := Self.Left + Self.Width - 1;
501 Bottom := Self.Top + Self.Height - 1;
504 if JoinChannelsBackup <> nil then JoinChannelsBackup.Free;
506 ScriptConstList.Save;
509 BottleChainRuleList.Free;
512 ReleaseMutex(FMutex);
517 procedure TfrmSender.SetConnecting(const Value: boolean);
519 FConnecting := Value;
521 StatusBar.Panels[PanelConnecting].Text := '
\92Ê
\90M
\92\86';
522 actStart.Enabled := false;
523 actStop.Enabled := false;
524 actSend.Enabled := false;
525 actVoteMessage.Enabled := false;
526 actAgreeMessage.Enabled := false;
527 mnGetNewId.Enabled := false;
528 Screen.Cursor := crAppStart;
530 StatusBar.Panels[PanelConnecting].Text := '';
531 actStart.Enabled := true;
532 actStop.Enabled := true;
533 actSend.Enabled := true;
534 //actVoteMessage.Enabled := true;
535 //actAgreeMessage.Enabled := true;
536 frmLog.lvwLogChange(Self, nil, ctState);
537 mnGetNewId.Enabled := Pref.LUID = '';
538 Screen.Cursor := crDefault;
542 procedure TfrmSender.actSendExecute(Sender: TObject);
543 var Talk, Ghost: String;
544 Command: TStringList;
548 if Length(GetScriptText) = 0 then begin
549 ShowMessage('
\83X
\83N
\83\8a\83v
\83g
\82ª
\8bó
\82Å
\82·
\81B');
553 if Pref.LUID = '' then begin
557 if tabChannel.TabIndex < 0 then begin
558 ShowMessage('
\83`
\83\83\83\93\83l
\83\8b\82É
\8eQ
\89Á
\82µ
\82Ä
\82¢
\82Ü
\82¹
\82ñ
\81B'#13#10+
559 '
\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');
562 if ChannelList.Channel[FNowChannel].NoPost then begin
564 ShowMessage(FNowChannel + '
\82Í
\8eó
\90M
\90ê
\97p
\82Å
\82·');
568 if Pref.NeedConfirmBeforeSend and FScriptModified then begin
569 MessageDlg('
\91\97\90M
\91O
\82É
\83\8d\81[
\83J
\83\8b\8am
\94F
\82µ
\82Ä
\82
\82¾
\82³
\82¢
\81B', mtError, [mbOk], 0);
573 if not Pref.NoConfirm then begin
574 if not SendConfirmDialog(FNowChannel, cbxTargetGhost.Text) then Exit;
578 Talk := GetScriptText;
579 Err := DoTrans(Talk, [toWarnMessySurface, toWarnCheck]);
580 if Err <> '' then begin
581 MessageDlg(Err, mtWarning, [mbOk], 0);
586 if cbxTargetGhost.ItemIndex > 0 then Ghost := cbxTargetGhost.Text;
588 Command := TStringList.Create;
589 with Command do begin
590 Add('Command: sendBroadcast');
591 Add('Channel: ' + FNowChannel);
592 Add('LUID: ' + Pref.LUID);
593 Add('Agent: ' + VersionString);
594 if Ghost <> '' then Add('Ghost: ' + Ghost);
595 Add('Talk: ' + Talk);
597 PostCommand(Command);
602 //
\91\97\90M
\83\8d\83O
\95Û
\91¶
603 AssignFile(F, ExtractFilePath(Application.ExeName) + SentLogFile);
604 if FileExists(ExtractFilePath(Application.ExeName) + SentLogFile) then
608 WriteLn(F, Format('%s,%s,%s,%s', [FNowChannel, Ghost, FormatDateTime('yy/mm/dd hh:nn:ss', Now), Talk]));
613 procedure TfrmSender.BeginConnect;
615 if Pref.LUID = '' then begin
619 IdSlpp20.LUID := Pref.LUID;
620 self.Cursor := crHourGlass;
622 if IdSlpp20.Connected then IdSlpp20.Disconnect;
623 if Pref.UseHttpProxy then begin
624 IdSlpp20.Host := Pref.ProxyAddress;
625 IdSlpp20.Port := Pref.ProxyPort;
626 IdSlpp20.ProxyMode := true;
628 IdSlpp20.Host := 'bottle.mikage.to';
629 IdSlpp20.Port := 9871;
630 IdSlpp20.ProxyMode := false;
634 on EIdException do begin
636 if FBeginConnectFailCount = 0 then begin
637 Inc(FBeginConnectFailCount);
639 if Pref.UseHttpProxy then
640 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 +
641 '
\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 +
642 '
\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')
644 ShowMessage('SSTP Bottle
\83T
\81[
\83o
\82É
\90Ú
\91±
\82Å
\82«
\82Ü
\82¹
\82ñ
\82Å
\82µ
\82½
\81B'#13#10 +
645 '
\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 +
646 '
\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');
648 Inc(FBeginConnectFailCount);
651 self.Cursor := crDefault;
654 procedure TfrmSender.EndConnect;
656 IdSlpp20.OnDisconnect := nil;
660 procedure TfrmSender.SetAdded(const Value: boolean);
662 if FAdded = Value then Exit;
665 StatusText := 'SSTP Bottle
\83T
\81[
\83o
\82É
\90Ú
\91±
\82³
\82ê
\82Ä
\82¢
\82Ü
\82·';
667 ShowHintLabel('SSTP Bottle
\83T
\81[
\83o
\82ª
\8c©
\82Â
\82©
\82è
\82Ü
\82µ
\82½');
669 StatusText := '
\83T
\81[
\83o
\82Æ
\82Ì
\90Ú
\91±
\82ª
\90Ø
\82ê
\82Ä
\82¢
\82Ü
\82·!';
671 ShowHintLabel('SSTP Bottle
\83T
\81[
\83o
\82©
\82ç
\90Ø
\92f
\82³
\82ê
\82Ü
\82µ
\82½!', WarningColor);
675 procedure TfrmSender.HTTPSuccess(Sender: TObject);
676 var Str, ResStr, Command: String;
677 HeadValue: THeadValue;
679 SetChannel: TStringList;
682 Str := (Sender as THttpDownloadThread).RecvString;
686 HeadValue := THeadValue.Create(Str);
688 ShowMessage('SSTP Bottle
\83T
\81[
\83o
\82ª
\89ð
\90Í
\82Å
\82«
\82È
\82¢
\83G
\83\89\81[
\82ð
\95Ô
\82µ
\82Ü
\82µ
\82½
\81B');
691 Command := HeadValue['Command'];
692 ResStr := HeadValue['Result'];
693 if ResStr = 'Err' then begin
694 if HeadValue['ExtraMessage'] <> '' then begin
696 ShowMessage('SSTP Bottle
\83T
\81[
\83o
\82ª
\8e\9f\82Ì
\83G
\83\89\81[
\82ð
\95Ô
\82µ
\82Ü
\82µ
\82½:'#13#10 +
697 HeadValue['ExtraMessage']);
700 ShowMessage('SSTP Bottle
\83T
\81[
\83o
\82ª
\89½
\82ç
\82©
\82Ì
\83G
\83\89\81[
\82ð
\95Ô
\82µ
\82Ü
\82µ
\82½
\81B');
703 if (Command = 'sendBroadcast') and (ResStr = 'OK') then begin
704 ShowHintLabel(HeadValue['Channel'] + '
\82Ì ' + HeadValue['SentNum'] +
705 '
\90l
\82É
\91\97\90M
\82µ
\82Ü
\82µ
\82½');
706 //
\83S
\81[
\83X
\83g
\82ð
\83f
\83t
\83H
\83\8b\83g
\82É
\96ß
\82·
707 if Pref.ResetIfGhostAfterSend then begin
708 cbxTargetGhost.ItemIndex := 0;
710 //
\83X
\83N
\83\8a\83v
\83g
\82ð
\83N
\83\8a\83A
711 if Pref.ClearAfterSend then begin
714 end else if (Command = 'sendBroadcast') and (ResStr <> 'OK') then begin
715 ShowHintLabel('
\83\81\83b
\83Z
\81[
\83W
\82ð
\91\97\90M
\82Å
\82«
\82Ü
\82¹
\82ñ
\82Å
\82µ
\82½', WarningColor);
717 if (Command = 'getNewId') then begin
718 if ResStr = 'OK' then begin
719 Pref.LUID := HeadValue['NewID'];
720 ShowHintLabel('LUID
\8eæ
\93¾
\8a®
\97¹
\81B');
721 mnGetNewId.Enabled := false;
724 ShowHintLabel('LUID
\8eæ
\93¾
\82É
\8e¸
\94s
\82µ
\82Ü
\82µ
\82½');
727 if (Command = 'voteMessage') then begin
728 if ResStr = 'OK' then begin
729 ShowHintLabel('
\83\81\83b
\83Z
\81[
\83W
\82É
\93\8a\95[/
\93¯
\88Ó
\82µ
\82Ü
\82µ
\82½
\81B
\95[
\90\94: ' + HeadValue['Votes']);
732 if (Command = 'getChannels') and (ResStr = 'OK') then begin
733 UpdateChannelInfo(HeadValue);
736 if FAutoAddAfterGetChannel then begin
737 SetChannel := TStringList.Create;
738 if JoinChannelsBackup <> nil then begin
739 //
\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
740 SetChannel.Assign(JoinChannelsBackup);
742 //
\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¾
743 for i := 0 to Pref.AutoJoinChannels.Count-1 do begin
744 if ChannelList.Channel[Pref.AutoJoinChannels[i]] <> nil then
745 SetChannel.Add(Pref.AutoJoinChannels[i]);
749 if frmChannelList.Execute(ChannelList, JoinChannels) then begin
750 SetChannel := TStringList.Create;
751 SetChannel.Assign(frmChannelList.JoinList);
754 if SetChannel <> nil then PostSetChannel(SetChannel);
756 if SetChannel <> nil then FreeAndNil(SetChannel);
759 if (Command = 'setChannels') then begin
760 if ResStr <> 'OK' then begin
762 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¢');
763 ShowHintLabel('
\83`
\83\83\83\93\83l
\83\8b\90Ý
\92è
\82É
\8e¸
\94s
\82µ
\82Ü
\82µ
\82½', WarningColor);
766 if HeadValue['ExtraTip'] <> '' then ShowHintLabel(HeadValue['ExtraTip']);
772 procedure TfrmSender.actStartClick(Sender: TObject);
774 if Pref.LUID = '' then begin
778 if not IdSlpp20.Connected then begin
779 FBeginConnectFailCount := 0; //
\8e©
\93®
\8dÄ
\90Ú
\91±
\83J
\83E
\83\93\83^
\83\8a\83Z
\83b
\83g
783 FAutoAddAfterGetChannel := false;
784 PostCommand(['Command: getChannels']);
788 procedure TfrmSender.actStopExecute(Sender: TObject);
790 //
\8b
\90§
\8dÄ
\90Ú
\91±
\82ð
\8ds
\82¤
791 IdSlpp20.OnDisconnect := nil;
792 if IdSlpp20.Connected then IdSlpp20.Disconnect;
793 FAutoAddAfterGetChannel := true;
795 IdSlpp20.OnDisconnect := Slpp20Disconnect;
798 procedure TfrmSender.FormShow(Sender: TObject);
800 if FBooted or Application.Terminated then Exit;
801 //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
802 if Pref.LUID <> '' then BeginConnect
803 else mnGetNewIdClick(Self);
804 FAutoAddAfterGetChannel := Pref.AutoStart;
807 frmSurfacePreview.Show;
809 SakuraSeekerDetectResultChanged(Self);
812 procedure TfrmSender.mnAboutClick(Sender: TObject);
815 Str := VersionString + #13#10 + BottleDisclaimer + #13#10#13#10;
816 Str := Str + Format('Compiler Version: %f', [CompilerVersion]);
817 frmMessageBox.ShowMessage(Str);
820 procedure TfrmSender.actExitClientExecute(Sender: TObject);
825 procedure TfrmSender.actClearExecute(Sender: TObject);
826 var TmpScript: String;
829 TmpScript := Pref.DefaultScript;
830 Position := Pos('|', TmpScript);
831 if Position < 1 then Position := 1;
832 TmpScript := StringReplace(TmpScript, '|', '', []);
833 memScript.Lines.Text := TmpScript;
834 Sendmessage(memScript.Handle, WM_VSCROLL, SB_LINEUP, 0);
835 memScript.SelStart := Position-1;
837 if Visible then memScript.SetFocus;
838 FScriptModified := false;
839 memScriptChange(self);
842 procedure TfrmSender.memScriptChange(Sender: TObject);
845 Script := StringReplace(GetScriptText, #13#10, '', [rfReplaceAll]);
846 StatusBar.Panels[PanelBytes].Text := IntToStr(length(Script)) + '
\83o
\83C
\83g';
847 FScriptModified := true;
850 procedure TfrmSender.mnStayOnTopClick(Sender: TObject);
852 Pref.StayOnTop := not Pref.StayOnTop;
853 mnStayOnTop.Checked := Pref.StayOnTop;
854 if Pref.StayOnTop then begin
855 FormStyle := fsStayOnTop;
857 FormStyle := fsNormal;
862 function TfrmSender.GetScriptText: String;
864 Result := memScript.Lines.Text;
867 procedure TfrmSender.mnConstClick(Sender: TObject);
870 i := (Sender as TMenuItem).Tag;
871 memScript.SelText := ScriptConstList.GetConstByID(i).ConstText;
874 procedure TfrmSender.actEditConstExecute(Sender: TObject);
876 ScriptConstList.LoadFromDir(FConstDir);
878 Application.CreateForm(TfrmConstEditor, frmConstEditor);
879 frmConstEditor.Execute;
880 ScriptConstList.Save;
882 frmConstEditor.Release;
884 ConstructMenu(false);
887 procedure TfrmSender.mnTaskBarClick(Sender: TObject);
889 Application.Minimize;
890 WindowState := wsNormal;
893 procedure TfrmSender.FormClose(Sender: TObject; var Action: TCloseAction);
896 TaskTray.Registered := false;
899 procedure TfrmSender.ApplicationEventsMinimize(Sender: TObject);
902 Application.ShowMainForm := false;
903 ShowWindow(Application.Handle, SW_HIDE);
906 procedure TfrmSender.ApplicationEventsRestore(Sender: TObject);
908 Application.ShowMainForm := true;
912 procedure TfrmSender.mnTaskRestoreClick(Sender: TObject);
917 procedure TfrmSender.TaskTrayDblClick(Seft: TObject; Button: TMouseButton);
922 procedure TfrmSender.FormActivate(Sender: TObject);
927 procedure TfrmSender.mnTaskNewMessageClick(Sender: TObject);
930 actClearExecute(Sender);
933 procedure TfrmSender.ChangeTaskIcon;
938 if Sleeping then IcoNum := IconSleep else IcoNum := IconConnected;
940 if Sleeping then IcoNum := IconSleepDisconnected
941 else IcoNum := IconDisconnected;
945 imgIcon.GetIcon(IcoNum, Ico);
946 TaskTray.Icon := Ico;
947 TaskTray.Registered := true;
953 procedure TfrmSender.SetStatusText(const Value: String);
955 FStatusText := Value;
956 StatusBar.Panels[PanelStatus].Text := Value;
959 procedure TfrmSender.ApplicationEventsHint(Sender: TObject);
962 if Length(Application.Hint) > 0 then
964 StatusBar.Panels[PanelStatus].Text := GetLongHint(Application.Hint);
965 Application.HintColor := clInfoBk;
966 if (Application.Hint = SendButtonLongHint)
967 and (FNowChannel <> '') then
969 //
\91\97\90M
\83{
\83^
\83\93\82Ì
\8fê
\8d\87\82Í
\91¬
\8dU
\8fo
\82·
970 Application.HintColor := clYellow;
971 Application.ActivateHint(Mouse.CursorPos);
973 if IsSurfaceTag(Application.Hint, id) and Pref.SurfacePreviewOnHint then
975 //
\83T
\81[
\83t
\83B
\83X
\83v
\83\8c\83r
\83\85\81[
976 DoSurfacePreview(id);
980 StatusBar.Panels[PanelStatus].Text := FStatusText;
981 frmSurfacePreview.HideAway;
985 procedure TfrmSender.ConstructMenu(Simple: boolean);
987 BuildMenu(mnPopConst, mnConstClick, Simple);
988 BuildMenu(mnPopUpConst.Items, mnConstClick, Simple);
989 BuildMenu(ConstBarMenu.Items, mnConstClick, Simple);
990 //ConstMenuBar.Menu := nil;
991 ConstMenuBar.AutoSize := false;
992 ConstMenuBar.Width := 1000;
993 ConstMenuBar.Menu := ConstBarMenu;
994 ConstMenuBar.AutoSize := true;
997 procedure TfrmSender.memScriptKeyDown(Sender: TObject; var Key: Word;
1000 Func: TReturnKeyFunction;
1002 if (Key = VK_RETURN) then begin
1003 if (ssShift in Shift) then
1004 Func := Pref.WhenShiftReturn
1005 else if (ssCtrl in Shift) then
1006 Func := Pref.WhenCtrlReturn
1008 Func := Pref.WhenReturn;
1011 with tbtnInsertConst do
1012 Pos := tbtnInsertConst.ClientToScreen(Point(0, Height));
1013 mnPopUpConst.Popup(Pos.X, Pos.Y);
1016 memScript.SelText := '\n';
1020 memScript.SelText := '\n'#13#10;
1023 memScript.SelText := #13#10
1029 procedure TfrmSender.mnShowToolBarClick(Sender: TObject);
1031 mnShowToolBar.Checked := not mnShowToolBar.Checked;
1032 Pref.ShowToolBar := mnShowToolBar.Checked;
1036 procedure TfrmSender.mnShowConstBarClick(Sender: TObject);
1038 mnShowConstBar.Checked := not mnShowConstBar.Checked;
1039 Pref.ShowConstBar := mnShowConstBar.Checked;
1043 procedure TfrmSender.UpdateLayout;
1045 with SakuraScriptFountain do begin
1046 TagColor.Color := Pref.MarkUpColor;
1047 TagErrorColor.Color := Pref.MarkErrorColor;
1048 Scope0Color.Color := Pref.TalkColorH;
1049 Scope1Color.Color := Pref.TalkColorU;
1050 SynchronizedColor.Color := Pref.TalkColorS;
1052 memScript.Ruler.Visible := Pref.ShowRuler;
1053 memScript.Ruler.Color := Pref.TalkColorH;
1054 memScript.Color := Pref.BgColor;
1056 ToolBar.Visible := Pref.ShowToolBar;
1057 ConstMenuBar.Visible := Pref.ShowConstBar;
1060 with tabChannel do begin
1061 TabPosition := Pref.TabPosition;
1062 case Pref.TabPosition of
1063 tpTop: Align := alTop;
1064 tpBottom: Align := alBottom;
1069 function TfrmSender.DoTrans(var Script: String;
1070 Options: TScriptTransOptions): String;
1071 var UrlCancel, Mark: String;
1072 Url, UrlName: array[0..6] of String;
1073 i, j, u, UrlCount: integer;
1074 LastSurfaceH, LastSurfaceU: integer;
1075 UnyuTalking: boolean;
1076 QuickSection, Synchronize: boolean;
1077 Warnings: TStringList;
1082 UnyuTalking := false;
1083 QuickSection := false;
1084 Synchronize := false;
1085 SsParser.InputString := Script;
1087 Warnings := TStringList.Create;
1089 for i := 0 to SsParser.Count-1 do begin
1090 if SsParser[i] = '\t' then begin
1091 if not(toIgnoreTimeCritical in Options) then
1092 Script := Script + '\t';
1093 end else if SsParser[i] = '\e' then begin
1095 end else if (SsParser.Match(SsParser[i], '\URL%b') > 0) then begin
1096 if toConvertURL in Options then begin
1097 UrlCount := 0; //
\91O
\82ÌURL
\83^
\83O
\82Ì
\89e
\8b¿
\82ð
\96³
\8e\8b\81B
1098 for u := 7 downto 1 do begin
1099 if (SsParser.Match(SsParser[i],
1100 '\URL%b'+StringReplace(StringOfChar('-', u*2),
1101 '-', '%b', [rfReplaceAll]))) > 0 then begin
1102 for j := 1 to u do begin
1103 Url[UrlCount] := SsParser.GetParam(SsParser[i], UrlCount*2+2);
1104 UrlName[UrlCount] := SsParser.GetParam(SsParser[i], UrlCount*2+3);
1105 if UrlName[UrlCount] = '' then UrlName[UrlCount] := Url[UrlCount];
1106 if Pos('http://', Url[UrlCount]) > 0 then Inc(UrlCount);
1109 if UrlCount > 0 then UrlCancel := SsParser.GetParam(SsParser[i], 1);
1110 if UrlCancel = '' then UrlCancel := '
\8ds
\82©
\82È
\82¢
\81@
\81@
\81@
\81@';
1112 if SsParser.Match(SsParser[i], '\URL%b%b') = 0 then begin //
\8aÈ
\88Õ
\94ÅURL
\95Ï
\8a·
1113 //
\8aÈ
\88Õ
\8c`
\8e®\URL
\83^
\83O
\95Ï
\8a·
1114 Url[0] := SsParser.GetParam(SsParser[i], 1);
1115 UrlName[0] := '
\8ds
\82
\81@
\81@
\81@
\81@
\81@
\81@';
1116 UrlCancel := '
\8ds
\82©
\82È
\82¢
\81@
\81@
\81@
\81@';
1117 if Pos('http://', Url[0]) > 0 then begin
1119 if not QuickSection then
1120 Script := Script + '\_q' + Url[0] + '\_q'
1122 Script := Script + Url[0];
1125 end else Script := Script + SsParser[i];
1127 Mark := SsParser[i];
1128 if Mark = '\h' then begin
1129 UnyuTalking := false;
1130 if toHUTagTo01Tag in Options then Mark := '\0';
1131 if Synchronize and Pref.WarnScopeChangeInSynchronize then
1132 Warnings.Add('
\83V
\83\93\83N
\83\8d\83i
\83C
\83Y
\83h
\83Z
\83N
\83V
\83\87\83\93\92\86\82É\h
\82ª
\82 \82è
\82Ü
\82·
\81B');
1133 end else if Mark = '\u' then begin
1134 UnyuTalking := true;
1135 if toHUTagTo01Tag in Options then Mark := '\1';
1136 if Synchronize and Pref.WarnScopeChangeInSynchronize then
1137 Warnings.Add('
\83V
\83\93\83N
\83\8d\83i
\83C
\83Y
\83h
\83Z
\83N
\83V
\83\87\83\93\92\86\82É\u
\82ª
\82 \82è
\82Ü
\82·
\81B');
1138 end else if Mark = '\_q' then begin
1139 QuickSection := not QuickSection;
1140 end else if Mark = '\_s' then begin
1141 Synchronize := not Synchronize;
1142 end else if SsParser.Match(Mark, '\s%b') > 0 then begin
1143 if UnyuTalking then begin
1144 LastSurfaceU := StrToIntDef(SsParser.GetParam(Mark, 1),
1147 LastSurfaceH := StrToIntDef(SsParser.GetParam(Mark, 1),
1150 end else if SsParser.Match(Mark, '\s%d') > 0 then begin
1151 if UnyuTalking then begin
1152 LastSurfaceU := StrToIntDef(Mark[3], LastSurfaceU);
1154 LastSurfaceH := StrToIntDef(Mark[3], LastSurfaceH);
1157 Script := Script + Mark;
1160 if UrlCount > 0 then begin
1161 Script := Script + '\h\n';
1162 if not (toNoChoice in Options) then begin
1163 for i := 0 to UrlCount-1 do begin
1164 Script := Script + Format('\q%d[%s][%s]',
1165 [i, SsParser.EscapeParam(Url[i]), UrlName[i]]);
1167 Script := Script + Format('\q%d[#cancel][%s]', [UrlCount, UrlCancel]);
1168 //Script := Script + '\z'; //
\8dÅ
\90Vphase
\82Å
\82Í
\8dí
\8f\9c
1170 Script := Script + '\h';
1171 for i := 0 to UrlCount-1 do begin
1172 Script := Script + Format('\n{%s}(%s)', [UrlName[i], Url[i]]);
1173 Script := Script + Format('\n{%s}', [UrlCancel]);
1177 //
\83X
\83N
\83\8a\83v
\83g
\82Ì
\8dÅ
\8cã
\82É
\83E
\83F
\83C
\83g
\91}
\93ü
1178 if toWaitScriptEnd in Options then begin
1179 i := Pref.WaitScriptEnd;
1180 while i > 0 do begin
1182 Script := Script + '\w9';
1185 Script := Script + '\w' + IntToStr(i);
1191 Script := Script + '\e';
1192 RegExp.Subst('s/\r\n//gk', Script);
1194 //
\83^
\83O
\83`
\83F
\83b
\83N
\8aÖ
\98A
1195 for i := 0 to SsParser.Count-1 do begin
1196 if SsParser.MarkUpType[i] = mtTagErr then begin
1197 Result := '"' + SsParser[i] + '"'#13#10 +
1198 '
\82Í
\81ASSTP Bottle
\82Å
\94F
\82ß
\82ç
\82ê
\82È
\82¢
\82©
\81A
\94F
\8e¯
\82Å
\82«
\82È
\82¢
\83^
\83O
\82Å
\82·
\81B';
1202 if (SsParser[0] <> '\t') and Pref.WarnYenTNotExist then begin
1203 Warnings.Add('
\83X
\83N
\83\8a\83v
\83g
\82ª\t
\82©
\82ç
\8en
\82Ü
\82Á
\82Ä
\82¢
\82Ü
\82¹
\82ñ
\81B');
1207 if (Warnings.Count > 0) and (toWarnCheck in Options) then begin
1208 if MessageDlg(Warnings.Text + #13#10 + '
\91\97\90M
\82µ
\82Ü
\82·
\82©?', mtWarning,
1209 mbOkCancel, 0) = mrCancel then
1210 Result := Warnings.Text;
1217 procedure TfrmSender.mnGoToHPClick(Sender: TObject);
1219 ShellExecute(Handle, 'open', PChar(Pref.HomePage), nil, nil, SW_SHOW);
1222 procedure TfrmSender.ShowHintLabel(const Mes: String; Col: TColor);
1224 lblMessage.Caption := Mes;
1225 lblMessage.Font.Color := Col;
1226 lblMessage.Visible := true;
1227 LabelTimer.Enabled := false;
1228 LabelTimer.Enabled := true;
1231 procedure TfrmSender.LabelTimerTimer(Sender: TObject);
1233 LabelTimer.Enabled := false;
1234 lblmessage.Visible := false;
1237 procedure TfrmSender.actCopyAllExecute(Sender: TObject);
1241 Str := memScript.Lines.Text;
1242 Clip := ClipBoard();
1243 Clip.SetTextBuf(PChar(Str));
1246 procedure TfrmSender.actCopyAllNoReturnExecute(Sender: TObject);
1250 Str := memScript.Lines.Text;
1251 RegExp.Subst('s/\r\n//gk', Str);
1252 Clip := ClipBoard();
1253 Clip.SetTextBuf(PChar(Str));
1256 procedure TfrmSender.Slpp20SlppEvent(Sender: TObject; EventType: TIdSlppEventType;
1257 const Param: String);
1258 var HeadValue: THeadValue;
1260 HeadValue := THeadValue.Create(Param);
1263 etScript, etForceBroadcast, etUnicast: begin
1264 //
\83\81\83b
\83Z
\81[
\83W
\8eó
\90M
1265 DispatchBottle(EventType, HeadValue);
1267 etMemberCount: begin
1268 StatusBar.Panels[PanelMembers].Text := HeadValue['Num'] + '
\90l'
1270 etChannelCount: begin
1272 ChannelList.Channel[HeadValue['Channel']].Members := StrToInt(HeadValue['Num']);
1277 ShowHintLabel('SSTP Bottle
\83T
\81[
\83o
\82Æ
\92Ê
\90M
\8am
\97§
\81B');
1278 FBeginConnectFailCount := 0;
1279 //
\83`
\83\83\83\93\83l
\83\8b\8e©
\93®
\93o
\98^
1280 if not Connecting then
1281 PostCommand(['Command: getChannels']);
1282 SakuraSeeker.BeginDetect;
1283 if SakuraSeeker.Count = 0 then
1284 frmMessageBox.ShowMessage('
\83S
\81[
\83X
\83g(SSTP
\83T
\81[
\83o)
\82ª1
\82Â
\82à
\8bN
\93®
\82µ
\82Ä
\82¢
\82Ü
\82¹
\82ñ
\81B'#13#10 +
1285 'SSTP Bottle
\82ð
\97\98\97p
\82·
\82é
\82½
\82ß
\82É
\82Í
\81A
\83S
\81[
\83X
\83g
\82ð
\93¯
\8e\9e\82É
\8bN
\93®
\82·
\82é
\95K
\97v
\82ª
\82 \82è
\82Ü
\82·'#13#10 +
1286 '
\8fÚ
\8d×
\82Í
\83w
\83\8b\83v
\82ð
\82²
\97\97\89º
\82³
\82¢
\81B');
1288 etChannelList: begin
1289 UpdateJoinChannelList(HeadValue);
1290 //
\8dÅ
\8cã
\82É
\8eQ
\89Á
\82µ
\82Ä
\82¢
\82½
\83`
\83\83\83\93\83l
\83\8b\82ð
\8bL
\98^
\82·
\82é
1291 if JoinChannelsBackup = nil then JoinChannelsBackup := TStringList.Create;
1292 JoinChannelsBackup.Assign(JoinChannels);
1294 etCloseChannel: begin
1295 with JoinChannels do
1296 if IndexOf(HeadValue['Channel']) >= 0 then
1297 Delete(IndexOf(HeadValue['Channel']));
1298 with tabChannel do begin
1299 if Tabs.IndexOf(HeadValue['Channel']) >= 0 then
1300 Tabs.Delete(Tabs.IndexOf(HeadValue['Channel']));
1301 if Tabs.Count > 0 then TabIndex := 0 else TabIndex := -1;
1302 tabChannelChange(self);
1304 ShowHintLabel(HeadValue['Channel'] + '
\83`
\83\83\83\93\83l
\83\8b\82Í
\94p
\8e~
\82³
\82ê
\82Ü
\82µ
\82½',
1306 frmLog.AddCurrentSystemLog('SYSTEM', HeadValue['Channel'] + '
\83`
\83\83\83\93\83l
\83\8b\82Í
\94p
\8e~
\82³
\82ê
\82Ü
\82µ
\82½');
1307 frmMessageBox.ShowMessage(HeadValue['Channel'] + '
\83`
\83\83\83\93\83l
\83\8b\82Í
\94p
\8e~
\82³
\82ê
\82Ü
\82µ
\82½');
1309 etForceBroadcastInformation: begin
1310 if HeadValue['Type'] = 'Vote' then begin
1311 frmLog.VoteLog(HeadValue['MID'], StrToIntDef(HeadValue['Num'], 0));
1312 end else if HeadValue['Type'] = 'Agree' then begin
1313 frmLog.AgreeLog(HeadValue['MID'], StrToIntDef(HeadValue['Num'], 0));
1322 procedure TfrmSender.BottleSstpResendCountChange(Sender: TObject);
1324 StatusBar.Panels[PanelCount].Text := IntToStr(FBottleSstp.CueCount) + '
\8c\8f';
1325 TaskTray.TipString := 'SSTP Bottle Client (' +
1326 IntToStr(FBottleSstp.CueCount) + '
\8c\8f)';
1327 actClearBottles.Enabled := (FBottleSstp.CueCount > 0);
1330 procedure TfrmSender.actSettingExecute(Sender: TObject);
1332 Application.CreateForm(TfrmSetting, frmSetting);
1344 frmLog.UpdateWindow;
1347 procedure TfrmSender.memScriptKeyPress(Sender: TObject; var Key: Char);
1349 if (Key = #13) or (Key = #10) then Key := Char(0);
1352 procedure TfrmSender.Slpp20Disconnect(Sender: TObject);
1355 UpdateJoinChannelList(nil);
1356 frmLog.AddCurrentSystemLog('SYSTEM', '
\83T
\81[
\83o
\82©
\82ç
\90Ø
\92f
\82³
\82ê
\82Ü
\82µ
\82½');
1357 if not Application.Terminated then RetryBeginConnect;
1360 procedure TfrmSender.SetSleeping(const Value: boolean);
1363 FBottleSstp.ResendSleep := Value;
1367 procedure TfrmSender.actClearBottlesExecute(Sender: TObject);
1370 Re := MessageDlg(Format('
\96¢
\94z
\91\97\82Ì%d
\8c\8f\82ÌBottle
\82ð
\91S
\95\94\83N
\83\8a\83A
\82µ
\82Ü
\82·', [FBottleSstp.CueCount]),
1371 mtWarning, mbOkCancel, 0);
1372 if Re = mrOk then begin
1374 frmLog.AllBottleOpened;
1375 frmLog.UpdateWindow;
1379 procedure TfrmSender.SakuraSeekerDetectResultChanged(Sender: TObject);
1382 Http: THTTPDownloadThread;
1385 UpdateIfGhostBox; //
\83h
\83\8d\83b
\83v
\83_
\83E
\83\93\82Ì
\92\86\90g
\82ð
\8f\91\82«
\8a·
\82¦
\82é
1386 //
\8d\91\90¨
\92²
\8d¸
\82É
\8eQ
\89Á
1387 if FBooted and not Pref.NoSendGhostList and (SakuraSeeker.Count > 0) then begin
1388 GhostList := 'CCC=' + TIdURI.ParamsEncode('
\88¤');
1389 GhostList := GhostList + '&LUID=' + Pref.LUID;
1391 for i := 0 to SakuraSeeker.Count-1 do begin
1392 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¤
1393 GhostList := GhostList + '&GHOST=' + TIdURI.ParamsEncode(SakuraSeeker[i].SetName);
1397 if SendOk then begin
1398 Http := THTTPDownloadThread.Create(BottleServer, Pref.CgiNameGhost, GhostList);
1399 if Pref.UseHttpProxy then begin
1400 Http.ProxyServer := Pref.ProxyAddress;
1401 Http.ProxyPort := Pref.ProxyPort;
1403 Http.FreeOnTerminate := true;
1409 procedure TfrmSender.UpdateChannelInfo(Dat: THeadValue);
1411 Ch: TChannelListItem;
1414 for i := 1 to Dat.IntData['Count'] do begin
1415 Ch := TChannelListItem.Create;
1416 Ch.Name := Dat[Format('CH%d_name', [i])];
1417 Ch.Ghost := Dat[Format('CH%d_ghost', [i])];
1418 Ch.Info := Dat[Format('CH%d_info', [i])];
1419 Ch.NoPost := Dat[Format('CH%d_nopost', [i])] = '1';
1420 Ch.Members := Dat.IntData[Format('CH%d_count', [i])];
1421 Ch.WarnPost:= Dat[Format('CH%d_warnpost', [i])] = '1';
1422 ChannelList.Add(Ch);
1427 procedure TfrmSender.mnGetNewIdClick(Sender: TObject);
1429 PostCommand(['Command: getNewId', 'Agent: ' + VersionString]);
1432 procedure TfrmSender.NoLuidError;
1435 ShowMessage('SSTP Bottle ID
\82Ì
\8eæ
\93¾
\82ª
\82Ü
\82¾
\8a®
\97¹
\82µ
\82Ä
\82¢
\82Ü
\82¹
\82ñ
\81B'#13#10+
1436 '
\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+
1437 '
\82±
\82Ì
\91\80\8dì
\82ÍClient
\8f\89\89ñ
\8bN
\93®
\8e\9e\82É1
\89ñ
\82¾
\82¯
\95K
\97v
\82Å
\82·
\81B');
1440 procedure TfrmSender.tabChannelChange(Sender: TObject);
1442 if tabChannel.TabIndex >= 0 then begin
1443 FNowChannel := tabChannel.Tabs[tabChannel.TabIndex];
1444 actSend.Hint := Format('
\81u%s
\81v
\82É
\91\97\90M|%s', [FNowChannel, SendButtonLongHint]);
1449 tabChannel.Repaint; //
\82±
\82ê
\82ª
\82È
\82¢
\82Æ
\90F
\82ª
\95Ï
\82í
\82ç
\82È
\82¢
\82±
\82Æ
\82ª
\82 \82é
1450 ConstructMenu(true);
1453 procedure TfrmSender.actPrevChannelExecute(Sender: TObject);
1455 with tabChannel do begin
1456 if Tabs.Count = 0 then Exit;
1457 if TabIndex=0 then TabIndex := Tabs.Count-1
1458 else TabIndex := TabIndex-1;
1460 tabChannelChange(Self);
1463 procedure TfrmSender.actNextChannelExecute(Sender: TObject);
1465 with tabChannel do begin
1466 if Tabs.Count = 0 then Exit;
1467 if TabIndex=Tabs.Count-1 then TabIndex := 0
1468 else TabIndex := TabIndex+1;
1470 tabChannelChange(Self);
1473 procedure TfrmSender.UpdateJoinChannelList(Dat: THeadValue);
1477 nodat := Dat = nil; //nil
\82È
\82ç
\83`
\83\83\83\93\83l
\83\8b\91S
\89ð
\8f\9c
1478 if nodat then Dat := THeadValue.Create('');
1480 for i := 0 to Dat.Count-1 do
1481 if Dat.KeyAt[i] = 'Entry' then begin
1482 if RegExp.Match('m/^(.+?) \((\d+?)\)$/', Dat.ValueAt[i]) then
1483 JoinChannels.Add(RegExp[1]);
1485 with tabChannel do begin
1490 for i := 0 to JoinChannels.Count-1 do begin
1491 //
\8eó
\90M
\90ê
\97p
\83`
\83\83\83\93\83l
\83\8b\82Í
\95\
\8e¦
\82µ
\82È
\82¢
1492 if not ChannelList.Channel[JoinChannels[i]].NoPost then
1493 Tabs.Add(JoinChannels[i]);
1497 for i := 0 to Tabs.Count-1 do
1498 if Tabs[i] = FNowChannel then TabIndex := i;
1499 if Tabs.Count > 0 then begin
1500 FNowChannel := Tabs[TabIndex];
1501 actSend.Hint := Format('
\81u%s
\81v
\82É
\91\97\90M|%s', [FNowChannel, SendButtonLongHint]);
1504 actSend.Hint := Format('
\91\97\90M|%s', [SendButtonLongHint]);
1506 Visible := Tabs.Count > 0;
1507 if Tabs.Count > 1 then begin
1508 actNextChannel.Enabled := true;
1509 actPrevChannel.Enabled := true;
1511 actNextChannel.Enabled := false;
1512 actPrevChannel.Enabled := false;
1514 OnChange := tabChannelChange;
1516 if nodat then Dat.Free;
1517 if JoinChannels.Count = 0 then begin
1518 Self.Caption := FOriginalCaption + ' -
\83`
\83\83\83\93\83l
\83\8b\82É
\8eQ
\89Á
\82µ
\82Ä
\82¢
\82Ü
\82¹
\82ñ';
1519 actSend.Enabled := false;
1521 Self.Caption := FOriginalCaption;
1522 actSend.Enabled := true;
1526 procedure TfrmSender.cbxTargetGhostDropDown(Sender: TObject);
1528 SakuraSeeker.BeginDetect;
1532 procedure TfrmSender.actShowLogExecute(Sender: TObject);
1535 if frmLog.WindowState = wsMinimized then frmLog.WindowState := wsNormal;
1538 procedure TfrmSender.Slpp20Connect(Sender: TObject);
1543 procedure TfrmSender.actSleepExecute(Sender: TObject);
1545 if actSleep.Checked then begin
1546 actSleep.Checked := false;
1547 ShowHintLabel('
\83X
\83\8a\81[
\83v
\82ð
\89ð
\8f\9c\82µ
\82Ü
\82µ
\82½');
1549 actSleep.Checked := true;
1550 ShowHintLabel('
\83X
\83\8a\81[
\83v
\82ð
\90Ý
\92è
\82µ
\82Ü
\82µ
\82½');
1552 Sleeping := actSleep.Checked;
1557 procedure TfrmSender.DispatchBottle(EventType: TIdSlppEventType;
1559 var Opt: TSstpSendOptions;
1560 Event: TBottleChainBottleEvent;
1561 Script, Sender, Ghost, Channel: String;
1562 BreakFlag, NoDispatch: boolean;
1563 Sound, LogName: String;
1564 i, j, k, SkipCount: integer;
1565 Rule: TBottleChainRule;
1566 Action: TBottleChainAction;
1567 LogNameList: TStringList;
1571 if Pref.NoTranslate then Opt := Opt + [soNoTranslate];
1572 if Pref.NoDescript then Opt := Opt + [soNoDescript];
1573 Channel := Dat['Channel'];
1575 etScript: Sender := Channel;
1576 etForceBroadcast: Sender := '
\81y
\82¨
\92m
\82ç
\82¹
\81z';
1577 etUnicast: Sender := Dat['SenderUID'];
1580 //
\96Ú
\95W
\83S
\81[
\83X
\83g(
\83I
\81[
\83o
\81[
\83\89\83C
\83h
\88È
\91O)
\8c\88\92è
1581 if Dat['IfGhost'] <> '' then begin
1582 Ghost := Dat['IfGhost'];
1584 if ChannelList.Channel[Channel] <> nil then
1585 Ghost := ChannelList.Channel[Channel].Ghost;
1587 Dat['TargetGhost'] := Ghost;
1589 Event := TBottleChainBottleEvent.Create;
1592 if EventType = etScript then Event.LogType := ltBottle
1593 else Event.LogType := ltSystemLog;
1595 //
\83X
\83N
\83\8a\83v
\83g
\95Ï
\8a·
1596 Script := ScriptTransForSSTP(Dat['Script']);
1597 if Script = '' then begin
1598 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'+
1599 '
\94z
\91\97\82³
\82ê
\82Ü
\82¹
\82ñ
\82Å
\82µ
\82½
\81@
\81c '+Dat['Script']);
1604 NoDispatch := false;
1606 LogNameList := TStringList.Create;
1609 for i := 0 to BottleChainRuleList.Count-1 do begin
1610 if SkipCount > 0 then begin
1614 Rule := BottleChainRuleList[i];
1615 if not Rule.Enabled then Continue;
1616 if not Rule.Check(Event) then Continue;
1617 for j := 0 to Rule.Actions.Count-1 do begin
1618 Action := (Rule.Actions[j] as TBottleChainAction);
1619 if Action is TBottleChainAbortRuleAction then BreakFlag := true;
1620 if Action is TBottleChainSkipRuleAction then
1621 SkipCount := (Action as TBottleChainSkipRuleAction).SkipCount;
1622 if (Action is TBottleChainSoundAction) and (Sound = '') then begin
1623 Sound := (Action as TBottleChainSoundAction).SoundFile;
1624 Sound := StringReplace(Sound, '%channel%', Dat['Channel'], [rfReplaceAll]);
1625 Sound := StringReplace(Sound, '%ghost%', Dat['TargetGhost'], [rfReplaceAll]);
1627 if Action is TBottleChainNoDispatchAction then NoDispatch := true;
1628 if Action is TBottleChainLogAction then begin
1629 for k := 0 to (Action as TBottleChainLogAction).LogNames.Count-1 do begin
1630 LogName := (Action as TBottleChainLogAction).LogNames[k];
1631 LogName := StringReplace(LogName, '%channel%', Dat['Channel'], [rfReplaceAll]);
1632 LogName := StringReplace(LogName, '%ghost%', Dat['TargetGhost'], [rfReplaceAll]);
1633 LogName := StringReplace(LogName, '%date%', FormatDateTime('yy/mm/dd', Now()), [rfReplaceAll]);
1634 LogNameList.Add(LogName);
1637 if Action is TBottleChainOverrideGhostAction then begin
1638 Dat['TargetGhost'] := (Action as TBottleChainOverrideGhostAction).TargetGhost;
1640 if Action is TBottleChainQuitAction then Application.Terminate;
1642 if BreakFlag then Break;
1645 if Dat['Script'] <> '' then begin
1646 for i := 0 to LogNameList.Count-1 do
1647 frmLog.AddCurrentScriptLog(LogNameList[i], Dat['Script'], Sender, Dat['MID'], Dat['IfGhost']);
1648 if NoDispatch then begin
1649 frmLog.SetBottleState(Dat['MID'], lsOpened);
1651 Ghost := Dat['TargetGhost']; //
\83I
\81[
\83o
\81[
\83\89\83C
\83h
\82³
\82ê
\82Ä
\82¢
\82é
\89Â
\94\
\90«
\82ª
\82 \82é
1652 CueItem := TLogItem.Create(ltBottle, Dat['MID'], Dat['Channel'],
1653 Script, Ghost, Now());
1655 FBottleSstp.Push(CueItem);
1662 if Dat['DialogMessage'] <> '' then begin
1664 frmMessageBox.ShowMessage(
1665 DateTimeToStr(Now) + #13#10 +
1666 'SSTP Bottle
\83T
\81[
\83o
\82©
\82ç
\82¨
\92m
\82ç
\82¹'#13#10+Dat['DialogMessage']);
1667 for i := 0 to LogNameList.Count-1 do
1668 frmLog.AddCurrentSystemLog(LogNameList[i], Dat['DialogMessage']);
1672 if (Sound <> '') then PlaySound(Sound);
1681 function TfrmSender.SetHWndToFavoriteGhost(const Ghost: String): String;
1683 //DirectSstp.TargetHWnd
\82ð
\81A
\90\84\8f§
\82·
\82é
\83S
\81[
\83X
\83g
\82É
\90Ý
\92è
\82·
\82é
\81B
1684 //
\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
1685 SakuraSeeker.BeginDetect; //
\8dÅ
\90V
\82ÌFMO
\8eæ
\93¾
1686 if SakuraSeeker.ProcessByName[Ghost] <> nil then begin
1687 DirectSstp.TargetHWnd := SakuraSeeker.ProcessByName[Ghost].HWnd;
1689 end else if SakuraSeeker.Count > 0 then begin
1690 DirectSstp.TargetHWnd := SakuraSeeker[0].HWnd;
1691 Result := SakuraSeeker[0].Name;
1693 DirectSstp.TargetHwnd := 0;
1698 procedure TfrmSender.YenETrans;
1699 var St, Le, i: integer;
1702 St := memScript.SelStart;
1703 Le := memScript.SelLength;
1704 Orig := GetScriptText;
1705 RegExp.Subst('s/(\r\n)+$//kg', Orig);
1707 SsParser.InputString := Orig;
1708 for i := 0 to SsParser.Count-1 do begin
1709 if SsParser[i] <> '\e' then Text := Text + SsParser[i];
1712 Text := Text + '\e';
1714 if Orig <> Text then memScript.Lines.Text := Text;
1715 SsParser.InputString := Text;
1717 RegExp.Subst('s/\r\n//kg', Text);
1719 memScript.SelStart := St;
1720 memScript.SelLength := Le;
1723 procedure TfrmSender.PostCommand(const Command: array of String);
1724 var PostStr: TStringList;
1729 PostStr := TStringList.Create;
1730 for i := Low(Command) to High(Command) do begin
1731 PostStr.Add(Command[i]);
1733 PostCommand(PostStr);
1739 procedure TfrmSender.PostCommand(Command: TStrings);
1740 var PostStr: String;
1743 PostStr := Command.Text;
1744 PostStr := TIdURI.ParamsEncode(PostStr);
1746 FHttp := THTTPDownloadThread.Create(BottleServer, Pref.CgiName, PostStr);
1747 if Pref.UseHttpProxy then begin
1748 FHttp.ProxyServer := Pref.ProxyAddress;
1749 FHttp.ProxyPort := Pref.ProxyPort;
1751 FHttp.OnSuccess := HttpSuccess;
1752 FHttp.OnConnectionFailed := HttpFailure;
1753 FHttp.FreeOnTerminate := true; //
\8f\9f\8eè
\82É
\8e©
\95ª
\82ÅFree
\82µ
\82Ä
\82
\82¾
\82³
\82¢
1756 on EHeapException do begin
1757 Connecting := false;
1763 procedure TfrmSender.tabChannelDrawTab(Control: TCustomTabControl;
1764 TabIndex: Integer; const Rect: TRect; Active: Boolean);
1767 with tabChannel.Canvas do begin
1769 if Active then begin
1770 Font.Color := clBlue;
1772 Font.Style := Font.Style - [fsBold];
1773 Font.Color := clWindowText;
1775 X := (Rect.Left + Rect.Right) div 2;
1776 X := X - TextWidth(tabChannel.Tabs[TabIndex]) div 2;
1777 if tabChannel.TabPosition = tpTop then
1780 Y := Rect.Bottom - 15;
1781 TextOut(X, Y, tabChannel.Tabs[TabIndex]);
1785 procedure TfrmSender.actVoteMessageExecute(Sender: TObject);
1788 if frmLog.lvwLog.Selected = nil then Exit;
1789 Log := frmLog.SelectedBottleLog[frmLog.lvwLog.Selected.Index] as TLogItem;
1790 if Log = nil then Exit;
1791 if Log.LogType <> ltBottle then Exit;
1793 'Command: voteMessage',
1795 'LUID: ' + Pref.LUID,
1801 procedure TfrmSender.actAgreeMessageExecute(Sender: TObject);
1804 if frmLog.lvwLog.Selected = nil then Exit;
1805 Log := frmLog.SelectedBottleLog[frmLog.lvwLog.Selected.Index] as TLogItem;
1806 if Log = nil then Exit;
1807 if Log.LogType <> ltBottle then Exit;
1809 'Command: voteMessage',
1811 'LUID: ' + Pref.LUID,
1817 function TfrmSender.GhostNameToSetName(const Ghost: String): String;
1819 if SakuraSeeker.ProcessByName[Ghost] <> nil then
1820 Result := SakuraSeeker.ProcessByName[Ghost].SetName
1825 procedure TfrmSender.tabChannelContextPopup(Sender: TObject;
1826 MousePos: TPoint; var Handled: Boolean);
1829 with tabChannel do begin
1830 Tag := IndexOfTabAt(MousePos.X, MousePos.Y);
1831 if Tag < 0 then Handled := true;
1836 procedure TfrmSender.PostSetChannel(Channels: TStrings);
1837 var PostStr: TStringList;
1842 PostStr := TStringList.Create;
1843 with PostStr do begin
1844 Add('Command: setChannels');
1845 Add('Agent: ' + VersionString);
1846 Add('LUID: ' + Pref.LUID);
1847 if Channels <> nil then
1848 for i := 0 to Channels.Count-1 do begin
1849 Add(Format('Ch%d: %s'#13#10, [i+1, Channels[i]]));
1852 PostCommand(PostStr);
1858 procedure TfrmSender.mnLeaveThisChannelClick(Sender: TObject);
1862 with tabChannel do Ch := Tabs[Tag];
1865 Chs := TStringList.Create;
1866 Chs.Assign(JoinChannels);
1867 while Chs.IndexOf(Ch) >= 0 do Chs.Delete(Chs.IndexOf(Ch));
1868 PostSetChannel(Chs);
1874 procedure TfrmSender.mnGotoVoteClick(Sender: TObject);
1876 ShellExecute(Handle, 'open', PChar(Pref.VotePage), nil, nil, SW_SHOW);
1879 procedure TfrmSender.mnGotoGLogClick(Sender: TObject);
1881 ShellExecute(Handle, 'open', PChar(Pref.GLogPage), nil, nil, SW_SHOW);
1884 procedure TfrmSender.tabChannelMouseMove(Sender: TObject;
1885 Shift: TShiftState; X, Y: Integer);
1889 with tabChannel do begin
1890 Index := IndexOfTabAt(X, Y);
1892 Hint := Ch + ': ' + IntToStr(ChannelList.Channel[Ch].Members) + '
\90l';
1896 procedure TfrmSender.mnGoToHelpClick(Sender: TObject);
1898 ShellExecute(Handle, 'open', PChar(Pref.HelpPage), nil, nil, SW_SHOW);
1901 procedure TfrmSender.tabChannelMouseDown(Sender: TObject;
1902 Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
1905 with tabChannel do begin
1906 Index := IndexOfTabAt(X, Y);
1907 if Index = -1 then Exit; //
\83^
\83u
\82ª
\82È
\82¢
\82Ì
\82Å
\83h
\83\89\83b
\83O
\82Å
\82«
\82È
\82¢
1908 if Button = mbLeft then begin
1909 FDragTabIndex := Index; //
\83h
\83\89\83b
\83O
\82·
\82é
\83^
\83u
\82Ì
\83C
\83\93\83f
\83b
\83N
\83X
\82ð
\95Û
\91¶
1911 FDragTabDest := -1; //
\83h
\83\89\83b
\83O
\98g
\90ü
\95`
\89æ
\83t
\83\89\83O
\83N
\83\8a\83A
\82Ì
\82½
\82ß
1916 procedure TfrmSender.tabChannelDragOver(Sender, Source: TObject; X,
1917 Y: Integer; State: TDragState; var Accept: Boolean);
1918 var TargetRect: TRect;
1921 Accept := Source = tabChannel;
1922 if not Accept then Exit;
1923 with tabChannel do begin
1924 OldDest := FDragTabDest;
1925 FDragTabDest := IndexOfTabAt(X, Y);
1926 if FDragTabDest = -1 then begin
1927 Accept := false; //
\82±
\82Ì
\8fê
\8d\87\82Í
\83h
\83\8d\83b
\83v
\82ð
\94F
\82ß
\82È
\82¢
1930 with Canvas do begin
1934 if (OldDest <> FDragTabDest) and (OldDest >= 0) then begin
1935 //
\88È
\91O
\82Ì
\98g
\90ü
\8fÁ
\8b\8e
1936 TargetRect := TabRect(OldDest);
1937 with Canvas do begin
1938 Brush.Style := bsClear;
1939 Rectangle(TargetRect.Left, TargetRect.Top,
1940 TargetRect.Right, TargetRect.Bottom);
1943 if (OldDest <> FDragTabDest) then begin
1944 //
\90V
\82µ
\82¢
\98g
\90ü
\95`
\89æ
1945 TargetRect := TabRect(FDragTabDest);
1946 with Canvas do begin
1947 Brush.Style := bsClear;
1948 Rectangle(TargetRect.Left, TargetRect.Top,
1949 TargetRect.Right, TargetRect.Bottom);
1955 procedure TfrmSender.tabChannelDragDrop(Sender, Source: TObject; X,
1957 var DestIndex: integer;
1959 with tabChannel do begin
1960 DestIndex := IndexOfTabAt(X, Y);
1961 Tabs.Move(FDragTabIndex, DestIndex);
1965 procedure TfrmSender.tabChannelEndDrag(Sender, Target: TObject; X,
1968 //
\8b
\90§
\93I
\82É
\83^
\83u
\82ð
\8dÄ
\95`
\89æ
\82³
\82¹
\82é
\81B
\98g
\90ü
\8fÁ
\82µ
\91Î
\8dô
1969 tabChannel.Tabs.BeginUpdate;
1970 tabChannel.Tabs.EndUpdate;
1973 procedure TfrmSender.cbxTargetGhostDrawItem(Control: TWinControl;
1974 Index: Integer; Rect: TRect; State: TOwnerDrawState);
1976 with cbxTargetGhost do begin
1977 if Index > 0 then begin
1978 if SakuraSeeker.ProcessByName[Items[Index]] = nil then
1979 Canvas.Font.Color := clRed
1981 Canvas.Font.Color := clBlue;
1982 Canvas.Font.Style := [fsBold];
1984 Canvas.Font.Color := clWindowText;
1985 Canvas.Font.Style := [];
1987 if odSelected in State then
1988 Canvas.Font.Color := clHighlightText;
1989 cbxTargetGhost.Canvas.TextRect(Rect, Rect.Left, Rect.Top,
1990 cbxTargetGhost.Items[Index]);
1994 procedure TfrmSender.FormCloseQuery(Sender: TObject;
1995 var CanClose: Boolean);
1997 if not Pref.ConfirmOnExit then Exit;
1998 if MessageDlg('SSTP Bottle Client
\82ð
\8fI
\97¹
\82µ
\82Ü
\82·', mtConfirmation,
1999 mbOkCancel, 0) = mrCancel then CanClose := false;
2002 procedure TfrmSender.UpdateIfGhostBox;
2007 cbxTargetGhost.DropDownCount := Pref.GhostDropDownCount;
2008 Selected := cbxTargetGhost.Text;
2009 with cbxTargetGhost do begin
2012 Items.Add('(CH
\90\84\8f§)');
2013 for i := 0 to SakuraSeeker.Count-1 do begin
2014 //
\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é
2015 if Length(SakuraSeeker[i].Name) = 0 then Continue;
2016 if Pref.HideGhosts then
2017 if Pref.VisibleGhostsList.IndexOf(SakuraSeeker[i].Name) < 0 then
2019 if cbxTargetGhost.Items.IndexOf(SakuraSeeker[i].Name) < 0 then
2020 cbxTargetGhost.Items.Add(SakuraSeeker[i].Name);
2023 cbxTargetGhost.ItemIndex := 0;
2024 if (Length(Selected) > 0) and (Selected <> '(CH
\90\84\8f§)') then begin
2025 with cbxTargetGhost do begin
2026 for i := 1 to Items.Count-1 do begin
2027 if Items[i] = Selected then
2030 //
\83S
\81[
\83X
\83g
\82ª
\93Ë
\91R
\91¶
\8dÝ
\82µ
\82È
\82
\82È
\82Á
\82½
\8fê
\8d\87\91Î
\8dô
2031 if ItemIndex = 0 then begin
2032 Items.Add(Selected);
2033 ItemIndex := Items.Count - 1;
2041 procedure TfrmSender.HTTPFailure(Sender: TObject);
2045 ShowHintLabel('SSTP Bottle
\83T
\81[
\83o
\82Æ
\82Ì
\90Ú
\91±
\82É
\8e¸
\94s
\82µ
\82Ü
\82µ
\82½', WarningColor);
2046 ShowMessage((Sender as THTTPDownloadThread).LastErrorMessage);
2047 Connecting := false;
2050 procedure TfrmSender.actPrevGhostExecute(Sender: TObject);
2053 SakuraSeeker.BeginDetect;
2055 i := cbxTargetGhost.ItemIndex;
2057 if i <= -1 then i := cbxTargetGhost.Items.Count-1;
2058 cbxTargetGhost.ItemIndex := i;
2059 cbxTargetGhostChange(self);
2062 procedure TfrmSender.actNextGhostExecute(Sender: TObject);
2065 SakuraSeeker.BeginDetect;
2067 i := cbxTargetGhost.ItemIndex;
2069 if i > cbxTargetGhost.Items.Count-1 then i := 0;
2070 cbxTargetGhost.ItemIndex := i;
2071 cbxTargetGhostChange(self);
2074 procedure TfrmSender.actResetGhostExecute(Sender: TObject);
2076 cbxTargetGhost.ItemIndex := 0; // (CH
\90\84\8f§)
\82É
\96ß
\82·
2077 if Visible then memScript.SetFocus;
2078 cbxTargetGhostChange(self);
2081 procedure TfrmSender.timDisconnectCheckTimerTimer(Sender: TObject);
2083 if (IdSlpp20.LastReadTimeInterval > BottleServerTimeOut) then begin
2085 frmLog.AddCurrentSystemLog('SYSTEM', 'SSTP Bottle
\83T
\81[
\83o
\82Æ
\82Ì
\90Ú
\91±
\82ª
\83^
\83C
\83\80\83A
\83E
\83g
\82µ
\82Ü
\82µ
\82½');
2086 if IdSlpp20.Connected then IdSlpp20.Disconnect;
2088 if not IdSlpp20.Connected then begin
2090 Slpp20Disconnect(self); //
\82È
\82º
\82©Disconnect
\83C
\83x
\83\93\83g
\82ª
\8bN
\82±
\82ç
\82¸
\82É
\90Ø
\92f
\82µ
\82½
\8fê
\8d\87
2092 //
\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
2093 //
\82½
\82¾
\82µ
\89ñ
\90\94\90§
\8cÀ
\82 \82è
2099 procedure TfrmSender.RetryBeginConnect;
2101 if FBeginConnectFailCount < 3 then begin
2102 //
\90Ø
\92f
\82³
\82ê
\82Ä
\82¢
\82ê
\82Î
\8dÄ
\90Ú
\91±
2103 FAutoAddAfterGetChannel := true;
2105 end else if FBeginConnectFailCount = 3 then begin
2106 frmLog.AddCurrentSystemLog('SYSTEM', '
\8dÄ
\90Ú
\91±
\8e©
\93®
\83\8a\83g
\83\89\83C
\82ð
\92\86\8e~
\82µ
\82Ü
\82·');
2107 frmMessageBox.ShowMessage(
2108 'SSTP Bottle
\83T
\81[
\83o
\82É
\90Ú
\91±
\82Å
\82«
\82Ü
\82¹
\82ñ
\81B'#13#10+
2109 '
\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+
2110 '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'
2112 Inc(FBeginConnectFailCount);
2116 procedure TfrmSender.actDownloadLogExecute(Sender: TObject);
2117 var BottleLog: TBottleLogList;
2119 Cond: TBottleLogDownloadCondition;
2121 function TimeStr(Mins: integer): String;
2122 var day, hour, min: integer;
2124 day := Mins div (60 * 24);
2125 hour := (Mins div 60) mod 24;
2128 if day > 0 then Result := Result + Format('%d
\93ú', [day]);
2129 if hour > 0 then Result := Result + Format('%d
\8e\9e\8aÔ', [hour]);
2130 if (min > 0) or (Result = '') then Result := Result + Format('%d
\95ª', [min]);
2133 Application.CreateForm(TfrmLogDownload, frmLogDownload);
2135 if frmLogDownload.Execute then begin
2136 with frmLogDownload do begin
2137 if IsRange then begin
2138 if CompareDate(DateLo, DateHi) = 0 then
2139 Title := FormatDateTime('yy/mm/dd', DateLo)
2141 Title := FormatDateTime('yy/mm/dd', DateLo) + ' - ' + FormatdateTime('yy/mm/dd', DateHi);
2143 Title := Format('
\89ß
\8b\8e%s', [TimeStr(RecentCount)]);
2145 if Channel <> '' then Title := Title + '(' + Channel + ')';
2147 BottleLog := TBottleLogList.Create(Title);
2149 BottleLog.OnLoaded := frmLog.LogLoaded;
2150 BottleLog.OnLoadFailure := frmLog.LogLoadFailure;
2151 BottleLog.OnLoadWork := frmLog.LogLoadWork;
2152 with frmLogDownload do begin
2153 Cond.IsRange := IsRange;
2154 Cond.RecentCount := RecentCount;
2155 Cond.DateLo := DateLo;
2156 Cond.DateHi := DateHi;
2157 Cond.MinVote := MinVote;
2158 Cond.MinAgree := MinAgree;
2159 Cond.Channel := Channel;
2161 BottleLog.LoadFromWeb(Cond);
2163 FreeAndNil(BottleLog);
2165 if BottleLog <> nil then begin
2166 NewIndex := frmLog.BottleLogList.Add(BottleLog);
2168 frmLog.tabBottleLog.TabIndex := NewIndex;
2169 frmLog.UpdateWindow;
2173 frmLogDownload.Release;
2177 function TfrmSender.BuildMenuConditionCheck(const IfGhost,
2178 Ghost: String): boolean;
2185 Cond := Token(IfGhost, ',', i);
2186 if Cond <> '' then begin
2187 if Cond[1] = '!' then begin
2188 Cond := Copy(Cond, 2, High(integer));
2189 if Cond = Ghost then Result := false;
2191 if Cond <> Ghost then Result := false;
2198 procedure TfrmSender.BuildMenu(Root: TMenuItem; Event: TNotifyEvent; Simple: boolean);
2199 var i, j, k, count: integer;
2200 ConstData: TScriptConst;
2201 Menu1, Menu2: TMenuItem;
2204 // Simple = false
\82Ì
\8fê
\8d\87\82Í
\83\81\83j
\83\85\81[
\82ð
\8a®
\91S
\82É
\8dÄ
\8d\
\92z
\82·
\82é
\81B
2205 // 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
2206 if cbxTargetGhost.ItemIndex > 0 then Ghost := cbxTargetGhost.Text
2207 else if FNowChannel <> '' then Ghost := ChannelList.Channel[FNowChannel].Ghost;
2209 //
\8aù
\91¶
\82Ì
\83\81\83j
\83\85\81[
\8dí
\8f\9c
2210 if Simple then begin
2211 // IfGhost
\8fð
\8c\8f\95t
\82«
\83\81\83j
\83\85\81[
\82Ì
\82Ý
\8dí
\8f\9c
2212 for i := Root.Count-1 downto 0 do begin
2213 if ScriptConstList.GetMenuByID(Root.Items[i].Tag).IfGhost <> '' then
2217 //
\91S
\95\94\8dí
\8f\9c
2218 for i := Root.Count-1 downto 0 do begin
2224 for i := 0 to ScriptConstList.Count-1 do begin
2225 for j := 0 to ScriptConstList[i].Count-1 do begin
2226 //
\83S
\81[
\83X
\83g
\88á
\82¢
\82Ì
\8fê
\8d\87\82Í
\83X
\83L
\83b
\83v
2227 if not BuildMenuConditionCheck(ScriptConstList[i][j].IfGhost, Ghost) then Continue;
2229 // 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
2230 if Simple and (count < Root.Count) then
2231 if (Root.Items[count].Tag = ScriptConstList[i][j].ID) then begin
2235 Menu1 := TMenuItem.Create(Root);
2236 Menu1.Caption := ScriptConstList[i][j].Caption;
2237 Menu1.Hint := ScriptConstList[i][j].Caption;
2238 Menu1.AutoHotkeys := maManual;
2239 Menu1.Tag := ScriptConstList[i][j].ID;
2241 if not Simple then begin
2244 if count < Root.Count-1 then
2245 Root.Insert(count, Menu1)
2250 Menu1.Enabled := ScriptConstList[i][j].Count > 0;
2251 for k := 0 to ScriptConstList[i][j].Count-1 do begin
2252 ConstData := ScriptConstList[i][j][k];
2253 Menu2 := TMenuItem.Create(Root);
2254 Menu2.Caption := ConstData.Caption;
2255 Menu2.Hint := ConstData.ConstText;
2256 // if ConstData.ShortCut <> 0 then Menu2.Hint := Menu2.Hint
2257 // + ' (' + ShortCutToText(ConstData.ShortCut) + ')';
2258 //
\83T
\81[
\83t
\83B
\83X
\83v
\83\8c\83r
\83\85\81[
\8eÀ
\8c»
\82Ì
\82½
\82ß
\8fã
\8dí
\8f\9c
2259 Menu2.ShortCut := ConstData.ShortCut;
2260 Menu2.OnClick := Event;
2261 Menu2.AutoHotkeys := maManual;
2262 Menu2.Tag := ConstData.ID;
2263 if (k mod 15 = 0) and (k > 0) then Menu2.Break := mbBarBreak;
2270 procedure TfrmSender.cbxTargetGhostChange(Sender: TObject);
2272 ConstructMenu(true);
2275 procedure TfrmSender.PlaySound(const FileName: String);
2277 if Pref.SilentWhenHidden and not Application.ShowMainForm then Exit;
2279 MediaPlayer.FileName := FileName;
2283 on E: EMCIDeviceError do begin
2284 ShowMessage('
\83T
\83E
\83\93\83h
\8dÄ
\90¶
\83G
\83\89\81[:'#13#10 + FileName + #13#10#13#10 + E.Message);
2289 procedure TfrmSender.actFMOExplorerExecute(Sender: TObject);
2291 frmFMOExplorer.Show;
2294 procedure TfrmSender.SaveChainRuleList;
2295 var Str: TStringList;
2297 Str := TStringList.Create;
2299 Str.Text := ComponentToString(BottleChainRuleList);
2300 Str.SaveToFile(ExtractFileDir(Application.ExeName)+'\rule.txt');
2306 procedure TfrmSender.BottleSstpResendEnd(Sender: TObject; MID: String);
2308 frmLog.SetBottleState(MID, lsOpened);
2311 procedure TfrmSender.BottleSstpResendTrying(Sender: TObject; MID: String);
2313 frmLog.SetBottleState(MID, lsPlaying);
2316 procedure TfrmSender.actInsertCueExecute(Sender: TObject);
2317 var InsertItem: TLogItem;
2318 i, errCount: integer;
2319 Log: TBottleLogList;
2321 if FBottleSstp.CueCount > 0 then begin
2322 if MessageDlg(Format('
\8c»
\8dÝ
\8dÄ
\91\97\83L
\83\85\81[
\82É
\93ü
\82Á
\82Ä
\82¢
\82é%d
\8c\8f\82Ì
\96¢
\94z
\91\97\83{
\83g
\83\8b\82ð
\83N
\83\8a\83A
\82µ
\82Ä
\81A'+
2323 '
\83\8d\83O
\83E
\83B
\83\93\83h
\83E
\82É
\82 \82é
\83{
\83g
\83\8b\82ð
\98A
\91±
\8dÄ
\90¶
\82µ
\82Ü
\82·
\81B'#13#10+
2324 '
\90V
\92\85\83\81\83b
\83Z
\81[
\83W
\82Í
\82»
\82Ì
\8cã
\82É
\8dÄ
\90¶
\82³
\82ê
\82Ü
\82·
\81B', [FBottleSstp.CueCount]),
2325 mtWarning, mbOkCancel, 0) = mrCancel then Exit;
2328 frmLog.AllBottleOpened;
2329 if frmLog.lvwLog.Selected = nil then Exit;
2330 Log := frmLog.SelectedBottleLog;
2331 if Log = nil then Exit;
2332 FBottleSSTP.OnResendCountChange := nil;
2334 for i := frmLog.lvwLog.Selected.Index downto 0 do begin
2335 if (Log[i] as TLogItem).LogType <> ltBottle then Continue;
2336 InsertItem := TLogItem.Create(Log[i] as TLogItem);
2338 InsertItem.Script := ScriptTransForSSTP(InsertItem.Script);
2339 if InsertItem.Script = '' then begin
2340 raise Exception.Create('Script syntax error');
2342 if InsertItem.Ghost = '' then begin
2343 if ChannelList.Channel[InsertItem.Channel] <> nil then
2344 InsertItem.Ghost := ChannelList.Channel[InsertItem.Channel].Ghost;
2346 FBottleSSTP.Push(InsertItem);
2347 frmLog.SetBottleState(InsertItem.MID, lsUnopened);
2353 if errCount > 0 then
2354 ShowMessage(Format('%d
\8c\8f\82Ì
\83{
\83g
\83\8b\82É
\96â
\91è
\82ª
\82 \82Á
\82½
\82½
\82ß
\8dÄ
\90¶
\82Å
\82«
\82Ü
\82¹
\82ñ
\81B', [errCount]));
2355 FBottleSSTP.OnResendCountChange := BottleSstpResendCountChange;
2356 BottleSstpResendCountChange(self);
2359 function TfrmSender.ScriptTransForSSTP(const Script: String): String;
2360 var TransOpt: TScriptTransOptions;
2363 if Pref.NoTransURL then
2364 TransOpt := [toConvertURL, toNoChoice, toWaitScriptEnd]
2366 TransOpt := [toConvertURL, toWaitScriptEnd];
2367 if Pref.IgnoreFrequentYenS then TransOpt := TransOpt + [toIgnoreFrequentYenS];
2368 if Pref.FixMessySurface then TransOpt := TransOpt + [toFixMessySurface];
2369 if Pref.HUTagTo01Tag then TransOpt := TransOpt + [toHUTagTo01Tag];
2371 Err := DoTrans(Result, TransOpt);
2372 if Length(Err) > 0 then Result := '';
2375 procedure TfrmSender.FormResize(Sender: TObject);
2378 //
\83G
\83f
\83B
\83^
\81[
\95\94\95ª
\82Ì
\83\8f\81[
\83h
\83\89\83b
\83v
\95\9d\82ð
\92²
\90®
\82·
\82é
2379 if memScript.ColWidth <> 0 then
2383 w := Width - LeftMargin - ColWidth div 2;
2384 if ScrollBars in [ssVertical, ssBoth] then
2385 w := w - GetSystemMetrics(SM_CYVSCROLL);
2386 WrapOption.WrapByte := w div ColWidth;
2391 procedure TfrmSender.actCopyExecute(Sender: TObject);
2393 memScript.CopyToClipboard;
2396 procedure TfrmSender.actPasteExecute(Sender: TObject);
2398 memScript.PasteFromClipboard;
2401 procedure TfrmSender.actCutExecute(Sender: TObject);
2403 memScript.CutToClipboard;
2406 procedure TfrmSender.actSelectAllExecute(Sender: TObject);
2408 memScript.SelectAll;
2411 function TfrmSender.IsSurfaceTag(const Script: String;
2412 var ID: integer): boolean;
2415 if SsParser.Match(Script, '\s%d') = 3 then
2418 ID := Ord(Script[3]) - Ord('0')
2420 else if (Length(Script) > 0) and (SsParser.Match(Script, '\s[%D]') = Length(Script)) then
2423 ID := StrToIntDef(SsParser.GetParam(Script, 1), 0);
2427 procedure TfrmSender.memScriptMouseMove(Sender: TObject;
2428 Shift: TShiftState; X, Y: Integer);
2432 //
\95Ò
\8fW
\83E
\83B
\83\93\83h
\83E
\82Å
\83}
\83E
\83X
\83|
\83C
\83\93\83g
\82·
\82é
\82Æ
\83T
\81[
\83t
\83B
\83X
\83v
\83\8c\83r
\83\85\81[
2433 if not Pref.SurfacePreviewOnScriptPoint then
2435 token := memScript.TokenStringFromPos(Point(X, Y));
2436 if IsSurfaceTag(token, id) then
2438 DoSurfacePreview(id);
2441 frmSurfacePreview.HideAway;
2445 procedure TfrmSender.DoSurfacePreview(Surface: integer);
2450 if cbxTargetGhost.ItemIndex > 0 then
2451 ghost := cbxTargetGhost.Text
2452 else if FNowChannel <> '' then
2453 ghost := ChannelList.Channel[FNowChannel].Ghost;
2455 //
\93ñ
\8fd
\95\
\8e¦
\82Ì
\97}
\90§
2456 if (FVisiblePreviewGhost = Ghost) and (FVisiblePreviewSurface = Surface) and
2457 not (frmSurfacePreview.IsHidden) then
2464 Bmp := TBitmap.Create;
2466 if Spps.TryGetImage(ghost, Surface, Bmp) then
2469 frmSurfacePreview.ShowPreview(Bmp, Self.Left-Bmp.Width, CPos.Y);
2470 FVisiblePreviewGhost := Ghost;
2471 FVisiblePreviewSurface := Surface;