Jump to content
Korean Random
CrazySys

[Packages] Встроенный браузер - доступ к ресурсам веб-страниц внутри пакета.

Recommended Posts

UPD: Тема ответвилась здесь: Mod packages / Пакеты модов

А что делать тем у кого мод использует бравзер внутренний, например? Или другие внешние ресурсы, которые генерятся по ходу работы мода?
А если бравзеру еще и картинки нужны те что в пэкаджах? Изображения техники например... Сейчас у меня те картинки что нужны бравзеру распаковываются в отдельную папку при первом запросе...

ИМХО все одно не получится всех загнать в один zip - все равно будут папки плодиться.

Ну и да, эта вот мода каждый раз менять названия папок с модиками угнетает не только игроков :) Хотя причина понятна.

Edited by CrazySys

Share this post


Link to post

Short link
Share on other sites

 

 

ИМХО все одно не получится всех загнать в один zip - все равно будут папки плодиться.
 

А кто запрещает создавать временные папки/файлы?

  • Upvote 2

Share this post


Link to post

Short link
Share on other sites

Ну если исходить из того что "нет ничего более постоянного, чем временное"...

Если я правильно понимаю цель всей этой затеи с пэкаджами - максимально снизить количество "временных папок и файлов", упорядочить их именование и размещение (дабы было понятно чьи хвосты торчат по всему диску) и, возможно, в итоге запустить некий менеджер модификаций в самой игре.
 

В моем случае проблема в том, что встроенный браузер (впрочем как и внешний) сильно ограничены в доступе к локальным файлам, а про VFS они вообще ничего не слышали.

 

Так что внутри такой "временной" папки будет уйма мелких файлов и подпапок. Причем большая часть содержимого не меняется при смене версии игры (за вычетом генерируемых на лету файлов). В этом случае логичнее поднять такую папку выше предлагаемой ../mods/0.X.X

В самом же пэкадже останутся только пара *.pyc файлов. Но разве из-за них весь сыр-бор затеян?

Edited by CrazySys

Share this post


Link to post

Short link
Share on other sites
@CrazySys, все необходимые файлы находятся внутри пакета. Если функционал не может работать с VFS, или получать на вход поток двоичных данных из питона, то файл копируется из VFS во временный каталог пользователя ОС (%temp%) и используется оттуда.

Share this post


Link to post

Short link
Share on other sites

GPCracker, вероятно это хорошая идея для среднестатистического мода. Но не всегда такой вариант подходит наилучшим образом.

В моем случае придется каждый раз при запуске игры вытаскивать из пэкеджа и танко-клиента более двух сотен файлов. Даже простейшая проверка их наличия в %temp% при каждом запуске займет порядочно времени.

Если же сложить все в %temp% один раз и забить на проверку, то после очередной "очистки диска" игроком или после запуска одной из широко распространенных среди ЦА "утилит-ускорителей", %temp% окажется девственно чистым, а для html-файла открытого во внутреннем браузере это будет полной неожиданностью. Закончится же все нытьем на форуме - "мод не работает, ничего не трогал, только диск отформатировал". Гораздо проще объяснить один раз пользователю, что вот есть папка [танко-клиент]/mods/[mod_name] - ее руками не трогай, потрогал - не жалуйся.

Впрочем, если не ошибаюсь, ограничений на создание папок в других местах никто пока не накладывает и можно упаковать в пэкедж только загрузчик, а остальное делать по старинке (хотя это и убивает всю затею на корню). =)

Edited by CrazySys

Share this post


Link to post

Short link
Share on other sites

GPCracker, вероятно это хорошая идея для среднестатистического мода. Но не всегда такой вариант подходит наилучшим образом.

В моем случае придется каждый раз при запуске игры вытаскивать из пэкеджа и танко-клиента более двух сотен файлов. Даже простейшая проверка их наличия в %temp% при каждом запуске займет порядочно времени.

 

Если же сложить все в %temp% один раз и забить на проверку, то после очередной "очистки диска" игроком или после запуска одной из широко распространенных среди ЦА "утилит-ускорителей", %temp% окажется девственно чистым, а для html-файла открытого во внутреннем браузере это будет полной неожиданностью. Закончится же все нытьем на форуме - "мод не работает, ничего не трогал, только диск отформатировал". Гораздо проще объяснить один раз пользователю, что вот есть папка [танко-клиент]/mods/[mod_name] - ее руками не трогай, потрогал - не жалуйся.

 

Впрочем, если не ошибаюсь, ограничений на создание папок в других местах никто пока не накладывает и можно упаковать в пэкедж только загрузчик, а остальное делать по старинке (хотя это и убивает всю затею на корню). =)

 

