книги хакеры / журнал хакер / 114_Optimized
.pdf
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
C |
E |
|
|
|||
|
|
X |
|
|
|
|
|||
|
- |
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
NOW! |
o |
|||
>> codingto BUY |
|
|
|||||||
|
|
|
|
|
|||||
w Click |
|
|
|
|
|
m |
|||
w |
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
g |
|
|
|
|
|
|
df |
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
PSPLINKinAction
необходимыхдлякомпиляциипрограмм.Скачавсhttp://ps2dev.org/psp/Tools/ Toolchainилизабравсдиска,егонадобудетразархивироватьв%cygwin_ install_folder%/home/%windows_username%(еслитакойпапкинет
итебестрашноеесоздавать—запустисигвинионапоявится).Откройшелл сигвинаиперейдивдиректориюстулчайном(cd psptoolchain),после чегозапусти ./toolchain-sudo.sh.Онскачаетиустановитещенесколько нужныхпрограмм.Этозайметнемалоевремя.Послеустановкиоткройфайл
%cygwin_install_folder%/cygwin.batизамениегосодержимоена:
@echo off
C:
chdir C:\cygwin\bin
set path=%path%;C:/cygwin/usr/local/pspdev/bin set PSPSDK=C:/cygwin/usr/local/pspdev
bash --login -i
ТакмыустанавливаемпеременныесредыпередзапускомCygwin-a—что- былегчебылокомпилировать(незабудьпоменятьпутивфайле,еслиты ставилсигвинневC:\cygwin\).Все!Снастройкой,похоже,поконченои можнописатьпрограмму.
Перезапусти сигвин, чтобы он узнал о переменных, и создай папку projects(mkdir projects). Перейди в нее (cd projects), создай папку helloworld(ха-ха, а ты чего хотел? с этого все всегда начинается) и перенесись туда. Теперь нужно открыть какой-нибудь текстовый редактор (или даже IDE), создать в нем файл и сохранить его в нашу папку helloworldпод именем main.cpp. Лично я советую Notepad++, но ты можешь использовать что угодно — хоть Visual Studio, хоть блокнот. Файл должен содержать вот такой код:
Самыйпервыйкод
#include <pspkernel.h> #include <pspdebug.h>
PSP_MODULE_INFO("Hello World", 0, 1, 1);
int ExitCallback(int Arg1, int Arg2, void *Common) { sceKernelExitGame();
return 0;
}
int CallbackThread(SceSize Args, void *Argp) { int CallbackId;
CallbackId = sceKernelCreateCallback ("Exit Callback", ExitCallback, NULL);
sceKernelRegisterExitCallback(CallbackId);
sceKernelSleepThreadCB(); return 0;
}
int SetupCallbacks(void) { int ThreadId = 0;
Портизвестногорогаликавыполненбезглючно.Обративниманиенаклавиатуру
ThreadId = sceKernelCreateThread ("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
if (ThreadId >= 0) sceKernelStartThread(ThreadId, 0, 0);
return ThreadId;
}
int main(int argc, char ** argv) { pspDebugScreenInit(); SetupCallbacks();
while(1){
pspDebugScreenPrintf("Hello ][AKEP!\n"); sceDisplayWaitVblankStart();
}
sceKernelSleepThread(); return 0;
}
Компилируют(ой,собирают)программувGCCобычноспомощью
Makefile.Создаемиего—втойжепапке:
ПервоначальныйMakefile
TARGET = hello
OBJS = main.o
CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)
EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Hello World
PSPSDK=$(shell psp-config --pspsdk-path) include $(PSPSDK)/lib/build.mak
Вернисьвсигвиновскийшелл.Перейдивпапкуhelloworld,еслиты вдругоказалсяневней,и,затаивдыхание,набериmake.Внезапновпапке появитсяфайлсмилымназваниемEBOOT.PBP.Подключиприставкук компьютеруисоздайнакарточкепапку:\PSP\GAME150\HelloWorld\, послечегоскопируйполученныйфайлтуда.Запустивпрограмму,тыувидишьнаэкранесотнизаветныхстрочек!Илинеувидишь,тогдапридется посидетьипоразмышлять,что,собственно,произошлоикактеперьбыть. Затемможноиразобратьсяскодом.Взаголовкесодержатсядванеобходимыхинклюда,адалееидетнебольшойзаголовокнамашинномкоде.Как нистранно,pspDebugScreenInit()подготавливаетэкран.Приставка Debugзначит,чтомыпереводимэкранврежимотладки (текстовыйрежим).
ВфункцииSetupCallbacks()мысоздаемпоток(CallbackThread()),
вкоторомприпомощиsceKernelCreateCallback() создаетсякаллбек
(ExitCallback()).ПослечегочерезsceKernelRegisterExitCallbac k() регистрируемегокаккаллбеквыходаизприложения(еслитакогокалл-
xàêåð 06 /114/ 08 |
089 |
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
E |
|
|
||||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
NOW! |
o |
||||
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
||||
w Click |
to BUY |
|
>> coding |
|||||||
|
|
|
|
|
|
m |
||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
вызоваsceCtrlReadBufferPositiveбылнажаткружок. |
|
|
|
|
|
|
Чтож,этихзнанийвполнехватает,чтобынаписатьновуюпрограмму: |
|
|
|
|
|
|
|
|
|
|
|
|
|
Main()второго«хилловорлда» |
|
|
|
|
|
|
int main(int argc, char ** argv) { |
|
|
|
|
|
|
pspDebugScreenInit(); |
|
|
|
|
|
|
SetupCallbacks(); |
|
|
|
|
|
|
sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG); |
|
|
|
|
|
|
SceCtrlData pad; |
|
|
|
|
|
|
while(1) { |
|
|
|
|
|
|
|
|
|
Ода!Онареагирует! |
|
CtrlReadBufferPositive(&pad, 1); |
|
||
|
|
|
|
|
if (pad.Buttons & PSP_CTRL_CIRCLE) { |
|
|
|
|
|
|
if (pad.Buttons & PSP_CTRL_LTRIGGER) |
|
|
беканебудет,тоизприложениявыйтибезребутаипрочейнеприятнойерун- |
|
pspDebugScreenPrintf("OOOOOOOOOO"); |
|
||
|
дынеполучится).СамкаллбэквызываетсяпринажатиинакнопкуHOME |
|
else pspDebugScreenPrintf("oooooooooo"); |
|
||
|
ивыборе«ДА»—вответнавопрос,нехотимлимывыйти?Теперьможно |
|
} |
|
||
|
переходитьксодержательнойчастипрограммы—выводунаэкранстроки |
|
if (pad.Buttons & PSP_CTRL_CROSS) { |
|
||
|
«Hello ][AKEP!»посредствомpspDebugScreenPrintf.Какиследует |
|
if (pad.Buttons & PSP_CTRL_RTRIGGER) |
|
||
|
изназвания,этафункциянаследуетаргументыродного,сишногоprintf |
|
pspDebugScreenPrintf("XXXXXXXXXX"); |
|
||
|
—кодповедетсебя,какидолжен:pspDebugScreenPrintf(" %i ", |
|
else pspDebugScreenPrintf("xxxxxxxxxx"); |
|
||
|
666).Кириллицу,кстати,функцияоченьнелюбит.ЗагадочнаяsceDispla |
|
} |
|
||
|
yWaitVblankStart()синхронизируетэкран,заоднонедаваяпрограмме |
|
pspDebugScreenPrintf("\nJOYSTICK: %i, %i;" |
|
||
|
зависать—еслиубрать,топриложениеможетперестатьреагироватьна |
|
" FRAME: %i\n", pad.Lx, pad.Ly, pad.TimeStamp); |
|
||
|
кнопкуHOMEилизависнутьпризавершениипрограммы. |
|
sceDisplayWaitVblankStart(); |
|
||
|
|
|
|
|
} |
|
|
|
Жмем на кнопки |
|
sceKernelSleepThread(); |
|
|
|
|
|
|
|||
|
|
|
|
|||
|
Самыйгениальныйгеймдевелоперврядлиразработаетигру,неполучаю- |
|
return 0; |
|
||
|
щуюкомандотпользователя,апосемунампридетсякак-тополучатьдоступ |
|
} |
|
||
|
ксостояниюкнопокиджойстика.Заэтоотвечаетодна-единственная |
|
|
|
||
|
волшебнаяфункцияsceCtrlReadBufferPositive(&pad, 1). |
|
Достаточно простая программа. Она все время выводит номер |
|||
|
Здесьpad—заранееопределеннаятобойпеременнаятипаSceCtrlData. |
|
текущего фрейма и координаты положения джойстика, а также, |
|||
|
Функция(описаннаявфайлеpspctrl.h—незабудьпополнитьсписок |
|
если нажат нолик или крестик, выведет буквы X или О (большие |
|||
|
инклудов!)заполняетэтуструктурузначениями.Они,всвоюочередь,зави- |
|
или маленькие, в зависимости от нажатых шифтов). Не проблема |
|||
|
|
|
|
|
|
|
|
сятоттекущегосостоянияконтроллера,устанавливающегосяприпомощи |
|
переделать код так, чтобы выводилось больше информации, да и |
|||
|
функцииsceCtrlSetSamplingMode.Всегосостоянийдва:PSP_CTRL_ |
|
если приложить немного усилий — можно сделать, что угодно — от |
|||
|
MODE_ANALOG—привычноенамсостояниеиPSP_CTRL_MODE_DIGITAL |
|
крестиков-ноликов до солидной rogue-like игрушки (ну, почти «что |
|||
|
(выставленопоумолчанию)—безджойстика.Такимобразом,еслимы |
|
угодно»). |
|||
|
хотимиспользоватьвпрограммеджойстик,намнадобудетвызватьsceCtr |
|
Нопростойбелыйтекстначерномфоневыглядитнеоченьсолидно.Чтобы |
|||
|
lSetSamplingMode(PSP_CTRL_MODE_ANALOG). |
|
втвоихсупермегакрестиках-ноликахбыланимированныйкрасочный |
|||
|
ВструктуреSceCtrlData(послезаполнениявышеуказаннойфункции) |
|
аски-арт,нехватаетодного—цветов.Онизадаютсяприпомощи32 битно- |
|||
|
будутопределенычетырезначения:TimeStamp—количествофреймовот |
|
гопредставленияRGB,идляпереводаиспользуетсявоттакоймакрос: |
|||
|
началапрограммы;Buttons—битоваямаскакнопок;Lx,Ly—координаты |
|
|
|
||
|
джойстика,меняющиесяот0до255.Стандартноеположениеджойстика |
|
#define RGB(r,g,b) ((u32)((byte)(r)|((byte)(g) |
|
||
|
—примерно128:128,однакоиз-зачувствительностиотпущенныйджойс- |
|
<< 8)|((byte)(b) << 16))) |
|
||
|
тиквполнеможетоказатьсявкоординатахвроде112:139—всегда стоит |
|
|
|
||
|
делатьнаэтопоправку.Положениекаждойкнопкиопределяетсяприпомо- |
|
Так, соответственно, будет представлен зеленый: RGB(0, 255, 0). |
|||
|
щи (pad.Buttons & button_id),гдеbutton_id—однаизконстант: |
|
Цвет фона и текста задаются при помощи pspDebugScreenSetBackC |
|||
|
|
|
|
|
olor(u32 color) и pspDebugScreenSetTextColor(u32 color): |
|
|
|
PSP_CTRL_SELECT — кнопка SELECT |
|
pspDebugScreenSetBackColor(RGB(255, 0, 0)) — красный. |
||
|
|
PSP_CTRL_START — кнопка START |
|
Если ты программировал для компьютерного текстового режима, то |
||
|
|
PSP_CTRL_UP — стрелка вверх |
|
помнишь, что после установки цвета фон будет меняться только у све- |
||
|
|
PSP_CTRL_RIGHT — стрелка вправо |
|
женапечатанных символов. Также и в этом случае. Поэтому для смены |
||
|
|
PSP_CTRL_DOWN — стрелка вниз |
|
фона экрана придется пробежаться по всему экрану в цикле (обойти 32 |
||
|
|
PSP_CTRL_LEFT — стрелка влево |
|
строки и 68 столбцов). |
||
|
|
PSP_CTRL_LTRIGGER — левый шифт |
|
Чтобы поставить символ в произвольную точку экрана, можно воспользо- |
||
|
|
PSP_CTRL_RTRIGGER — правый шифт |
|
ваться функцией pspDebugScreenPutChar(int x, int y, u32 color, |
||
|
|
PSP_CTRL_TRIANGLE — треугольник |
|
u8 ch), где xи y— координаты, color— цвет символа, а ch— сам сим- |
||
|
|
PSP_CTRL_CIRCLE — круг |
|
вол. Например, pspDebugScreenPutChar(99, 120, RGB(0,0,255), |
||
|
|
PSP_CTRL_CROSS — крестик |
|
‘Y’)установит синюю Yв точке с координатами 99 и 120. Узнать, в какую |
||
|
|
PSP_CTRL_SQUARE — квадратик |
|
точку ты попал после таких прыжков, помогут pspDebugScreenGetX и |
||
|
Например,if (pad.Buttons & PSP_CTRL_CIRCLE) pspDebugScre |
|
pspDebugScreenGetY. Ну а pspDebugScreenClearочистит экран (кста- |
|||
|
|
ти, вызов этой функции, согласно документации, возвращает цвет фона в |
||||
|
enPrintf("O") выполнитсялишьвслучае,есливмоментпоследнего |
|
исходное значение — черное). |
090 |
xàêåð 06 /114/ 08 |
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
>>
svn co svn://svn.ps2dev.org/psp/trunk/psplink
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
coding |
|
BUY |
|
|
||||||
to |
|
|
|
|
|
|||||
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
Волшебнаяклавиатура
Итак,тысвидомэнтузиастаначалписатьпрограмму,ипонял, чтобезобращенияпоимени-отчествуигратеряетсвоюсупер- атмосферу.Какбыть?Программироватьсамомусистемуввода? Славакомпьютернымбогам,нет.ВSDKвходятфункциидлявызоваэкраннойклавиатурыивызыватьеенеожиданнопросто.
Сначаланадоподключитьзаголовочныйфайл<pspdebugkb. h>идобавитьвMakefileстроку,отвечающуюзаподключениедополнительныхбиблиотек:
LIBS = -lpspdebugkb
Послеэтогодостаточнообъявитьстрокуипередатьеефунк цииpspDebugKbInit.Позавершениивводастрокабудет изменена:
char str[20] = "X][X"; pspDebugKbInit(str);
pspDebugScreenPrintf("%s", str); // выводим!
Такможнооблегчитьвводстрок,неотвлекаясьнаунылый кодингинтерфейса.Конечно,проюзабилититутлучшеине заикаться,нодляtextmode—оченьдаженичего.
Кстати,естьдругаяреализацияклавиатуры,используемая впортенаPSProgue-likeигрушкеToME.Еслизажатьвигре
треугольник,наэкранепоявитсясписоккнопок,средикоторых стрелочкамиможновыбратьбукву.Правыйшифт—аналогком- пьютерногошифта,левый—Ctrl.Послевыбораможноотпустить треугольник,ииграотреагируетнабукву.Врогаликахтакудобнее,посколькуукаждойбуквывсочетаниискаждойизуправляющихкнопок(ctrlиshift)естьсвоесобственноедействие.
Скриншоты и отладка
Для удобной отладки при помощи самого обычного gdb приставку, разумеется, придется подключить к компьютеру. Единственный «легальный» способ соединения ПК и PSP
— через USB и специальный пункт в меню настройки, но его невозможно использовать одновременно с игрой. На помощь приходит PSPLINK — он не просто предоставит нам типичный шелл с возможностями отлаживать программы, делать скриншоты экрана или просто бродить по директориям, но и позволит провести связь через Wi-Fi, что избавит от необходимости запутываться в проводах.
Ясное дело, для этого нам понадобится точка доступа. Кстати, у меня не получилось приконнектиться через PSPLINK к запароленному Wi-Fi, поэтому придется на время снять защиту (это не так уж и страшно, — за несколько часов, на которые я убираю пароль, еще никто не успел насладиться безлимитным интернетом за мой счет. В крайнем случае можно настроить фильтр клиентов по MAC-адресу). Итак, после того, как настроил точку доступа, зайди в настройки сети приставки и научи ее соединяться со своей сетью без ввода пароля. И вернись за клавиатуру: открой Cygwin и слей PSPLINK из репозитория:
Потомперейдивдиректориюpsplink(cd psplink), собериего(makerelease)изайдиснимвдиректорию(вмоем случае—C:\cygwin\home\admin\psplink\)черезсвой файл-менеджер.Впапкеreleaseнаходятсятриподпапкис программамидляприставки—явыбралv1.5.Еслионанеза- пустится,попробуйдведругие(v1.0иv1.5_nocorrupt).Скопируй содержимое(двепапки,psplinkиpsplink%)наприставку,в каталог :/PSP/GAME150/наPSP.Послечегооткройфайл:/ PSP/GAME150/psplink/psplink.iniиперенастрой(буду даватьлишьтестрочки,значениявкоторыхнадозаменить):
info
Прочти psplink_
manual.pdfдля более подробной информации о возмож-
ностях PSPLINK.
usbmass=0
sioshell=0
kprintf=0
wifi=1
wifishell=1
Незабудьраскомментировать(убрать#)пятьпоследнихстрок,
озаглавленных«load the modules for networking».
ТеперьможешьотключатьUSB-соединениеискачиватьPuTTy илиPuTTyTel(еслиутебяегоещенет)—сhttp://www.chiark. greenend.org.uk/~sgtatham/putty/download.html,азатемзапус-
катьPSPLINK.Подождинесколькосекунд,и,когданаэкране появится«connection state 4 of 4»,запускайPuTTy.В
качествеIP-адресаукажипоявившийсянаэкране;порт:10000; типсоединения:Telnet.Сохранисессию,чтобынепришлось всякийразвводитьзаново,иподключайся.Появитсяконсоль. Первуюкомандууменяонанераспознавалаиз-застранных глюков,ноначинаясовторой,всешлоуспешно.
Всезапускаемыепрограммыидутнаприставкепараллельно сработойвконсолискомпа.Тоесть,запустивпрограмму, консольнезакроетсяинеостановится,итысможешьдампить памятьиделатьскрины.Командытутвполнезнакомые(полныйихсписок,кстати,тынайдешьвpsplink_manual.pdf в
папкесpsplink-ом):
•ls—листингфайлов
•cd—сменитьдиректорию
•exit—возвратвVSH(такназывается«главноеменю»PSP) scrshot screen.bmp(илиss screen.bmp)—скриншот экранавформатеBMPвуказанныйвпервомаргументефайл help—вывестинебольшуюсправку(еслипередатьейназва- ниекоманды—выдастсправкупоней).
Программызапускаютсятак:./EBOOT.pbp(предварительно нужносменитьдиректориюнату,гденаходитсяисполняемый файл).Прямопоходувыполненияможноделатьдамппамяти наэкран(memdump),выводитьразнуюинформациюопотоках икаллбекахит.п.,ноудобнееиспользоватьотладчик—отом, какегоиспользовать,рассказановмануале.
В заключение
Наэтомвсе.Еслитематебепонравится(амывсегдаждем твоихотзывовпосредствомвсехизвестныхнаукесредств связи,включаяинтернет,телеграфиотправкунарочным),тов следующихстатьяхярасскажуовыводенаэкранпростейшей графики,картинок,работесоспрайтами.Атакжеостановлюсь подробнеенаархитектурепроцессораиотладке(которая,кста- ти,надостаточновысокомуровне)инаработесWi-Fi.PSPне такаяпростаяитупаясистема,какпоройкажется.И,возможно, еслизловещаякорпорацияSonyпересмотритсвоюполитику поотношениюкинди-девелоперам,программированиедля приставокможетоказатьсявесьмаприбыльнымзанятием.
Вкачестве«домашнегозадания»попробуйсделатькрестикинолики.Недумаю,чтоэтобудетжуткосложнымзанятием,зато достаточноинтересновпланереальногоопыта.z
dvd
На компакт-диске лежат исходные коды программ,написанных мной для этой статьи, а также инструменты, упомянутые в статье.
links
Интересную информацию и полезные форумы (на английском языке) можно найти на сайтах http://ps2dev. org/psp/ и http://www. psp-programming. com/.
xàêåð 06 /114/ 08 |
091 |
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
C |
E |
|
|
|
||||
|
|
X |
|
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
r |
|
||
P |
|
|
|
|
NOW! |
o |
|
||||
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
|
||||
w Click |
to BUY |
|
>> coding |
|
|||||||
|
|
|
|
|
|
m |
|
||||
w |
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
|
. |
|
|
|
|
|
.c |
|
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
|
df |
|
|
n |
e |
|
|
||
|
|
|
|
-xcha |
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
Николай Байбородин
/ baiborodin@gmail.com /
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
AdSense
подконтролем
Мониторинг AdSense аккаунта через Vista Sidebar
Оптимизаторы могут ставить перед собой разные цели — но, в большинстве случаев, это борьба за презренный металл. Google AdSense — один из наиболее лакомых источников обогащения. Уверен, ты так бы сидел, не отрываясь, смотря на то, как капают лавандосы на адсеновский счет. Нет проблем
— сегодня мы напишем удобный AdSense монитор!
Анатомия гаджета
Дляначаларазберемся,какпишутсягаджеты.Изинструментовтебепонадобитсяблокноти…ипожалуй,все.ГаджетыпишутсянаHTMLиJavaScript. Такчто,еслитынезнакомсC#,ASP,LINQипрочимимоднымифишками
—расслабьсяиполучайудовольствие.Вотличиеотскриптов,запускаемых ввеб-браузере,гаджетыимеютгораздобольшевозможностейвзаимо- действиясоперационнойсистемой.Ещеоднаполезнаяфишка—возмож- ностьодновременногозапусканесколькихкопийодногоитогожегаджета. Например,можномониторитьодновременнонесколькоAdSenseаккаунтов. ЧтобысоздатьсвойVistaSidebarGadget,нужновыполнитьнесколькопростыхшагов,которыеосилитдажеСветкаБукина:
•создатькаталог,вкоторомбудутхранитьсявсефайлыгаджета;
•создатьHTML-страницу(этоосновабудущегогаджета);
•создатьXML-файл(манифест),содержащийописаниегаджетадляопера- ционнойсистемы.
Все.Гаджетготов.Дополнительноегоможнозащититьотизмененийи создатьудобныйинсталлятор(высшийпилотаж,доступныйтолькореально крутымхакерам).
Изприведенноговышеалгоритмавидно,чтогаджетсостоитиздвух файлов:ядрогаджета(HTML-файл)иманифествXML-формате.Манифест определяетсвойствагаджета—егоназвание,пиктограммуиописание. Файлманифеставсегдадолжениметьназваниеgadget.xml.Кромеэтих двух,всоставгаджетамогутвходитьидругиефайлы(HTML,JavaScript, графическиефайлы,CSS).
Создание HTML-каркаса
Чтобы сайдбар смог найти новый гаджет, тот должен оказаться в нужное время в нужном месте. А точнее, в каталоге: %userprofile%\
AppData\Local\Microsoft\Windows Sidebar\Gadgets.
Здесьрасположеныгаджетытекущегоюзера.Ещебываютгаджеты,общие длявсехпользователей,—длянихпредусмотренсвойкаталог.Перейдяв каталогсосвоимигаджетами,создайотдельныйподкаталогдлянового.
Названиеможешьпридуматьлюбое.Главное,чтобыонозаканчивалосьна «.gadget».Например,Adsense.gadget.Впринципе,можновсефайлы складыватьвкореньэтогокаталога,нохорошимтономсчитаетсяследующаявнутренняяфайловаяорганизациягаджета:каталогсграфическими объектами(images)инесколько(илиодин)каталоговсразнымиверсиями локализации(например,каталог«en-us»дляинтерфейсанаамериканс- команглийском—итакдалее).
ТеперьоткрывайсвойлюбимыйHTML-редакторипишиследующее:
<html>
<head>
<title>Adsense Monitor</title> </head>
<body style="width: 130; height: 67">
<div id="textEarnings">Ошибка инициализации.</div> <div id="textClicks"></div>
<div id="textImpressions"></div> </body>
</html>
Нукак?Яжеговорил,чтопосвоейприродегаджет—обычныйгипертексто- выйдокумент.Аэтозначит,чтобольшинствотехнологий,используемыхпри созданииHTML-страницдлябольшоговеба,доступныидлягаджето-пи- сателей.Вшаблонеясразуразместилслои,вкоторыхбудетотображаться
092 |
xàêåð 06 /114/ 08 |
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
C |
E |
|
|
|||
|
|
X |
|
|
|
|
|||
|
- |
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
NOW! |
o |
|||
>> codingto BUY |
|
|
|||||||
|
|
|
|
|
|||||
w Click |
|
|
|
|
|
m |
|||
w |
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
g |
|
|
|
|
|
|
df |
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
Коллекциятвоихгаджетов
информацияизAdSense-аккаунта.Обративниманиенапараметрstyle
—такмызадаемразмерыгаджета.Этотпараметрестьнечтоиное,как CSS-дескриптор.Следовательно,другиесредстваCSS-форматирования тожедоступны.И,кстатиговоря,могутбытьпримененыклюбомуэлементу (ктемжеслоям).
Теперьперейдемкфайлуманифеста.Создавайфайлgadget.xml:
<?xml version="1.0" encoding="utf-8" ?> <gadget>
<name>Adsense Monitor</name> <namespace>Adsense.Gadgets</namespace> <hosts>
<host name="sidebar">
<base type="HTML" apiVersion="1.0.0" src="adsense. html" />
<permissions>full</permissions> <platform minPlatformVersion="0.3" /> </host>
</hosts>
</gadget>
Файлнебольшойираскуритегодажепионер.Тег<namespace> определяетуникальноепространствоименпеременныхгаджета(чтобыневозникло конфликтасдругимигаджетами).Спомощьютега<host> можноуказать расположениегаджетапоумолчанию—насайдбареили«всвободномпла- вании».ЗдесьжетысообщаешьсистемеоверсииAPI,которуюсобираешь- сязаюзать,и,обязательно,—имяHTML-файла.Тег<permission> нужен, чтобыустановитьправадоступапользователякгаджету.
Естьещемногополезныхинеоченьтегов,которыетыможешьиспользоватьвфайлеманифеста.Например,теги<logo> и<icon> позволяют задатькартинкидляприданиягаджетубольшейгламурности.Подробнона нихостанавливатьсямынебудем.Вслучаенеобходимости—куриMSDN. Еслитвойгаджетлежитвправильномкаталоге(смотривыше),жмикнопку «плюс»насайдбаре.Вгалереегаджетовдолжнопоявитьсятвоетворение. Правда,пользыотнегоникакой.Ноэтомыскороисправим.
Есть у меня один могильничек…
Постепенноподбираемсякнашейцели.Еслитынезабыл—этовоз- можностьмониторитьAdSenseссайдбараВисты.Каквсепроисходитв браузере?Тызаходишьнасайтwww.google.com/adsenseивводишьлогин ипароль.Ежупонятно,чтобезбраузерапорядокдействийбудеттотже. Следовательно,где-тонужнохранитькаксамадрес,такипараметрытвоего аккаунта.Итакаявозможностьвгаджетахпредусмотрена.
ТыужезнаешьпроXML-иHTML-файлы,используемыевлюбомгаджете. Некоторыегаджеты,аименноте,которыетребуютпредварительнойна- стройки,включаютвсебяещеодинфайл—Settings.html.Есливкатало- гегаджетаестьтакойфайл,тонаярлыкегаджетапоявляетсяиконкаввиде гаечногоключа.Принажатиинанееоткроетсякакразэтотфайл,позволяющийнастроитьгаджетисохранитьегонастройкивреестресистемы.
Длясохранениянастроекиспользуетсяспециальныйметодизgadgets API—System.Gadget.write(параметр, значение).Длячтения сохраненныхпараметров—методSystem.Gadget.Settings. read(параметр).
AdSenseGadgetвразработке
Определимся,какиепараметрынужносохранить.Преждевсего,этологин навходвсистемуAdSenseисоответствующийпароль.Ябыпосоветовал добавитьпараметр,отвечающийзачастотуобновленияинформации.Можнопредусмотретьвозможностьизмененияфонаитекстагаджета,чтобы онорганичновписалсявоформлениетвоегорабочегостола.Ноэтоужеот лукавого,таккаккосновномуфункционалунеотносится.
Вкакоймоментчитатьизаписыватьпараметры?Тыможешьделатьэтопо своемуусмотрению,норазумнеепридерживатьсяпроверенныхвременем рекомендаций.Читатьпараметрылучшевсегопослеинициализациигаджета.Тоесть,сразу,кактолькоонготовкработе.Дляэтогофункциячтения параметроввешаетсянаобработчикdocument.onreadystatechange.После егосрабатываниянужнопроверить,вкакомсостояниинаходитсягаджет:
document.onreadystatechange = function()
{
if(document.readyState=="complete")
{
name = System.Gadget.Settings.read("Adsense_name"); password = System.Gadget.Settings.read(
"Adsense_password");
refresh = System.Gadget.Settings.read( "Adsense_refresh");
}
}
Естественно,переменные,вкоторыесчитываютсясохраненныепараметры,должныбытьзаранееобъявлены.Чтобытывпоследствиинегадал,с какимизначениямипараметроввданныймоментработаешь,неполенись тамжепрописатьзаполнениеполейдлявводаполученныхзначений.Сде-
лайчто-нибудьвродеdocument.setup.nameBox.value = name.
ТеперьвешайскриптнаобработчикSystem.Gadget. onSettingsClosing.Исохраняйнастройкивтомслучае,еслинажата соответствующаякнопка—event.Action.commit:
System.Gadget.onSettingsClosing = function(event)
{
if (event.closeAction == event.Action.commit)
{
System.Gadget.Settings.write("Adsense_name", document.setup.nameBox.value);
System.Gadget.Settings.write("Adsense_password", document.setup.passwordBox.value);
System.Gadget.Settings.write("Adsense_refresh", document.setup.refreshBox.value);
event.cancel = false;
}
}
xàêåð 06 /114/ 08 |
093 |
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
C |
E |
|
|
|||
|
|
X |
|
|
|
|
|||
|
- |
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|||
w Click |
to BUY |
|
>> coding |
||||||
|
|
|
|
|
m |
||||
w |
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
g |
|
|
|
|
|
|
df |
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
||
|
|
|
C |
|
E |
|
|
||||
|
|
X |
|
|
|
|
|
|
|||
|
- |
|
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
||
w Click |
|
|
|
|
|
m |
|||||
|
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
|
g |
|
|
|
|
|
|
df |
- |
|
|
n |
e |
|
||
|
|
|
|
x cha |
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
Гаджет,готовыйкинсталляции
Google с черного хода
Вотмыиперешликсамомуглавному—кпрограммнойлогикегаджета. Всеописанныенижесвященныекамланияярекомендуютебеоформить отдельнымjs-файлом,чтобынемешатьмухскотлетами.Всеадреса,явки ипароли(всеhttp-запросы),помогающиеполюбовнодоговоритьсяс AdSenseсервисом,легкоинепринужденноотыскиваютсяспомощьюанализаотправляемыхбраузеромпакетов.Еслиестьжеланиеповторитьопыт самостоятельно,тебенесоставиттруданайтисоответствующийплагиндля огнелиса.
Итак,сначала—подключение.Googleлюбит,чтобыснимобщалисьс помощьюXML-форматов.Непроблема.ВJavaScriptестьзамечательный объектxmlHttp.
xmlHttp.Open("POST", "https://www.google.com/adsense/login.do",true );
xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded" );
xmlHttp.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");
xmlHttp.send("destination=&username=" + name
+"&password=" + password );
Впринципе, с этого момента уже можно конструировать запросы для получения данных о состоянии AdSense баланса. Но предлагаю на время отвлечься и ответить на один вопрос. А именно — что ты ожидаешь получить в ответ на свой запрос? Я сейчас говорю не о сумме на счете, которая тебе снится в сладких снах. Я о формате данных. Чтобы в дальнейшем было меньше работы по разгребанию всякого мусора, советую выбрать что-нибудь простое. Щедрый Google предлагает несколько форматов представления отчетов. Грех не воспользоваться такой возможностью. Рекомендую остановить свой выбор на формате TSV. Это простая табличка, в которой столбцы разделяются с помощью знака табуляции, а строки
—с помощью символа перевода строки. В этой таблице первая колонка
—количество показов рекламных блоков, вторая — сколько тебе накликали, а третья — твой баланс.
Знаяструктурутаблицы,можнонаписатьдлянеепарсер:
var rows = xmlHttp.responseText.split("\n");
var cells = rows[1].split("\t"); if (cells.length == 6) {
impressions += parseInt(cells[1]); clicks += parseInt(cells[2]); balance += parseFloat(cells[5]);
}
Думаю,тутвсепонятно,икодвкомментарияхненуждается. Теперьнепосредственнозапросы,извлекающиестатистикуввиде
TSV-таблиц.КоличествозапросовсоответствуетколичествуAdSense
Заветныециферки
программ,вкоторыхтыучаствуешь.Мыограничимсядвумя—одиннаста- тистикуAdSenseдляконтентаиодиннастатистикуAdSenseдляпоиска. Всезапросыстроятсяпооднойитойжесхеме.Преждевсего,открываем xmlHttp-соединение,указаввкачествепараметратипзапроса—POSTили GET,строкузапросаидополнительныепараметры(еслинеобходимо).За- темформируемHTTP-заголовокзапроса—setRequestHeader().Чтобы обойтисторонойнеприятныемоментысвыдачейкэшируемыхданныхис каждымзапросомполучатьреальныеданные,вкачествепараметраметода setRequestHeader()можноуказатьвоттакуюхитруюстрочку:«If- Modified-Since», «Sat, 1 Jan 2000 00:00:00 GMT».
ПослечегопосылаемзапросГуглу.Еслиответполучен,парсимданные,как ужедемонстрировалосьнесколькимистрокамивыше.Еслиответатакине дождались—грязноругаемсянапользователя.
xmlHttp.Open("POST", "запрос", false); xmlHttp.setRequestHeader("If-Modified-Since",
"Sat, 1 Jan 2000 00:00:00 GMT"); xmlHttp.send();
if (xmlHttp.status == 200){ parseData();
} else {
loadstatus = "HTTP Error : " + xmlHttp.status;
}
Содержаниезапросабудетотличатьсявзависимостиоттого,какуюинформациюнужнополучить.Так,чтобыполучитьстатистикуAdSenseдляконтента,используетсяследующаястрока:https://www.google.com/adsense/ report/aggregate?outputFormat=TSV_EXCEL.
ЕслинужнополучитьстатистикуAdSenseдляпоиска,строкаприметвид: https://www.google.com/adsense/report/aggregate?product=afs&outputFor mat=TSV_EXCEL.
Чтодобавить?
Присозданиигаджетамыоставилибезвниманиямногиеаспекты, которыенужнообязательноучитыватьвреальнойжизни.Прежде всего,проверяйвсевводимыепользователемданные.
Неплохобылобыпроверятьиданные,получаемыепоСети(каки самфактуспешногополучения).Хорошимтономсчитаетсяявное указаниекодировкитекста.
Существенноповыситбезопасностьипроизводительностьработы гаджетапредварительнаяочисткаот«мусора»полученныхпоСети данных.Естьещерядважныхаспектовсозданиякачественногои безопасногогаджета.ВсеониописанывMSDN.
094 |
xàêåð 06 /114/ 08 |
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
C |
E |
|
|
|||
|
|
X |
|
|
|
|
|||
|
- |
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
NOW! |
o |
|||
>> codingto BUY |
|
|
|||||||
|
|
|
|
|
|||||
w Click |
|
|
|
|
|
m |
|||
w |
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
g |
|
|
|
|
|
|
df |
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
info
Всю самую подробную информацию о гаджетах для Vista SideBar ты найдешь в
Установканеподписанногогаджета MSDN, который, кстати говоря, потихоньку начали переводить на великий и могучий.
РусскоязычныйблогAdSense
Новыйэлементвбиблиотекегаджетов
Финиш
Большая часть работы уже позади — можешь побаловать себя бутылочкой кефира. Осталось заняться пользовательским интерфейсом и придать гаджету немного глянца. К настояще му моменту мы имеем статистику Google AdSense. Как вывести ее на морду гаджета? Очень просто — через параметр innerTextтекстовых полей.
if (loadstatus != '') { textClicks.innerText = ""; textImpressions.innerText = ""; textEarnings.innerText = loadstatus;
} else {
textEarnings.innerText = "Баланс: " + balance.toFixed(2);
textClicks.innerText = "Clicks: " + clicks; textImpressions.innerText = "Показы: " +
mpressions;
}
Еслитыпланируешьнетолькосампользоватьсясобранным
dvd
На диске тебя ждет готовый гаджет для мониторинга Google AdSense. Если лень писать самому — пользуйся на здоровье. И помни, что распаковав архив, ты получишь доступ к исходникам и сможешь усовершенствовать гаджет по своему усмотрению.
Настройкапараметровгаджета
своимирукамигаджетом,ноиподелитьсяимсосвоимидрузьями,тонеплохобылобызамутитьинсталлятор.Синсталляторомтожевсенастолькопросто,чтодажескучно.Берешь свойлюбимыйархиватор,поддерживающийZIP-формат(а какой,скажите,неподдерживает?)изапаковываешькаталогс гаджетом.Послеэтогопростопоменяйрасширениес.zip на
.gadget.Все.Теперьподвойномущелчкунасозданномфайлебудетоткрыватьсястандартныйдиалогустановкинового гаджета.Всемрадоваться.z
Опасно!
Как уже упоминалось в статье, гаджеты имеют достаточно широкие возможности взаимодействия с операционной системой. Это предъявляет особые требования к безопасности гаджета, особенно если он работает с сетевой средой.
Одним из откровенно слабых мест в системе безопасности является механизм взаимодействия с ActiveX-компонентами. Корректность и безопасность такого взаимодействия никак не контролируется операционной системой, и вся ответственность ложится на разработчика гаджета.
Альтернативы
HTML+JavaScript—далеконеединственнаятехнологиясоздания гаджетовдляVistaSidebar.Возможносозданиегаджетовнаоснове WPFиSilverlight.Хотяданныетехнологииболеетрудоемкие,они обеспечиваютбольшевозможностейвпланефункциональностии интеграциисоперационнойсистемой,атакжепредлагаютболее надежнуюсхемуобеспечениябезопасностигаджетаипользовательскихданных.
xàêåð 06 /114/ 08 |
095 |
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
C |
E |
|
|
|||
|
|
X |
|
|
|
|
|||
|
- |
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
NOW! |
o |
||||
|
|
|
|
|
|||||
|
|
|
|
|
|
||||
ort-film |
|
to BUY |
|
>> coding |
|||||
w Click |
|
|
|
|
|
m |
|||
w |
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
g |
|
|
|
|
|
|
df |
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
File View Help
Maximum upload rate: 20KB/s (DSL/cable 256k up)
i |
+ |
|
Example. zip
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
Search for torrents |
|
|
||||||||
|
|
|
|
to |
BUY |
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
|
File View |
Help |
Share ratio: 0%, will seed for 4:59 hours |
i |
||
10-install-i386.iso |
|
|||||
Игорь Антонов |
|
|
|
|||
|
|
|
|
|
|
|
|
|
3.7% |
|
Search for torrents |
|
|
|
|
|
i |
+ |
|
|
|
|
Maximum upload rate: 20KB/s (DSL/cable 256k up) |
|
|
|
|
|
|
blue-a-short-film |
|
|
|
|
041201.isoExample. zip |
|
|
|
|
i |
|
|
|
|
|
|
i |
|
|
|
Done, Share ratio: 0%, will seed for 4:59 hours |
|
+ |
||
|
|
ubuntu-5.10-install-i386.iso |
|
|
|
|
|
Разруливаем |
|
|
|
||
|
blue-a-short-film |
|
3.7% |
|
|
i |
Help |
|
|
|
|
i |
+ |
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
xlivecd-20041201.iso |
|
|
|
|
|
торренты |
|
|
|
|
|
|
|
Search for torrents |
|
|
|
|
Maximum upload rate: 20KB/s (DSL/cable |
? |
|
|
i |
||
|
ubuntu-5.10-install-i386.iso |
|
|
|||
|
|
|
|
|||
|
|
3.7% |
|
|
i |
+ |
|
|
|
|
|
||
|
Done, Share ratio: 0%, will seed for 4:59 hours |
i |
+ |
Done, Share ratio: |
seed for 4:59 hours |
|
|
|
|
||||
|
|
|
|
xlivecdКодим-20041201правильный.iso BitTorrent-клиент
Тебе не надоело сливать файлы с файлообменников типа rapidshare.com? Лично меня уже достали их ограничения. К счастью, есть хорошая альтерна-
тива — Bittorent трекеры. Сегодня мы попробуем поковырять этот протокол
all-i386.isoи написать свой продвинутый клиент.
3.7%
1.iso |
|
|
Теория |
xlivecd-20041201.iso |
|
|
|
|
|
|
хэшифайлов.Главнаязадачатрекера—предоставитьвозможностькли- |
||
|
|
|
|
|||
|
Какобычно,передтемкакринутьсявбой,тщательнопродумаемстрате- |
ентамнайтидругдруга.Пир(peer)—клиент,участвующий? враздаче.Как |
||||
|
? |
|
правило,пируприсущеi |
+ |
||
|
гиюиразберемсястеорией.«Bittorent»—протоколдлясетейтипаp2pи |
двасостояния—закачкаиотдачаужескачанных |
||||
|
|
предназначенондляпередачибольшихфайловпоCети.Перваяверсия |
частейфайла.Сид(seed)—пир,которыйужескачалвесьфайлполностьюи |
|||
|
|
протоколапоявиласьв2001году.КнастоящемувремениBittorentстал |
располагаетвсемиегосегментами.Чтобыстатьсидом,необязательноска- |
|||
|
|
оченьпопулярным,болеетого—онявляетсястандартомбыстрогораспро- |
чиватькакой-либофайл,можнопростоначатьраздачусвоегодобра.Личер |
|||
|
страненияфайлов.Популярнымегосделалирядособенностей: |
|
—онжепиявка(leech)—пир,укоторогоещенетвсехчастейфайла,ноон |
|||
|
1.Отсутствиеочередей.Закачкафайловначинаетсясразуибезкаких-либо |
продолжаетзакачку.Вбольшинствеслучаев,терминиспользуетсявнега- |
||||
|
|
ограничений,присущихтакимсетямкакedonkey. |
|
тивномсмысле.Такназываютклиентов,которыескачиваютбольше,чем |
||
|
2.Нетребуетсяпостоянноефункционированиесервера—трекера.Посути, |
отдают.Толпа/Рой(swarm)—всепиры,участвующиевраздаче.Рейтинг |
||||
|
|
клиентудостаточновсегоодинразподключитьсяксерверу,чтобыполучить |
(shareratio)—соотношениеотданногоискачанного.Рейтингнеобходим, |
|||
|
|
информациюопирах(клиентах,которыезанимаютсянепосредственно |
впервуюочередь,дляпополненияконтента.Работаетпоследующему |
|||
|
|
раздачейфайлов).Послечегоможноспокойноскачиватьфайл. |
|
принципу:скачиваяфайл,тыуменьшаешьсвойрейтинг,аотдаваяфайл |
||
|
3.Закачкалюбогофайлапроизводитсяпочастям.Темсамым,существенно |
—наоборот,увеличиваешь.Клиентсмаленькимрейтингомрискуетбыть |
||||
|
|
увеличиваетсяскоростьзакачки,ведьпостоянноеприсутствиесида(обла- |
забаненнымиунегоменьшевозможностей,чемуклиентасболеевысоким |
|||
|
дателявсехчастейфайла)необязательно.Вслучаеотсутствиясидабудет |
(например,отсутствуетодновременнаязакачканесколькихторрентов). |
||||
|
|
происходитьобменчастеймеждупирами. |
|
Анонс(announce)—отправкаинформациинасервер.Вкачествеотправи- |
||
|
4.Скоростьзакачкиограниченатолькоширинойканалараздающего. |
телявыступаетклиент,авкачествеинформации—соотношениескачан- |
||||
|
|
Соответственно,чембольшеклиентов,которыераздаютфайл,тембыстрее |
ногоиотданного.Получивэтиданные,трекерпередаетклиентуIP-адреса |
|||
|
|
тысможешьегоскачать.ЭтодалеконевсеплюсыпротоколаBitTorrent,но |
другихклиентов.АнонсURL(AnnounceURL)—адрестрекера.Именнопо |
|||
|
|
ихдолжнохватить,чтобызабытьпроословипрочиеrapid. |
|
этомуадресуипроисходитотправкаинформации.Торрент/торрент-файл |
||
|
|
|
|
|
(torrent)—файлметаданных,вкоторомсодержитсяинформацияоприни- |
|
|
|
|
Общаемся по понятиям |
|
маемых/раздаваемыхфайлах,количествесегментовииххэшах.Подробнее |
|
|
Чтобыпонять,очемречьвстатье,необходиморазобратьсястерминами. |
оструктуреэтогофайламыпоговоримпозже. |
||||
|
|
ЗнатьихдолженлюбойпользовательBitTorrent,апрограммист,решивший |
|
|
||
|
|
закодитьклиент,—иподавно.Уверен,чтотыитакихзнаешь,нонекоторая |
Как все это работает? |
|||
|
|
систематизациянепомешает.Начнемсоснов.Трекер(tracker)—сервер, |
Сосновнымипонятиямиразобрались,азначит,порапереходитькболее |
|||
|
|
накоторомхранятсяIP-адресаучастниковраздачи,рейтингучастникови |
детальномурассмотрениюBittorent.Передтем,какприступитькзакач- |
|||
|
|
|
|
|
|
|
096 |
xàêåð 06 /114/ 08 |
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|
|
|||
|
|
X |
|
|
|
|
|
|
|
|
||
|
- |
|
|
|
|
|
d |
|
|
|||
|
F |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
|
t |
|
|
||
P |
D |
|
|
|
|
|
|
|
|
o |
|
|
|
|
|
|
|
NOW! |
r |
Maximum upload rate: 20KB/s (DSL/cable 256k up) |
|||||
|
|
|
|
|
|
BUY |
|
|
||||
|
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
to |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
|
m |
|
|
w Click |
|
|
|
|
|
o |
zip |
|||||
|
w |
|
|
|
|
|
|
|
|
|
||
|
. |
|
|
|
|
|
|
.c |
|
|||
|
|
Example.e |
||||||||||
|
|
p |
df |
|
|
|
g |
|
|
|
|
|
|
|
|
|
|
n |
|
|
|
|
|||
|
|
|
|
|
-xcha |
|
|
|
|
|
||
+ |
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
blue |
|
|
|
|
|
|||
+ |
|
|
|
|
Принципработыпротокола |
|||||||
|
|
|
|
|
|
|
BitTorrent |
Search for torrents
Example. zip
|
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
|
|
|
|
|
|
X |
|
|
|
|
|
|||
|
|
|
|
|
|
|
- |
|
|
|
|
|
d |
|
||
|
|
|
|
|
|
|
F |
|
|
|
|
|
|
t |
|
|
|
|
|
|
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
r |
||
|
|
|
|
|
|
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
Maximum upload rate: 20KB/s (DSL/cab |
||||||||||||||||
>> codingto |
BUY |
|
|
|
|
|
||||||||||
|
|
|
|
|
|
w Click |
|
|
|
|
|
|
m |
|||
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
|
|
|
|
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
|
|
|
|
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
|
|
|
|
|
|
-x cha |
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Don |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4:5 |
|
ubuntu-5.10-install-i386.iso |
|||||||
|
|
ке/раздачефайлов,необходимо |
||||||
|
|
скачатьсоответствующийторрент- |
||||||
+ |
|
файл.Какправило,торрентыдобы- |
||||||
ваютсяизвсевозможныхфорумов, |
||||||||
|
||||||||
|
|
вродеtorrents.ruиличерезспеци- |
||||||
|
xlivecd-20041201.iso |
|
|
|
|
|||
|
|
альныепоисковыесистемывроде |
|
|
||||
|
|
piratebay.org.Скачавторрент-файл |
, |
ты |
долженскормитьеготоррент-кли- |
|||
Search for torrents |
|
|
|
? |
||||
+ |
енту.Далеевсепросто:клиентсоединяетсястрекером(анонсurlхранится |
|||||||
|
вторрент-файле),сообщаетемусвойIPихэшнеобходимогофайла;вответ |
|||||||
|
|
серверотправляетадресапиров/сидов,участвующихвраздаче.После |
||||||
|
|
этогонеобходимостьвтрекеренанекотороевремяисчезает.Тыкачаешьи |
||||||
|
|
обмениваешьсясдругимипирами.Обменсдругимипирамивыглядиттак: |
||||||
|
|
|
|
+ |
|
|
|
|
|
|
тыпосылаешьзапросназакачкусегментанужногофайлаопределенному |
||||||
|
|
|
i |
|
|
|
|
|
|
|
пиру—еслионнепротивиможетподелитьсяэтимкусочком,тоначина- |
||||||
|
|
етсяпроцессзакачки.Скачавсегмент,тыоповещаешьостальныхпирово |
||||||
|
|
наличиивтвоемраспоряженииновогокусочка(чтобыдругиепирызнали, |
||||||
|
|
укогоегокачать).Затемвсеповторяется.Причемповторяетсясшага,на |
||||||
|
|
которомтебенеобходимосоединитьсяссерверомиполучитьинформацию |
||||||
|
|
|
|
+ |
|
|
|
|
|
|
одругихпирах.Закончивзакачкувсегофайла,тыполучаешьстатуссида. |
||||||
|
|
|
i |
|
|
|
|
|
|
|
Нарисункевверхуприведенасхема,демонстрирующаяпроцессработыпо |
||||||
|
|
протоколуBitTorrent. |
|
|
|
|
||
|
|
|
Структура торрент-файла |
|||||
|
|
|
||||||
|
|
|
||||||
|
|
Вфайлеметаданных(торрент-файле),какяужеиговорил,находитсявся |
||||||
|
|
|
|
+ |
|
|
|
|
|
|
информацияпофайлу(илифайлам),участвующемувраздаче.Безнего |
||||||
|
|
|
i |
|
|
|
|
|
|
|
попротоколуBittorentскачатьничегонеудастся.Вобщемвидеструктуру |
||||||
|
|
файламетаданныхможноразделитьнатрисоставляющие(таблица1). |
||||||
|
|
Внутренностиtorrent-файла—этоbencoding-данные.Форматфайла |
||||||
|
|
позволяетхранитьследующиетипыданных:байт-строки,числа,спискии |
||||||
|
|
директивы. |
+ |
|
|
|
Напервыйвзгляд,iпереднами—«каша»непонятныхданных.Сразувозни- каетчувство,чтовсесложноизапутанно.Насамомделе,сложногоничего нет.Давайпопробуемрассмотретьпримерызаписиbencoding-данных.
Начнемсправилзаписистрок.Вобщемвидеформатзаписистроковых данныхвыглядиттак:
Строки:
<длина строки>:<строка>
Пример:5:xakep.
Числа:
<ключ i><число><ключ e>
Пример:i31337e.
Списки:
<ключ l><bencoding данные><ключ e> Пример:l5:xakep5:lamere.
Директивы:
<ключ d><строка bencoding><элемент bencoding><ключ e> Пример:d5:coder6:spidere (Coder => spider).
Вспецификацииструктурыфайламетаданныхестьнесколькопредопределенныхдиректив:
•info—директивадляописаниясвойствфайлов.Взависимостиоттипа торрент-файла(обычный—одинфайлилисмешанный—несколько файлов)этадирективаприменяетсяпо-разному.Вдирективувходят:piece length—длинасегментафайла;pieces—хэшсуммасегмента,полученная поалгоритмуSHA1.Разницуприменениядирективыдляобычногоисмешанногорежимовсмотривтаблице2;
•announce—анонсURL;
3.7
|
Разработкавсамомразгаре |
|
|
|
|
|
|
xlivecd-20041201.iso |
|
|
|
|
|
•announcelist—список,содержащийнесколькоannounceURL; |
|
|||||
•createdate |
|
|
формате+Unix-time; |
|
||
|
—датасозданияtorrent-файлав i |
|
|
? |
||
|
|
|
File |
V |
Help |
|
|
|
|
|
|||
•comment—комментарийотсоздателяторрент-файла; |
|
|
||||
•createdby—названиеиверсияпрограммы,вкоторойбылсозданtorrent- |
|
|||||
файл. |
|
|
|
|
|
|
Практика |
|
|
Maximum upload r |
|||
|
|
|
|
|||
Мыужерассмотрелидостаточнотеории.Самоевремячто-нибудьнакодить. |
|
|||||
|
|
|
Example. zip |
|
|
|
Ксожалению,рассмотретьнаписаниевсегоBittorent-клиентаврамках |
|
|||||
однойстатьиневозможно,поэтомусегоднямынапишемпервуючасть— |
|
|||||
редакторtorrent-файлов.Итак,кделу. |
|
|
|
D |
||
ЗапускайDelphiисоздавайновыйпроект.Дизайнможешьподогнатьпод |
|
|||||
мойвариант(смотририсунокнастр.99). |
|
|
|
|
||
ПовсейформеуменярастянуткомпонентTPageControlсдвумясоздан- |
|
|||||
|
|
|
blue-a-short-film |
|
|
|
нымизакладками.Напервой(«Содержимоеtorrent»)расположенкомпо- |
|
|||||
нентTListView.Вэтомкомпонентемыбудемхранитьназваниеиразмеры |
|
|||||
файлов,которыевпоследствиибудемдобавлятьвторрент.Радиудобства |
|
|||||
отображенияяустановилуTListviewсвойствоViewStyleвvsReport |
|
|||||
исоздалтриколонки:файл,размер,путь.Навторойзакладкеяразместил |
|
|||||
восемькомпонентовTEdit,одинTMemoиоднукопиюTDateTimePicker. |
|
|||||
|
|
|
ubuntu-5.10-install-i386.iso |
|
||
Вэтихкомпонентахмыбудемвыводитьразличнуюинформацию,выдер- |
|
|||||
нутуюизtorrent-файла.Длякомфортногоотображениядатысозданиятор- |
|
|||||
рент-файлаявоспользовалсякомпонентомTDateTimePicker.Сниммы |
|
|||||
избавимсяотлишнихпреобразованийполученнойдаты.Центруправления |
|
|||||
нашейпрограммойбудетнаходитьсянапанелиинструментов.Нанейя |
|
|||||
создалпятькнопок: |
xlivecd-20041201.iso |
|
•OpenTorrentBtn—кнопкадляоткрытияtorrent-файла;
•SaveTorrentBtn—пимпадлясозданияновоготорента;
•NewBtn—служитдляочисткивсеэлементовформы;
•AddFileBtn—кнопкадлядобавленияновогофайлавtorrent;
•DelFileBtn—кнопкадляудаленияфайлаизторрента.
Наэтомсдизайномформыпоразаканчиватьипереходитьксамомузахва- тывающемуиувлекательномупроцессу—кодингу.Сегодняяпокажу,как можночитатьисоздаватьторрент-файлы.Переходивредакторкодаисразу объявиновуюструктуру:
type
TPieces = record _hash : string; _hashBin: string; end;
Вданнойструктуре(илизаписи)мыбудемхранитьинформациюпокаждому сегментуфайла.В_hashбудемзаписывать20 байтнуюхэш-сумму,рассчи- таннуюпоалгоритмуSHA1,ав_hashBin—бинарныйвариантэтогоже значения.
Вразделе«private»нашейформыобъявипроцедуруCreateTorrent (fs: TFileStream; multifile:Boolean).Этимметодоммыбудемсоздавать новыйторрент-файл.Вкачествепараметроввпроцедурубудутпередаваться
fs—переменнаятипаTFIleStream(файловыйпотокдлясозданияторрент-
xàêåð 06 /114/ 08 |
097 |
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
C |
E |
|
|
|||
|
|
X |
|
|
|
|
|||
|
- |
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
NOW! |
o |
||||
|
|
|
|
|
|||||
|
|
|
|
|
|
||||
ort-film |
|
to BUY |
|
>> coding |
|||||
w Click |
|
|
|
|
|
m |
|||
w |
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
g |
|
|
|
|
|
|
df |
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
File View Help
Maximum upload rate: 20KB/s (DSL/cable 256k up)
i |
+ |
|
Example. zip
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
Search for torrents |
|
|
||||||||
|
|
|
|
to |
BUY |
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
View |
|
файла)ибулевскоезначение(multifile),определяющеетипбудущеготоррент- |
|
|
I: Integer; |
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||
Help |
|
|
|
Done,beginShare ratio: 0%, will seed for 4:59 hours |
|
|
|
|||||||||||||||||||||
|
|
|
|
|
|
файла(обычныйилисмешанный).Нажимай<ctrl+shift+с>иDelphiсоздаст |
|
|
|
|||||||||||||||||||
10-install-i386.iso |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||
|
|
|
|
|
|
заготовкупроцедуры.Перепишивнеекодизсоответствующейврезки. |
|
|
DateTimeToSystemTime(WinTime, |
SystemTime); |
||||||||||||||||||
|
|
|
|
|
|
Перебиваялистинг,незабывайвозвращатьсяктекстустатьиичитатьмои |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
3.7% |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
комментарии(лично я предпочитаю вообще целиком переписы- |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
Maximum upload rate: 20KB/s (DSL/cable 256k up) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
blue-a-short-film |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
вать чужой код по-своему, иначе я его так до конца и не могу |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
041201.isoпонять—Прим.ред.).Первымделомпосмотринасамоеначалопроцеду- |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||
|
|
Создание |
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||
e. zip |
|
ры.ВместопривычныхключевыхсловVAR/Beginуменяидетобъявление |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||
|
|
|
|
|
|
несколькихлокальныхпроцедур.Использованиетакогоподходанесколько |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||
|
|
|
|
|
|
|
|
torrent-файла |
|
|
||||||||||||||||||
|
|
|
|
|
|
таковымиявляется.Давайвзглянемнакаждуюпроцедурувотдельности. |
|
|
|
|
||||||||||||||||||
|
|
|
|
|
|
|
? |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ухудшаетчитабельностьDone,кода,ноShareиногдаratio:этоможет0%, willбытьseedудобноfor.Наш4:59случайhours |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
ubuntu-5.10-install-i386.iso |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
procedureTForm1.CreateTorrent |
|
WriteBuff('d'); |
|
|
||||||||||||||||
|
|
|
|
|
|
Procedure WriteBuff(buff:string)записываетвфайловыйпоток |
|
|
|
|
||||||||||||||||||
short-film |
|
первыйсимволизпереданнойвкачествепараметрастроки-переменной |
|
|
(fs:TFileStream; |
|
If(MultiFile)Then |
|
|
|||||||||||||||||||
|
buff.Еслитывнимательночиталтеорию,тоужедолженбылдога- |
|
|
multifile:boolean); |
|
begin |
|
|
||||||||||||||||||||
Help |
|
даться,чтоиспользоватьэтупроцедурумыбудемдлязаписи«ключей» |
|
|
|
|
|
|
|
|
|
|
WriteStr('files'); |
|
|
|||||||||||||
|
|
|
|
|
|
bencoding-данных.Процедуры WriteStr()иWriteInt()имеют |
|
procedureWriteBuff(buff:string); |
|
|
|
WriteBuff('l'); |
|
|
||||||||||||||
|
|
|
|
|
|
аналогичноепредназначениеиxlivecdбудутиспользоваться-20041201.isoдлязаписистрок |
|
begin |
|
|
|
|
|
fori:=0to |
|
|
||||||||||||
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||||
|
|
|
|
|
|
(WriteStr())ичисел(WriteInt()). |
|
|
fs.WriteBuffer(buff[1], |
|
|
|
|
|
|
|
ListView1.Items.Count-1Do |
|
|
|||||||||
|
|
|
Maximum upload rate: 20KB/s (DSL/cable |
|
|
length(buff)); |
|
|
|
withlistView1.Items.Item[i] |
|
|
||||||||||||||||
|
|
|
|
|
|
Разобравшисьслокальнымипроцедурами,можнодвигатьсядальше. |
|
|
|
|
|
|
|
|||||||||||||||
5.10-install-i386.iso |
|
|
|
|
end; |
|
|
|
do |
|
|
|||||||||||||||||
|
|
|
|
|
|
Впередибудетмногоинтересного.Сейчаснасекундочкуотвлекисьот |
|
|
|
|
|
|
||||||||||||||||
|
|
|
|
|
|
текстаипосмотринатаблицу1,вкоторойяопределилуровниструктуры |
|
|
|
|
|
|
|
|
|
|
begin |
|
|
|||||||||
|
|
|
|
|
|
|
3.7% |
|
|
procedureWriteStr(s:string); |
|
|
|
|
WriteBuff('d'); |
|
|
|||||||||||
|
|
|
|
|
|
torrent-файла.Первымуровнемидет«Заголовок»,азначит,самымпер- |
|
|
|
|
|
|
|
|||||||||||||||
|
|
|
|
|
|
вымшагомвнашейпроцедуребудетформированиезаголовкабудущего |
|
begin |
|
|
|
|
WriteStr('length'); |
|
|
|||||||||||||
|
|
|
|
|
|
|||||||||||||||||||||||
|
|
|
|
|
|
Done, Share ratio: 0%, will seed for 4:59 hours |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
торрент-файла.Формированиезаголовкаяначинаюсзаписиключа—d, |
|
|
WriteBuff( |
|
|
|
|
WriteInt(StrToInt( |
|
|
||||||||||||
20041201.isoазатемпоочередизаписываюименаэлементов(такназываемыедирек- |
|
|
IntToStr(length(s))+':'+s); |
|
|
|
|
|
SubItems.Strings[0])); |
|
|
|||||||||||||||||
|
|
|
|
|
|
тивы)иихзначения,которыемыбудемвводитьвкомпонентахTEdit, |
|
end; |
|
|
|
|
WriteStr('path'); |
|
|
|||||||||||||
|
|
|
|
|
|
расположенныхнавторойзакладке.Запись?элементоводнообразнаия |
|
|
|
|
|
|
|
|
|
|
|
WriteBuff('l'); |
|
|
||||||||
|
|
|
|
|
|
думаю,вседолжнобытьпонятным.Хотянет,процессзаписивременисо- |
|
procedureWriteInt(int:int64); |
|
|
|
|
WriteStr(ExtractFileName( |
|
|
|||||||||||||
|
|
|
|
|
|
зданиястоитрассмотретьподробней.Какяужеговорилвтеоретической |
|
begin |
|
|
|
|
|
SubItems.Strings[1])); |
|
|
||||||||||||
|
|
|
|
|
|
части,времясозданияторрент-файладолжнохранитьсявформатеUnix- |
|
|
WriteBuff('i'); |
|
|
|
|
WriteBuff('e'); |
|
|
||||||||||||
|
|
|
|
|
|
time.Ксожалению,вDelphiсредистандартныхфункцийнеттой,которая |
|
|
WriteBuff(IntToStr(int)); |
|
|
|
|
WriteBuff('e'); |
|
|
||||||||||||
|
|
|
|
|
|
моглабыконвертироватьвремявUnix-timeиобратно.Следовательно, |
|
|
WriteBuff('e'); |
|
|
|
end; |
|
|
|||||||||||||
all-i386.iso подобнуюфункциюпридетсяписатьсамому.Аможетинепридется,ведь |
|
end; |
|
|
|
WriteBuff('e'); |
|
|
||||||||||||||||||||
|
|
|
|
|
|
вовсемирнойпаутинкелегконайтипримерыкода,реализующегокон- |
|
|
|
|
|
|
|
|
end |
|
|
|||||||||||
|
|
|
|
|
|
|
3.7% |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
вертирование.Вариантовмного,номнебольшевсехнравитсяэтот: |
|
VAR |
|
else |
|
|
||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
i:integer; |
|
begin |
|
|
||||||||||||
|
|
|
|
|
|
function TForm1.WinTimeToUnixTime |
|
|
_pieceLength:Integer; |
|
|
|
WriteStr('length'); |
|
|
|||||||||||||
1.iso |
|
(winTime: TDateTime): Integer; |
|
BEGIN |
|
|
|
WriteInt(StrToInt( |
|
|
||||||||||||||||||
|
|
|
|
|
|
var |
|
|
|
|
|
WriteBuff('d'); |
|
|
|
|
ListView1.Items.Item[0]. |
|
|
|||||||||
|
|
|
|
|
|
FileTime: TFileTime; ? |
|
|
WriteStr('announce'); |
|
|
|
|
|
SubItems.Strings[0])); |
|
|
|||||||||||
|
|
|
|
|
|
SystemTime: TSystemTime; |
|
|
WriteStr(AnnounceUrlEdit.Text); |
|
end; |
|
|
|||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
If(CommentsMemo.Text<>'') |
|
|
|
|
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
Таблица2.Особенностииспользованиядирективыinfo |
|
|
|
WriteStr('name'); |
|
|
||||||||||||||||
|
|
|
|
|
|
|
|
|
Then |
|
|
|
||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||
|
|
|
|
|
|
Обычный(Single |
Смешанный(Multifilemode). |
|
|
begin |
|
WriteStr(NameEdit.Text); |
|
|
||||||||||||||
|
|
|
|
|
|
filemode).Список |
Списокзначений |
|
|
|
|
|
||||||||||||||||
|
|
|
|
|
|
|
|
WriteStr('comment'); |
|
|
|
|
|
|
|
|
|
|
|
|
||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
значений |
|
|
|
|
|
WriteStr( |
|
_pieceLength:=65536; |
|
|
||||||||||||
|
|
|
|
|
|
name—имяфайла |
|
|
|
|
|
|
|
|
||||||||||||||
|
|
|
|
|
|
name—имяtorrent-файла |
|
|
CommentsMemo.Text); |
|
WriteStr('piecelength'); |
|
|
|||||||||||||||
|
|
|
|
|
|
length—размер |
files—списокфайлов.Вдирективеможет |
|
|
end; |
|
WriteInt(_pieceLength); |
|
|
||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||
|
|
|
|
|
|
файла |
использоватьсянесколькоподдиректив:length |
|
|
|
|
|
|
|
|
WriteStr(‘pieces’); |
|
|
||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||
|
|
|
|
|
|
|
(размерфайла),md5sum(хеш),path(путькфайлу). |
|
|
If(ProgNameEdit.Text<>'') |
|
|
|
|
|
|
|
|
|
|
|
|
||||||
|
|
|
|
|
|
md5sum—хэшсумма |
|
|
|
|
|
Then |
|
GetPieces(_pieceLength); |
|
|
||||||||||||
|
|
|
|
|
|
файла,полученнаяпо |
|
|
|
|
|
|
|
|
||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
begin |
|
WriteBuff(IntToStr(( |
|
|
|||||||||||||
|
|
|
|
|
|
алгоритмуMD5 |
|
|
|
|
|
|
|
|
||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
WriteStr('createdby'); |
|
|
|
high(pieces)+1)*20)); |
|
|
|||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
WriteStr(ProgNameEdit.Text); |
|
WriteBuff(':'); |
|
|
||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
end; |
|
|
|
|
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
Таблица1.Структураtorrent-файла |
|
|
|
|
fori:=0toHigh(pieces)Do |
|
|
|||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||
|
|
|
|
|
|
Названиеуровня |
Описание |
|
|
WriteStr('creationdate'); |
|
|
|
WriteBuff(pieces[i]._hashBin); |
|
|
||||||||||||
|
|
|
|
|
|
1.Заголовок |
ВзаголовкесодержитсяанонсURL,датасозда- |
|
|
|
|
|
|
|
||||||||||||||
|
|
|
|
|
|
|
|
WriteInt(WinTimeToUnixTime( |
|
|
|
|
|
|
|
|
|
|
|
|
||||||||
|
|
|
|
|
|
|
нияtorrent-файла,кодировкафайла,название |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||
|
|
|
|
|
|
|
|
|
DateCreate.DateTime)); |
|
WriteBuff('e'); |
|
|
|||||||||||||||
|
|
|
|
|
|
|
программывкоторойбылпостроенфайл,коммен- |
|
|
|
|
|
||||||||||||||||
|
|
|
|
|
|
|
|
|
If(EncodingEdit.Text<>'')Then |
|
WriteBuff('e'); |
|
|
|||||||||||||||
|
|
|
|
|
|
|
тариисоздателяит.д. |
|
|
|
|
|
||||||||||||||||
|
|
|
|
|
|
|
|
|
begin |
|
|
|
|
|
|
|
|
|
|
|
|
|||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
2.Информация |
Вэтомблокесодержатсявсеназванияиразмеры |
|
|
WriteStr('encoding'); |
|
Fs.Free; |
|
|
||||||||||||||
|
|
|
|
|
|
офайлах |
файлов,которыеможнополучитьспомощью |
|
|
|
|
|
||||||||||||||||
|
|
|
|
|
|
|
|
WriteStr(EncodingEdit.Text); |
|
|
|
|
|
|
|
|
|
|
|
|
||||||||
|
|
|
|
|
|
|
данноготоррент-файла. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||
|
|
|
|
|
|
|
|
|
end; |
|
ShowMessage( |
|
|
|||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||
|
|
|
|
|
|
3.Сведения |
ВблокеуказаноколичествосегментовиихSHA1- |
|
|
|
|
|
|
|
|
|
|
'Torrentфайлсоздан!'); |
|
|
||||||||
|
|
|
|
|
|
осегментах |
хэшсуммы. |
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||
|
|
|
|
|
|
|
|
WriteStr('info'); |
END; |
|
|
|||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
i
i
i
? i
098 |
xàêåð 06 /114/ 08 |