Храни инфу в APPDATA, получая доступ туда через функцию в BigWorld.xxx, которая возвращает путь до "c:\Users\StranikS\AppData\Roaming\Wargaming.net\WorldOfTanks\", название не помню просто.

  • Upvote 2

Share this post


Link to post

Short link
Share on other sites

Даже простейшая проверка их наличия в %temp% при каждом запуске займет порядочно времени.

Не угадал. Проверка займет доли секунды. Это питон, если есть мозги - можно написать быстро и красиво в несколько строчек кода всего.

Там всего-то надо сделать walk по каталогу, сформировать список файлов, найти недостающие просто вычитанием сетов, и скопировать их из пакета. Все.

То, что юзвер почистил временную папку - ну грузиться первый раз после этого будет чуть дольше из-за копирования файлов и все.

А вообще для этого существует специальный формат упакованных веб-страниц (mhtml). Не уверен правда, получится ли их открыть во внутриигровом браузере, но в обычных работает.

название не помню просто.

prefsFilePath = unicode(BigWorld.wg_getPreferencesFilePath(), 'utf-8', errors='ignore')
cacheDir = os.path.join(os.path.dirname(prefsFilePath), 'dossier_cache')
Это пример из скриптов картохи. Думаю, проанализировав все это дело, можно без проблем разобраться как создать там себе папочку для личных нужд. Edited by GPCracker

Share this post


Link to post

Short link
Share on other sites

Храни инфу в APPDATA

 Изначально так и делаю. os.getenv('APPDATA') + '\\Wargaming.net\\WorldOfTanks\\WoTLogger.ru'

 

Не угадал. Проверка займет доли секунды. Это питон, если есть мозги - можно написать быстро и красиво в несколько строчек кода всего.

Зависит от кол-ва файлов конечно. Но не отрицаю, это один из возможных путей.

Быстро и красиво не всегда получается с первого раза =) Опыта в змеюке не хватает катастрофически, а тут еще и "приколы" внутри танко-клиента.

Сейчас вот уперся в особенности работы threading внутри игры, пытаюсь раскуривать в меру сил.

 

 

 

Share this post


Link to post

Short link
Share on other sites

os.getenv('APPDATA')

Если уж на то пошло, то

os.path.expandvars('$APPDATA/Wargaming.net/WorldOfTanks/WoTLogger.ru')

Сейчас вот уперся в особенности работы threading внутри игры, пытаюсь раскуривать в меру сил.

threading не совсем корректно временами работает с некоторыми C модулями игры, некоторые вызовы функций BigWorld или GUI могут крашиться внутри потока. Если нужно что-то такое запараллелить - используй колобок (BigWorld.callback()).
  • Upvote 1
  • Downvote 1

Share this post


Link to post

Short link
Share on other sites

Если уж на то пошло, то

Не факт что так быстрее, но как вариант, спс =) В принципе там и %APPDATA% тоже развернется, мы же под "винду" пишем...

 

threading не совсем корректно временами работает с некоторыми C модулями игры,

На краши пока не наступал, но столкнулся с непонятными тормозами потоков в определенные моменты (ангар).

 

Если нужно что-то такое запараллелить - используй колобок (BigWorld.callback()).

Спасибо за наводку, пойду почитаю код на эту тему, возможно это решит мою проблему с тормозами потоков.

UPD: Проблема с тормозами потоков снята, еще раз спасибо.

 

Впрочем мы отошли от темы и как бы не нагрянул Mr.13 с бан-хаммером ;) Если что, попробую тебя в ЛС подергать, спасибо!

Edited by CrazySys

Share this post


Link to post

Short link
Share on other sites

 

 

Если нужно что-то такое запараллелить - используй колобок (BigWorld.callback()).
 

Ты ведь понимаешь, что он не параллелен?

  • Upvote 1

Share this post


Link to post

Short link
Share on other sites

Если что, попробую тебя в ЛС подергать, спасибо!

Для этих целей лучше использовать раздел помощи. Возможно, ответы будут еще кому-то интересны.

Ты ведь понимаешь, что он не параллелен?

Но это единственный способ не ждать окончания выполнения команды, или запустить процесс что-то в отдельном потоке, если идет работа с движком игры. Потому как далеко не все нормально работает в потоках threading. Одно время ловились краши при попытке создать в потоке модельку например. С чисто питоновскими вещами проблем быть не должно.

Share this post


Link to post

Short link
Share on other sites

С чисто питоновскими вещами проблем быть не должно.

Но они есть. Танко-клиент похоже как-то рулит приоритетами потоков. С ходу (неделю убил, с перерывами на основную работу и перекуры) про такую возможность в питоне я ничего нагуглить не смог.

Мой пример - достаточно примитивная функция с обработкой кучки файлов (прочесть, разжать zlib, развернуть pickle в многослойный словарь, подергать нужное, сдампить в json, записать в соседний файл) в дочернем потоке выполнялась 30-40 сек (150 файлов общим весом менее 1Мб) - это в ангаре.

При уходе игрока в очередь боев и в самом бою, все ровно тоже самое прокручивалось за 10-15сек.

При цеплянии этой функции за внутриигровые ивенты (нажатие кнопки, или прочие события типа выхода в ангар) - все тоже самое делалось за 2-3 сек (похоже тут уже была передача функции в колобок).

 

После раскуривания BigWorld.callback() - все то же самое делается менее чем за 500мс, почти как в голом питоне. Вне зависимости от "окружения" игрока.

 

А что касается параллельности колобков - легко убедиться засунув туда функцию с

while True:

  time.sleep(1)

 

Параллельностью там и не пахнет  =)

Edited by CrazySys
  • Upvote 1

Share this post


Link to post

Short link
Share on other sites

 

 

не ждать окончания выполнения команды, или запустить процесс что-то в отдельном потоке
 

Ты понимаешь, что BW.callback - это не поток?

Share this post


Link to post

Short link
Share on other sites

В дочернем потоке выполнялась 30-40 сек в ангаре.

При уходе игрока в очередь боев и в самом бою, все ровно тоже самое прокручивалось за 10-15сек.

При цеплянии этой функции за внутриигровые ивенты (нажатие кнопки, или прочие события типа выхода в ангар) - все тоже самое делалось за 2-3 сек.

После раскуривания BigWorld.callback() - все то же самое делается менее чем за 500мс, почти как в голом питоне. Вне зависимости от "окружения" игрока.

Танко-клиент похоже как-то рулит приоритетами потоков.

В ангаре в потоках вертится куда больше всякой шляпы, чем в бою. Поэтому и выполняется медленнее.

Для питона - вполне возможно. Дело в том, что питон так устроен, что одновременно может выполняться только один поток. В реале потоки питона не параллельны, а поочередно частями выполняются. Есть такая штука как GIL (Global Interpreter Lock). Загугли.

P.S. Таки подкину немного инфы, раз, два. Еще советую почитать про разницу между модулями threading и multiprocessing, м.б. это тоже как-то тебе поможет.

Так что вполне возможно что клиент чаще выдает GIL на более критичные потоки. К примеру, выставляя критичным потокам выполнение 100 инструкций перед освобождением GIL, а некритичным 50 или типа того.

C часть клиента, если она адекватно написана, данная проблема затрагивать не должна, поскольку во всех С функциях, которые не затрагивают питон, но выполняются достаточно небыстро, прописано, что в процессе их выполнения GIL освобождается, и питон может выполнять другие потоки, пока выполняется С код, и снова запрашивается, когда С код будет выполнен, для продолжения выполнения питоновского кода.

Ты понимаешь, что BW.callback - это не поток?

Бл***ь, я в курсе, что колобки выполняются по тикам и доки я читать тоже умею.

Registers a callback function to be called after a certain time, but not before the next tick. The callback is executed once and is not automatically repeated, so reset the callback again if regular updates are needed. If multiple callbacks are due to be executed within a single frame, the chronological order in which they were added is maintained. 
Смысл в другом! У тебя идет выполнение некоторой последовательности инструкций. Тебе нужно запустить какую-то функцию, и не ждать ее выполнения, а продолжать выполнять свои задачи. С этой точки зрения колобок можно рассматривать как поток, и хотя реальным потоком он не является, это мало кого е***, поскольку в большинстве случаев задача стоит избежать т.н. "блокировки". И в нехилой части случаев, запуск колобка происходит не из колобка, а например из какого-то ивента игры, и зачастую этот ивент и колобки выполняются игрой в разных потоках. Edited by GPCracker

Share this post


Link to post

Short link
Share on other sites

Загугли.

Гуглил, доки и хабр читал, спс. Про GIL и питоновскую "многозадачность" уже начитан.

Так что вполне возможно что клиент чаще выдает GIL на более критичные потоки.

Было бы интересно узнать как он это делает, но боюсь мы этого не узнаем. Хотя и без этого знания жить можно...

 

Бл***ь

Воу-воу!

<зануда mode> У тебя одна звездочка лишняя :-) </зануда mode>

=)

Edited by CrazySys

Share this post


Link to post

Short link
Share on other sites

Бл***ь, я в курсе, что колобки выполняются по тикам и доки я читать тоже умею. Смысл в другом! У тебя идет выполнение некоторой последовательности инструкций. Тебе нужно запустить какую-то функцию, и не ждать ее выполнения, а продолжать выполнять свои задачи. С этой точки зрения колобок можно рассматривать как поток, и хотя реальным потоком он не является, это мало кого е***, поскольку в большинстве случаев задача стоит избежать т.н. "блокировки". И в нехилой части случаев, запуск колобка происходит не из колобка, а например из какого-то ивента игры, и зачастую этот ивент и колобки выполняются игрой в разных потоках.

Если метод отжирает для примера одну секунду выполнения, чисто для примера, то нет совершенно никакой разницы запустишь ты его сразу или через BigWorld.callback ибо этот фриз на одну секунду ты все равно увидишь.

BigWorld.callback это по сути просто отложенный вызов метода в main потоке, он применяется в контексте параллельности также как и модуль multiprocessing в контексте танков (то есть никак).

Зачем такое советовать?

 

Хотя и без этого знания жить можно...

Потоки оформляйте через threading, и будет вам счастье.

А для нормального структурированного кода курите как используется модуль adisp в игре.

Edited by POLIROID
  • Upvote 2

Share this post


Link to post

Short link
Share on other sites

 

 

С этой точки зрения колобок можно рассматривать как поток

 

Ни с какой точки зрения колобок нельзя рассматривать как поток. Если конечно это не точка зрения сумасшедшего человека. 

  • Upvote 3

Share this post


Link to post

Short link
Share on other sites

Потоки оформляйте через threading, и будет вам счастье.

Все вышеописанное мной наблюдалось именно при работе функции в дочернем потоке через threading.thread

 

И одна из мыслей была передать ее выполнение в main, что по сути (с твоих же слов) и делается через BigWorld.callback()

Так что совет GPCracker, в данном случае, был очень в тему.

 

А для нормального структурированного кода курите как используется модуль adisp в игре.

Курил @async и @process еще до того как сюда запостить. Так же ни на что не повлияло.

По ощущениям - код всего модуля (как и описано в доке с "магией") продолжил работать после запуска функции, но выполнение самой @async функции осталось в том же дочернем потоке и на скорости ее выполнения никак не отразилось.

Edited by CrazySys

Share this post


Link to post

Short link
Share on other sites

также как и модуль multiprocessing в контексте танков

Если честно, я давно не удивляюсь, что у картофана то тот стандартный питоновкий модуль не фурычит, то этот. Это же картошка!

Смысл был в том, что "поток" без помех в виде GIL и магии картофана на питоне можно запустить, сделав его отдельным процессом. Правда, по всей видимости придется брать для этого свой питон :(

Мой пример - достаточно примитивная функция с обработкой кучки файлов (прочесть, разжать zlib, развернуть pickle в многослойный словарь, подергать нужное, сдампить в json, записать в соседний файл)

В рамках реализации описанного большую часть вообще можно (и выгоднее всего, с точки зрения производительности) реализовать отдельным процессом.

А для нормального структурированного кода курите как используется модуль adisp в игре.

Тоже давно уже обращал внимание на эти декораторы. Как раз таки в основном на различном IO висят.

Потоки оформляйте через threading, и будет вам счастье.

Мой пример - достаточно примитивная функция с обработкой кучки файлов (прочесть, разжать zlib, развернуть pickle в многослойный словарь, подергать нужное, сдампить в json, записать в соседний файл) в дочернем потоке выполнялась 30-40 сек (150 файлов общим весом менее 1Мб) - это в ангаре.

При уходе игрока в очередь боев и в самом бою, все ровно тоже самое прокручивалось за 10-15сек.

При цеплянии этой функции за внутриигровые ивенты (нажатие кнопки, или прочие события типа выхода в ангар) - все тоже самое делалось за 2-3 сек (похоже тут уже была передача функции в колобок).

После раскуривания BigWorld.callback() - все то же самое делается менее чем за 500мс, почти как в голом питоне. Вне зависимости от "окружения" игрока.

Смысл вопроса, если я правильно понял @CrazySys, был не в том, как создать поток, а как ускорить процесс его выполнения. Ибо 30-40 сек и 500мс это как-бы заметная разница. Edited by GPCracker
  • Upvote 1
  • Downvote 1

Share this post


Link to post

Short link
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...