<?xml version="1.0"?>
<rss version="2.0"><channel><title>&#x41F;&#x43E;&#x441;&#x43B;&#x435;&#x434;&#x43D;&#x438;&#x435; &#x442;&#x435;&#x43C;&#x44B;: &#x413;&#x430;&#x439;&#x434;&#x44B;</title><link>https://computercraft.ru/forum/86-gaydy/</link><description>&#x41F;&#x43E;&#x441;&#x43B;&#x435;&#x434;&#x43D;&#x438;&#x435; &#x442;&#x435;&#x43C;&#x44B;: &#x413;&#x430;&#x439;&#x434;&#x44B;</description><language>ru</language><item><title>&#x423;&#x441;&#x442;&#x430;&#x43D;&#x43E;&#x432;&#x43A;&#x430; MineOS &#x43D;&#x430; &#x43F;&#x43B;&#x430;&#x43D;&#x448;&#x435;&#x442;</title><link>https://computercraft.ru/topic/9606-ustanovka-mineos-na-planshet/</link><description><![CDATA[
<p>
	У меня такой произошло идея: я установил mineOS на другой компьютер. и я установленного диска переносил в планшет<br>
	<br>
	 
</p>

<p>
	Первый Гайд:<br>
	Собрать планшет в сборщике необходимо компоненты:<br>
	1 - Корпус планшета (можно взять креатив)<br>
	2 - Интернет-карта<br>
	3 - Клавиатура (поместится в 1 слот)<br>
	4 - Оперативный память 3-2 уровня<br>
	5 - eeprom (нужно чтобы прошито MineOS EFI)<br>
	6 - память (нужно чтобы установлен MineOS)<br>
	7 - добавить 8 ёмкостей<br>
	<br>
	Второй Гайд:<br>
	вы должны собрать компьютер и ввести install и потом pastebin run PDE3eVsL<br>
	<br>
	Третий Гайд:<br>
	вы должны поставить mineOS если до конца установился переносите в сборщике память и всё можно запустить операционную систему mineOS<br>
	 
</p>

]]></description><guid isPermaLink="false">9606</guid><pubDate>Tue, 31 Dec 2024 14:36:39 +0000</pubDate></item><item><title>&#x41A;&#x430;&#x43A; &#x43F;&#x43E;&#x43B;&#x443;&#x447;&#x438;&#x442;&#x44C; &#x43F;&#x440;&#x44F;&#x43C;&#x443;&#x44E; &#x441;&#x441;&#x44B;&#x43B;&#x43A;&#x443; &#x43D;&#x430; &#x43C;&#x443;&#x437;&#x44B;&#x43A;&#x443; &#x432; OpenFM</title><link>https://computercraft.ru/topic/5456-kak-poluchit-pryamuyu-ssylku-na-muzyku-v-openfm/</link><description><![CDATA[
<p>
	Привет! Сегодня расскажу как можно воспроизводить музыку в OpenFM без всякой заморочки!
</p>

<p>
	Для начала нам нужно поставить радио. Затем поставить динамик рядом с радио и соединить. Так возникает вопрос, как их соединить?
</p>

<p>
	Все просто! Берем радио тюнер из OpenFM и сначала нажимаем пкм по динамику а затем по радио, готово!
</p>

<p>
	Затем возник еще один вопрос, а как нам транслировать наши аудио файлы? Можно конечно через гугл диск, но так как его могут заблокировать, будем использовать более легкую и надежную схему: для начала перейдем на сайт: <a href="https://fm.hinja.xyz" rel="external nofollow">https://fm.hinja.xyz</a> в нем нам надо нажать "Выбрать файл"
</p>

<p>
	<b>При загрузке нам надо соблюдать несколько правил:</b>
</p>

<p>
	<b>1. Формат который поддерживает OpenFM (это MPEG) </b>но вот вопрос как нам сделать mp3 в mpeg? Просто замените расширение или воспользуйтесь конвертером!
</p>

<p>
	<strong>2. Файл не должен содержать пробелов и русских букв! (пример: marshmallow_alone.mpeg)</strong>
</p>

<p>
	Далее после того как мы все загрузили нам надо получить ссылку, как это сделать? Когда вы выбрали файл и нажали загрузить у вас в левом верхнем углу будет ссылка то есть нас интересует только ссылка, она там одна (смотрите внимательнее)
</p>

<p>
	 
</p>

<p>
	Супер! Когда у нас есть ссылка мы можем вставить её в поле StreamURL и нажать кнопку плей и готово!!! Спасибо за прочтение
</p>

]]></description><guid isPermaLink="false">5456</guid><pubDate>Mon, 14 Mar 2022 16:01:43 +0000</pubDate></item><item><title>&#x41A;&#x430;&#x43A; &#x43B;&#x435;&#x433;&#x43A;&#x43E; &#x432;&#x43A;&#x43B;&#x44E;&#x447;&#x438;&#x442;&#x44C; &#x441;&#x432;&#x43E;&#x44E; &#x43C;&#x443;&#x437;&#x44B;&#x43A;&#x443; &#x432; OpenFM(&#x438; &#x43D;&#x435; &#x442;&#x43E;&#x43B;&#x44C;&#x43A;&#x43E;)</title><link>https://computercraft.ru/topic/3059-kak-legko-vklyuchit-svoyu-muzyku-v-openfmi-ne-tolko/</link><description><![CDATA[
<p>
	<span style="font-size:10px;">Если я где-то не прав или хотите что-то дополнить, то сообщите и объясните что.</span>
</p>

<p>
	И так. Для себя "легко и удобно" это нажать на пару кнопок и не париться.
</p>

<p>
	Для воспроизведения музыки в OpenFM нужна прямая ссылка на музыку или радио, ее не так легко бывает найти, а еще может захотеться, что бы играла любая своя музыка.
</p>

<p>
	<br>
	Всё что нужно сделать, это лишь скачать программу, которую я сделал, и половина уже готова.<br>
	В Minecraft заходим в блок Радио и вписываем в "<em>StreamURL</em>" "<em><a href="http://localhost" rel="">http://localhost</a></em>"(если вы играете с другом при помощи VPN туннеля(Hamachi, RadminVPN...), то впишите "<em>http://</em>"+ IPv4 <strong><u>хоста</u></strong>) и ждем пока буду выполнены следующие действия уже в программе.
</p>

<p>
	<span style="font-size:10px;">Если всё правильно сделать, то в браузере будет аналогичный результат.</span><br>
	<br>
	Программа+- проста в использовании<span>:</span>
</p>

<ol>
	<li>
		Открываем программу
	</li>
	<li>
		Нажимаем на кнопку если написано "<em>Not Hosting</em>"(кнопка отображает значение работы сервера).
	</li>
	<li>
		В нажимаем на кнопку "<em>Выбрать файл</em>" и выбираем <strong><u><em>музыку</em></u></strong>(не работает с видео, и форматами отличных от mp3, ogg и wav), или вставляем <strong><u>путь</u></strong> в пустое окно текста.
	</li>
</ol>

<p>
	 
</p>

<p>
	Теперь о изъянах:
</p>

<ol>
	<li>
		Нельзя поставить на паузу - мод OpenFM был ориентирован на постоянную подачу аудио(радио трансляция). Вместо этого музыка будет начинаться сначала. Также расширение в среде, где которой я делал программу, не позволяет(задумано и без костылей) вести прямой эфир.
	</li>
	<li>
		Файл отправляется, сразу после захода на сервер. Если вы подключились и начали слушать музыку, то можете не беспокоиться о том, включён ли хост.
	</li>
	<li>
		Может случиться баг, когда вы всё правильно сделали, а радио не хочет запускаться. В таком случае можете заново установить этот блок или перезайдите в мир.
	</li>
</ol>

<p>
	 
</p>

<p>
	Программу можно будет скачать по ссылке ниже(если у ваш антивирус найдёт там вирусы, то или у вас липовый антивирус, либо он очень старый, либо это связано с историей развития движка(в суме ему около 20 лет) и антивирусы не правильно распознают встроенные функции программы)
</p>

<p>
	 
</p>

<p>
	Программа будет развиваться если будут предложения, для ее улучшения.<br>
	<br>
	Программа:<a href="https://drive.google.com/open?id=16q7O0Cdi35QbKNHSISpbUDWsW3kCNQl8" rel="external nofollow">https://drive.google.com/open?id=16q7O0Cdi35QbKNHSISpbUDWsW3kCNQl8</a><br>
	Исходник(написан на Clickteam Fusion Developer R291.6):<a href="https://drive.google.com/open?id=1_UtEnlMuPWhlCCFiFt-2NDsscEF3oTep" rel="external nofollow">https://drive.google.com/open?id=1_UtEnlMuPWhlCCFiFt-2NDsscEF3oTep</a><br>
	<br>
	Изменено: планирую сделать программу в OpenComputers, для общения с локальным сайтом(будет возможно сделать внутриигровой выбор музыки с настоящего компьютера)
</p>

]]></description><guid isPermaLink="false">3059</guid><pubDate>Wed, 29 Jan 2020 13:38:24 +0000</pubDate></item><item><title>RC. &#x427;&#x442;&#x43E; &#x437;&#x430; &#x437;&#x432;&#x435;&#x440;&#x44C; &#x442;&#x430;&#x43A;&#x43E;&#x439;?</title><link>https://computercraft.ru/topic/1679-rc-chto-za-zver-takoy/</link><description><![CDATA[
<p>Если вы когда нибудь сталкивались с созданием серверов под <em>OpenOS</em>, вам знакома проблема блокирования всего компьютера. Его нельзя использовать, пока сервер не выключится. Некоторые придумывали свои велосипеды, которые запускали <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">event.listen</span> или <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">event.ignore</span>. Но не то это!<br> <br>Для таких вещей существует <em><strong>rc</strong></em>, в <em>OpenOS. </em>Сейчас я расскажу вам, что это за зверь, где он живет и зачем он нам.<br><br></p>
<hr>
<span style="font-size:24px;"><strong>Немного теории <span style="font-size:36px;"> <img src="https://computercraft.ru/uploads/emoticons/default_cool.png" alt="B-)"></span><span style="font-size:24px;"><strong> </strong></span></strong></span><br>Итак, все скрипты для <em>rc</em> хранятся в папочке <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">/etc/rc.d/</span>. Любой файл с расширением <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">.lua</span>, который находится там, является <em>rc-скриптом.</em><br><br>У такого скрипта все глобальные функции это команды. Запустить такую команду можно командой <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">rc &lt;имя скрипта, без расширения&gt; &lt;имя команды&gt;</span>. Например если мы создадим <strong>глобальную </strong>функцию <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">start</span> в файлике <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">/etc/rc.d/test.lua</span>, то запустив команду <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">rc test start</span> эта команда выполнится. Все просто.<br> <br>Получить список команд определенного скрипта можно при помощи команды <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">rc &lt;имя скрипта, без расширения&gt;</span>. <em>Например так:</em> <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">rc test</span>.<br> <br><strong>RC сам создает некоторые команды, хотя мы их можем переопределить:</strong>
<ul>
<li>
<span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">enable/disable</span>. Соответственно <em>включают/выключают </em>скрипт. Все <em>включенные </em>скрипты получат команду <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">start</span> при запуске компьютера.</li>
<li>
<span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">restart</span> <em>если есть <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">start и stop</span>. </em>Перезапускает скрипт, то есть поочередно запускает <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">stop и start</span>.</li>
</ul>
<p>Каждый скрипт можно конфигурировать. Конфиг находится в <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">/etc/rc.cfg</span>.<br>Формат файла прост:</p>
<pre class="ipsCode prettyprint">
&lt;имя скрипта&gt; = &lt;конфиг: все что угодно, таблица, текст, число&gt;
</pre>
<p>По сути это обычный <em>луа-файл</em>, все глобальные значения из которого считаются полями.</p>
<p>Каждый скрипт может получить доступ к своему конфигу. Конфиг записывается в переменную <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">args</span>.</p>
<p> </p>
<p>С теорией покончено, приступим к практике!</p>
<p> </p>
<p><span style="font-size:24px;"><strong>Практика</strong></span></p>
<p>Я предлагаю написать простой эхо-сервер. Он будет слушать определенный порт (из конфига), и отвечать на любое сообщение эхом.</p>
<p>Начнем!</p>
<p> </p>
<p>Создадим файл <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">/etc/rc,d/echo.lua</span>, и начнем писать в нем код.</p>
<p> </p>
<p>Нам понадобятся некоторые переменные</p>
<pre class="ipsCode prettyprint">
-- нам понадобятся библиотека event
-- что бы установить свой обработчик событий
local event = require("event")

-- еще нам нужна библиотека computer
-- что бы подключить компонент `modem`
local component = require("component")

-- будем считать количество ответов
-- зачем? для диванных аналитиков конечно!
local count = 0

-- будем хранить текущее положение
-- что б никто не запустил случайно сервер два раза
local started = false

-- сюда запишем прокси модема, когда убедимся что он есть
local modem

-- а сюда запишем рабочий порт
local port
</pre>
<p>Создадим обработчик события modem_message. Он будет вызываться при каждом сообщении по сетевой карте.</p>
<pre class="ipsCode prettyprint">
-- функция ниже будет запускаться
-- при каждом сообщении по сетевой плате
local function onModemMessage(_, _, snd, prt, _, ...)
  -- `_` в нашем понимании - неиспользуемый аргумент

  -- если порт сообщения не совпадает с портом
  -- из конфига, выходим
  print(prt)
  if prt ~= port then
    return
  end

  -- добавим еденицу к счетчику
  count = count + 1

  -- здесь мы уверены, что modem существует
  -- так как обработчик поставится только если у нас есть модем
  modem.send(snd, prt, ...)
  --         /     |    \
  -- получатель, порт, данные

  -- просто напросто пересылаем отправителю то что он
  -- отправил нам =)
end
</pre>
<p>Теперь мы добавим команду <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">start</span>, которая запустит наш сервер.</p>
<pre class="ipsCode prettyprint">
-- функция ниже глобальная, `local` нет.
-- потому _rc_ ее будет смело считать командой
-- а команда эта будет запускать наш сервер
function start()
  -- мы должны проверить, есть ли у нашего сервера
  -- сетевая карта
  if not component.isAvailable("modem") then
    -- если ее нет, мы выводим ошибку и выходим
    io.stderr:write("Сетевая карта не найдена!")
    return
  end

  -- еще нам нужно проверить, выключены ли мы
  -- если это не так, снова ошибка
  if started then
    io.stderr:write("Сервер уже запущен!")
    return
  end

  count = 0   -- сбросим счетчик
  started = true   -- теперь мы знаем, что с этого момента
                   -- сервер включен.

  port = args or 666
  -- args это переменная, в которую _rc_ запишет данные из конфига
  -- конфиг находится в /etc/rc.cfg
  -- но если в конфиге порт не настроен, используем дефолтный

  modem = component.modem
  -- мы проверили, что модем существует,
  -- поэтому смело его подключаем

  -- откроем порт
  modem.open(port)

  -- нам нужно сделать так, что бы все сообщения
  -- по сетевой карте обслуживались нашей функцией
  event.listen("modem_message", onModemMessage)
  -- ну а теперь мы точно включились!
end
</pre>
<p>Куда без команды <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">stop</span>? Добавим ее!</p>
<pre class="ipsCode prettyprint">
-- эта функция тоже глобальная, поэтому считаем ее командой
-- эта команда остановит сервер
function stop()
  -- мы должны проверить, включен ли вообще сервер
  -- если он не включен, какой толк его выключать, верно?
  if not started then
    -- если он не включен, выводим ошибку и выходим
    io.stderr:write("Сервер уже выключен!")
    return
  end

  count = 0   -- опять же сбрасываем счетчик
  started = false   -- запоминаем, что теперь
                    -- сервер выключен

  -- теперь нам нужно по-настоящему выключить сервер
  event.ignore("modem_message", onModemMessage)
  -- все! с этого момента сервер выключен, и не принимает сообщение
end
</pre>
<p>Еще самая малость, добавим команду <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">printCount</span>, которая будет отображать количество полученных сообщений.</p>
<pre class="ipsCode prettyprint">
-- и это тоже команда, думаю вы понимаете
-- а эта команда напишет количество отправленных сообщений
function printCount()
  -- выводить информацию будем только если сервер не запущен
  -- поэтому выведем ошибку, если он не включен
  if not started then
    io.stderr:write("Сервер выключен!")
    return
  end

  print(count)   -- пишем количество подключений
                 -- диванные аналитики ликуют!
end
</pre>
<p>Ну вот и все, программа сделана, диванные аналитики ликуют, инженеры недоумевают. <img src="https://computercraft.ru/uploads/emoticons/default_dirol.gif" alt=":dirol:"></p>
<p> </p>
<p><em><strong>Полный код: </strong></em></p>
<div class="ipsSpoiler" data-ipsspoiler="">
<div class="ipsSpoiler_header"><span></span></div>
<div class="ipsSpoiler_contents">
<p> </p>
<pre class="ipsCode prettyprint">
-- нам понадобятся библиотека event
-- что бы установить свой обработчик событий
local event = require("event")

-- еще нам нужна библиотека computer
-- что бы подключить компонент `modem`
local component = require("component")

-- будем считать количество ответов
-- зачем? для диванных аналитиков конечно!
local count = 0

-- будем хранить текущее положение
-- что б никто не запустил случайно сервер два раза
local started = false

-- сюда запишем прокси модема, когда убедимся что он есть
local modem

-- а сюда запишем рабочий порт
local port

-- функция ниже будет запускаться
local function onModemMessage(_, _, snd, prt, _, ...)
  -- `_` в нашем понимании - неиспользуемый аргумент

  -- если порт сообщения не совпадает с портом
  -- из конфига, выходим
  print(prt)
  if prt ~= port then
    return
  end

  -- добавим еденицу к счетчику
  count = count + 1

  -- здесь мы уверены, что modem существует
  -- так как обработчик поставится только если у нас есть модем
  modem.send(snd, prt, ...)
  --         /     |    \
  -- получатель, порт, данные

  -- просто напросто пересылаем отправителю то что он
  -- отправил нам =)
end

-- функция ниже глобальная, `local` нет.
-- потому _rc_ ее будет смело считать командой
-- а команда эта будет запускать наш сервер
function start()
  -- мы должны проверить, есть ли у нашего сервера
  -- сетевая карта
  if not component.isAvailable("modem") then
    -- если ее нет, мы выводим ошибку и выходим
    io.stderr:write("Сетевая карта не найдена!")
    return
  end

  -- еще нам нужно проверить, выключены ли мы
  -- если это не так, снова ошибка
  if started then
    io.stderr:write("Сервер уже запущен!")
    return
  end

  count = 0   -- сбросим счетчик
  started = true   -- теперь мы знаем, что с этого момента
                   -- сервер включен.

  port = args or 666
  -- args это переменная, в которую _rc_ запишет данные из конфига
  -- конфиг находится в /etc/rc.cfg
  -- но если в конфиге порт не настроен, используем дефолтный

  modem = component.modem
  -- мы проверили, что модем существует,
  -- поэтому смело его подключаем

  -- откроем порт
  modem.open(port)

  -- нам нужно сделать так, что бы все сообщения
  -- по сетевой карте обслуживались нашей функцией
  event.listen("modem_message", onModemMessage)
  -- ну а теперь мы точно включились!
end

-- эта функция тоже глобальная, поэтому считаем ее командой
-- эта команда остановит сервер
function stop()
  -- мы должны проверить, включен ли вообще сервер
  -- если он не включен, какой толк его выключать, верно?
  if not started then
    -- если он не включен, выводим ошибку и выходим
    io.stderr:write("Сервер уже выключен!")
    return
  end

  count = 0   -- опять же сбрасываем счетчик
  started = false   -- запоминаем, что теперь
                    -- сервер выключен

  -- теперь нам нужно по-настоящему выключить сервер
  event.ignore("modem_message", onModemMessage)
  -- все! с этого момента сервер выключен, и не принимает сообщение
end

-- и это тоже команда, думаю вы понимаете
-- а эта команда напишет количество отправленных сообщений
function printCount()
  -- выводить информацию будем только если сервер не запущен
  -- поэтому выведем ошибку, если он не включен
  if not started then
    io.stderr:write("Сервер выключен!")
    return
  end

  print(count)   -- пишем количество подключений
                 -- диванные аналитики ликуют!
end
</pre>
<p> </p>
</div>
</div>
<p> </p>
<p> </p>
<p> </p>
<p><span style="font-size:24px;"><strong>Время QA! <span style="font-size:36px;"> <img src="https://computercraft.ru/uploads/emoticons/default_crazy_pilot.gif" alt=":crazy_pilot:"></span></strong></span></p>
<p> </p>
<p>Симулируем Васю Пупкина...</p>
<p> </p>
<div class="ipsSpoiler" data-ipsspoiler="">
<div class="ipsSpoiler_header"><span></span></div>
<div class="ipsSpoiler_contents">
<p> </p>
<p><span style="font-size:24px;"><strong><img src="http://image.prntscr.com/image/44e93ee134de491ab6b7519862f020ff.png" alt="44e93ee134de491ab6b7519862f020ff.png"></strong></span></p>
<p> </p>
</div>
</div>
<p> </p>
<p> </p>
<p>А вот уже на другом компьютере отправлено сообщение на работающий сервер.</p>
<p> </p>
<div class="ipsSpoiler" data-ipsspoiler="">
<div class="ipsSpoiler_header"><span></span></div>
<div class="ipsSpoiler_contents">
<p> </p>
<p><img src="http://image.prntscr.com/image/7822297da5f14a0baf29a59a0228377e.png" alt="7822297da5f14a0baf29a59a0228377e.png"></p>
<p> </p>
</div>
</div>
<p> </p>
<p> </p>
<p>Счетчик тоже работает.</p>
<p> </p>
<div class="ipsSpoiler" data-ipsspoiler="">
<div class="ipsSpoiler_header"><span></span></div>
<div class="ipsSpoiler_contents">
<p> </p>
<p><img src="http://image.prntscr.com/image/983e4a7a0519474593e344c96969d00a.png" alt="983e4a7a0519474593e344c96969d00a.png"></p>
<p> </p>
</div>
</div>
<p> </p>
<p> </p>
<p>Установим значение в конфиге.</p>
<p> </p>
<div class="ipsSpoiler" data-ipsspoiler="">
<div class="ipsSpoiler_header"><span></span></div>
<div class="ipsSpoiler_contents">
<p> </p>
<p><img src="http://image.prntscr.com/image/0a120b12376d4428b7cd6753bb401928.png" alt="0a120b12376d4428b7cd6753bb401928.png"></p>
<p> </p>
</div>
</div>
<p> </p>
<p> </p>
<p>Проверим...</p>
<p> </p>
<div class="ipsSpoiler" data-ipsspoiler="">
<div class="ipsSpoiler_header"><span></span></div>
<div class="ipsSpoiler_contents">
<p> </p>
<p><img src="http://image.prntscr.com/image/491e0b36172d47d3b33511747b0c5a3a.png" alt="491e0b36172d47d3b33511747b0c5a3a.png"></p>
<p> </p>
</div>
</div>
<p> </p>
<p> </p>
<p>Все работает, инженеры ликуют!  <img src="https://computercraft.ru/uploads/emoticons/default_smile.png" alt=":)"></p>
<p> </p>
<p></p>
<hr>
<p> </p>
<p>Такую систему очень удобно использовать для всяческих серверов. Сервер может спокойно работать в фоне, а в главном потоке спокойно можно запускать консоль сервера, интерпретатор луа, <strike> rm -rf / </strike> ...</p>
<p> </p>
<p><em><strong>Enjoy!</strong></em></p>

]]></description><guid isPermaLink="false">1679</guid><pubDate>Wed, 22 Jun 2016 16:00:59 +0000</pubDate></item><item><title>&#x41A;&#x430;&#x43A; &#x441;&#x434;&#x435;&#x43B;&#x430;&#x442;&#x44C; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E;&#x439; &#x438;&#x43D;&#x441;&#x442;&#x430;&#x43B;&#x44F;&#x442;&#x43E;&#x440; &#x43D;&#x430; &#x43E;&#x441;&#x43D;&#x43E;&#x432;&#x435; github</title><link>https://computercraft.ru/topic/4001-kak-sdelat-prostoy-instalyator-na-osnove-github/</link><description><![CDATA[
<p>
	Предположим, Вы написали крутую программу. И она размазана, скажем на 10 файлов. Или нет, лучше на 50. И Вам захотелось сделать инсталятор. Первая мысль - вручную заливать все файлы на pastebin, потом писать инсталятор, в нём же вручную прописывать коды файлов на pastebin, и их целевые адреса в системе. Это предложение даже читать больно, не то что совершать описанное в нём действие. Но, выход есть. И так, нам понадобятся две вещи:
</p>

<ul>
	<li>
		Github аккаунт
	</li>
	<li>
		Хостинг, на котором можно разместить серверную часть.
	</li>
</ul>

<p>
	И если с первым всё предельно понятно, то со вторым возникает вопрс: А где его, собственно, взять? Вариантов много. Можно арендовать VPS, поднять сервер на домашнем компьютере или Raspberry Pi, можно воспользоваться услугами таких сайтов как Heroku или PythonAnywhere. Последний вариант примечателен тем, что он полностью бесплатный. И так, какой из сайтов выбрать? PythonAnywhere имеет более ограниченный функционал, по сравнению с Heroku. Но, при этом он намного легче в настройке и эксплуатации, так что остановимся на нём. Далее по пунктам:
</p>

<p>
	1)Заливаем программу на гитхаб.
</p>

<p>
	2)Переходим по <a href="https://github.com/settings/tokens" rel="external nofollow">ссылке</a>, и создаём токен. Ставим только одну галочку:
</p>

<p>
	<img class="ipsImage ipsImage_thumbnailed" data-fileid="2091" data-ratio="24.03" width="724" alt="1866525534_.png.c35ef06fc221428b52faeef70cfb0fc2.png" src="https://computercraft.ru/uploads/monthly_2021_03/1866525534_.png.c35ef06fc221428b52faeef70cfb0fc2.png">
</p>

<p>
	После создания <s>запоминаем</s> копируем токен, он нам дальше пригодится. <strong><span style="color:#ff0000;">Обращаю внимание, что токен нужно держать в секрете. </span></strong>
</p>

<p>
	3) На этом этапе нам нужен хостинг. Я рассмотрю пример с <a href="http://www.pythonanywhere.com" rel="external nofollow">www.pythonanywhere.com</a> . Идём на сайт, регистрируем аккаунт и создаём Flask приложение. В этом нет ничего сложного, если знать английский. Находим файл flask_app.py, и вставляем в него следующее содержимое:
</p>

<pre class="ipsCode prettyprint prettyprinted">
<span class="kwd">from</span><span class="pln"> flask </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Flask</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> flask </span><span class="kwd">import</span><span class="pln"> request
</span><span class="kwd">import</span><span class="pln"> requests
</span><span class="kwd">import</span><span class="pln"> json

</span><span class="kwd">def</span><span class="pln"> request_url</span><span class="pun">(</span><span class="pln">url</span><span class="pun">,</span><span class="pln"> result</span><span class="pun">):</span><span class="pln">
    r </span><span class="pun">=</span><span class="pln"> requests</span><span class="pun">.</span><span class="pln">get</span><span class="pun">(</span><span class="pln">url</span><span class="pun">)</span><span class="pln">
    j </span><span class="pun">=</span><span class="pln"> json</span><span class="pun">.</span><span class="pln">loads</span><span class="pun">(</span><span class="pln">r</span><span class="pun">.</span><span class="pln">text</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">for</span><span class="pln"> x </span><span class="kwd">in</span><span class="pln"> j</span><span class="pun">:</span><span class="pln">
        </span><span class="kwd">if</span><span class="pln"> x</span><span class="pun">[</span><span class="str">"type"</span><span class="pun">]</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> </span><span class="str">"file"</span><span class="pun">:</span><span class="pln">
            result </span><span class="pun">=</span><span class="pln"> result </span><span class="pun">+</span><span class="pln"> </span><span class="str">"\""</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> x</span><span class="pun">[</span><span class="str">"path"</span><span class="pun">]</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="str">"\","</span><span class="pln">
        </span><span class="kwd">else</span><span class="pun">:</span><span class="pln">
            result </span><span class="pun">=</span><span class="pln"> request_url</span><span class="pun">(</span><span class="pln">x</span><span class="pun">[</span><span class="str">"url"</span><span class="pun">],</span><span class="pln">result</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> result

app </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Flask</span><span class="pun">(</span><span class="pln">__name__</span><span class="pun">)</span><span class="pln">

</span><span class="com">#@app.route('/',methods=['POST'])</span><span class="pln">
</span><span class="kwd">def</span><span class="pln"> main</span><span class="pun">():</span><span class="pln">
    uname </span><span class="pun">=</span><span class="pln"> </span><span class="str">""</span><span class="com"># Сюда нужно прописать логин аккаунта Github</span><span class="pln">
    token </span><span class="pun">=</span><span class="pln"> </span><span class="str">""</span><span class="com"># А сюда полученный токен</span><span class="pln">
    </span><span class="kwd">if</span><span class="pln"> uname </span><span class="pun">!=</span><span class="pln"> request</span><span class="pun">.</span><span class="pln">args</span><span class="pun">[</span><span class="str">"owner"</span><span class="pun">]:</span><span class="pln">
        </span><span class="kwd">return</span><span class="pln"> </span><span class="str">"{}"</span><span class="pln">
    result </span><span class="pun">=</span><span class="pln"> request_url</span><span class="pun">(</span><span class="str">"https://"</span><span class="pun">+</span><span class="pln">uname</span><span class="pun">+</span><span class="str">":"</span><span class="pun">+</span><span class="pln">token</span><span class="pun">+</span><span class="str">"@api.github.com/repos/"</span><span class="pun">+</span><span class="pln">request</span><span class="pun">.</span><span class="pln">args</span><span class="pun">[</span><span class="str">"owner"</span><span class="pun">]+</span><span class="str">"/"</span><span class="pun">+</span><span class="pln">request</span><span class="pun">.</span><span class="pln">args</span><span class="pun">[</span><span class="str">"repo"</span><span class="pun">]+</span><span class="str">"/contents"</span><span class="pun">+</span><span class="pln">request</span><span class="pun">.</span><span class="pln">args</span><span class="pun">[</span><span class="str">"path"</span><span class="pun">]+</span><span class="str">"?ref="</span><span class="pun">+</span><span class="pln">request</span><span class="pun">.</span><span class="pln">args</span><span class="pun">[</span><span class="str">"ref"</span><span class="pun">],</span><span class="str">"{"</span><span class="pun">)</span><span class="pln">
    result </span><span class="pun">=</span><span class="pln"> result </span><span class="pun">+</span><span class="pln"> </span><span class="str">"}"</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> result

app</span><span class="pun">.</span><span class="pln">add_url_rule</span><span class="pun">(</span><span class="str">"/"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"main"</span><span class="pun">,</span><span class="pln"> main</span><span class="pun">,</span><span class="pln">methods</span><span class="pun">=[</span><span class="str">'GET'</span><span class="pun">])</span></pre>

<p>
	Заполняем поля uname и token, и можно двигаться дальше.
</p>

<p>
	4) На своём компьютере создаём Lua файл, и вставляем в него:
</p>

<pre class="ipsCode prettyprint lang-lua prettyprinted">
<span class="kwd">local</span><span class="pln"> internet </span><span class="pun">=</span><span class="pln"> require</span><span class="pun">(</span><span class="str">"internet"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">local</span><span class="pln"> fs </span><span class="pun">=</span><span class="pln"> require</span><span class="pun">(</span><span class="str">"filesystem"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">local</span><span class="pln"> shell </span><span class="pun">=</span><span class="pln"> require</span><span class="pun">(</span><span class="str">"shell"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">local</span><span class="pln"> ser </span><span class="pun">=</span><span class="pln"> require</span><span class="pun">(</span><span class="str">"serialization"</span><span class="pun">)</span><span class="pln">

</span><span class="kwd">local</span><span class="pln"> host </span><span class="pun">=</span><span class="pln"> </span><span class="str">""</span><span class="com">--Хост, на котором расположена серверная часть</span><span class="pln">
</span><span class="kwd">local</span><span class="pln"> owner </span><span class="pun">=</span><span class="pln"> </span><span class="str">""</span><span class="com">--Логин аккаунта Github</span><span class="pln">
</span><span class="kwd">local</span><span class="pln"> repo </span><span class="pun">=</span><span class="pln"> </span><span class="str">""</span><span class="com">--Название репозитория</span><span class="pln">
</span><span class="kwd">local</span><span class="pln"> ref </span><span class="pun">=</span><span class="pln"> </span><span class="str">"master"</span><span class="com">--Название ветки</span><span class="pln">
</span><span class="kwd">local</span><span class="pln"> path </span><span class="pun">=</span><span class="pln"> </span><span class="str">"/"</span><span class="com">--Путь к папке, из которой скачивать файлы</span><span class="pln">
</span><span class="kwd">local</span><span class="pln"> deploy_to </span><span class="pun">=</span><span class="pln"> </span><span class="str">"/"</span><span class="com">--Куда скачивать файлы</span><span class="pln">

</span><span class="kwd">function</span><span class="pln"> request</span><span class="pun">(</span><span class="pln">url</span><span class="pun">)</span><span class="pln">
  </span><span class="kwd">local</span><span class="pln"> data </span><span class="pun">=</span><span class="pln"> </span><span class="str">""</span><span class="pln">
  </span><span class="kwd">local</span><span class="pln"> result</span><span class="pun">,</span><span class="pln"> response </span><span class="pun">=</span><span class="pln"> pcall</span><span class="pun">(</span><span class="pln">internet</span><span class="pun">.</span><span class="pln">request</span><span class="pun">,</span><span class="pln"> url</span><span class="pun">)</span><span class="pln">
  </span><span class="kwd">if</span><span class="pln"> result </span><span class="kwd">then</span><span class="pln">
    </span><span class="kwd">local</span><span class="pln"> result </span><span class="pun">=</span><span class="pln"> pcall</span><span class="pun">(</span><span class="kwd">function</span><span class="pun">()</span><span class="pln">
      </span><span class="kwd">for</span><span class="pln"> chunk </span><span class="kwd">in</span><span class="pln"> response </span><span class="kwd">do</span><span class="pln">
        data </span><span class="pun">=</span><span class="pln"> data </span><span class="pun">..</span><span class="pln"> chunk
      </span><span class="kwd">end</span><span class="pln">
    </span><span class="kwd">end</span><span class="pun">)</span><span class="pln">
  </span><span class="kwd">end</span><span class="pln">
  </span><span class="kwd">return</span><span class="pln"> data  
</span><span class="kwd">end</span><span class="pln">

files </span><span class="pun">=</span><span class="pln"> ser</span><span class="pun">.</span><span class="pln">unserialize</span><span class="pun">(</span><span class="pln">request</span><span class="pun">(</span><span class="str">"http://"</span><span class="pun">..</span><span class="pln">host</span><span class="pun">..</span><span class="str">"/?owner="</span><span class="pun">..</span><span class="pln">owner</span><span class="pun">..</span><span class="str">"&amp;repo="</span><span class="pun">..</span><span class="pln">repo</span><span class="pun">..</span><span class="str">"&amp;path="</span><span class="pun">..</span><span class="pln">path</span><span class="pun">..</span><span class="str">"&amp;ref="</span><span class="pun">..</span><span class="pln">ref</span><span class="pun">))</span><span class="pln">

</span><span class="kwd">for</span><span class="pln"> _</span><span class="pun">,</span><span class="pln">v </span><span class="kwd">in</span><span class="pln"> pairs</span><span class="pun">(</span><span class="pln">files</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">do</span><span class="pln">
  </span><span class="kwd">local</span><span class="pln"> pth </span><span class="pun">=</span><span class="pln"> deploy_to</span><span class="pun">..</span><span class="pln">v
  </span><span class="kwd">if</span><span class="pln"> </span><span class="kwd">not</span><span class="pln"> fs</span><span class="pun">.</span><span class="pln">exists</span><span class="pun">(</span><span class="pln">pth</span><span class="pun">:</span><span class="pln">match</span><span class="pun">(</span><span class="str">".*/"</span><span class="pun">))</span><span class="pln"> </span><span class="kwd">then</span><span class="pln"> fs</span><span class="pun">.</span><span class="pln">makeDirectory</span><span class="pun">(</span><span class="pln">pth</span><span class="pun">:</span><span class="pln">match</span><span class="pun">(</span><span class="str">".*/"</span><span class="pun">))</span><span class="pln"> </span><span class="kwd">end</span><span class="pln">
  shell</span><span class="pun">.</span><span class="pln">execute</span><span class="pun">(</span><span class="str">"wget -f "</span><span class="pun">..</span><span class="str">"https://raw.githubusercontent.com/"</span><span class="pun">..</span><span class="pln">owner</span><span class="pun">..</span><span class="str">"/"</span><span class="pun">..</span><span class="pln">repo</span><span class="pun">..</span><span class="str">"/"</span><span class="pun">..</span><span class="pln">ref</span><span class="pun">..</span><span class="str">"/"</span><span class="pun">..</span><span class="pln">v</span><span class="pun">..</span><span class="str">" "</span><span class="pun">..</span><span class="pln">pth</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">end</span></pre>

<p>
	Заполняем поля, и готово.
</p>

]]></description><guid isPermaLink="false">4001</guid><pubDate>Wed, 24 Feb 2021 17:42:59 +0000</pubDate></item><item><title>TypeScript to Lua</title><link>https://computercraft.ru/topic/3028-typescript-to-lua/</link><description><![CDATA[
<p style="text-align:center;">
	 
</p>

<p style="text-align:center;">
	 
</p>

<p style="text-align:center;">
	 
</p>

<p style="text-align:center;">
	 
</p>

<p style="text-align:center;">
	<img alt="512px-TypeScript_Logo_(Blue).svg.png" class="ipsImage" data-ratio="24.80" height="127" width="512" src="https://upload.wikimedia.org/wikipedia/commons/thumb/2/29/TypeScript_Logo_(Blue).svg/512px-TypeScript_Logo_(Blue).svg.png">
</p>

<p style="text-align:center;">
	 
</p>

<p style="text-align:center;">
	 
</p>

<p style="text-align:center;">
	 
</p>

<p style="text-align:center;">
	 
</p>

<p>
	<strong>Вместо вступления:</strong>
</p>

<p>
	Я не считаю C-подобный синтаксис лучше синтаксиса lua и не буду заставлять вас переписывать все ваши программы на TypeScript! Я просто хочу поделится с вами альтернативой и рассказать про ее преимущества и недостатки.
</p>

<p>
	 
</p>

<p>
	<span style="font-size:22px;"><strong># Что такое TypeScript?</strong></span>
</p>

<p>
	<span>TypeScript — язык программирования, представленный Microsoft в 2012 году и позиционируемый как средство разработки веб-приложений. </span>Он создан для расширения JavaScript и он компилируется в JavaScript, но также существует <a href="https://github.com/TypeScriptToLua/TypeScriptToLua" rel="external nofollow">инструмент</a> для преобразования TypeScript кода в Lua. Вам может показаться, что этот транслятор крайне ограничен, но, поверьте мне, его возможности впечатляют.
</p>

<p>
	 
</p>

<p>
	<span style="font-size:22px;"><strong># Почему его стоит попробовать?</strong></span>
</p>

<p>
	Я сначала продемонстрирую некоторые возможности TypeScript графически, а потом подробно расскажу про установку и настройку необходимых инструментов. Я покажу вам далеко не все возможности TypeScript, а только самые основные и интересные.
</p>

<p>
	Из-за большого размера контент каждого раздела будет скрыт под спойлер.
</p>

<p>
	 
</p>

<p>
	<strong><span style="font-size:18px;">1. Статический анализ</span></strong>
</p>

<div class="ipsSpoiler" data-ipsspoiler="">
	<div class="ipsSpoiler_header">
		<span>Скрытый текст</span>
	</div>

	<div class="ipsSpoiler_contents">
		<p>
			Системы типов JavaScript и Lua во многом похожи, и потому они имеют некоторые общие проблемы, которые может решить TypeScript.
		</p>

		<p>
			 
		</p>

		<p>
			<strong>1.1 Проверка типов</strong>
		</p>

		<p>
			Если функция или метод явно требует среди аргументов число, TypeScript не допустит что-то отличное от числа.
		</p>

		<p>
			<img alt="image.png.d5fc0b4b741592cf190d3a77c124c785.png" class="ipsImage ipsImage_thumbnailed" data-fileid="1801" data-ratio="9.65" width="933" src="https://computercraft.ru/uploads/monthly_2020_01/image.png.d5fc0b4b741592cf190d3a77c124c785.png">
		</p>

		<p>
			 
		</p>

		<p>
			Lua тоже сообщит об этом, но только после запуска скрипта.
		</p>

		<p>
			<img alt="image.png.21ad2183b440c8b07a9b118bf2b45e19.png" class="ipsImage ipsImage_thumbnailed" data-fileid="1802" data-ratio="51.47" width="645" src="https://computercraft.ru/uploads/monthly_2020_01/image.png.21ad2183b440c8b07a9b118bf2b45e19.png">
		</p>

		<p>
			 
		</p>

		<p>
			<strong>1.2 Проверка существования полей и методов</strong>
		</p>

		<p>
			Если вы попытаетесь обратится к несуществующему полю или методу, TypeScript сообщит вам об этом и даже поможет исправить, если вы, например, опечатались.
		</p>

		<p>
			<img alt="image.png.e6cf4d71e5b073e5d2595257259c12fa.png" class="ipsImage ipsImage_thumbnailed" data-fileid="1807" data-ratio="16.85" width="896" src="https://computercraft.ru/uploads/monthly_2020_01/image.png.e6cf4d71e5b073e5d2595257259c12fa.png">
		</p>

		<p>
			 
		</p>

		<p>
			В Lua мы узнаем об этом только после запуска скрипта.
		</p>

		<p>
			<img alt="image.png.610e5cdb29c1d11ea667e1c0587ecb49.png" class="ipsImage ipsImage_thumbnailed" data-fileid="1808" data-ratio="44.84" width="669" src="https://computercraft.ru/uploads/monthly_2020_01/image.png.610e5cdb29c1d11ea667e1c0587ecb49.png">
		</p>
	</div>
</div>

<p>
	 
</p>

<p>
	<strong><span style="font-size:18px;">2. Автодополнение</span></strong>
</p>

<div class="ipsSpoiler" data-ipsspoiler="">
	<div class="ipsSpoiler_header">
		<span>Скрытый текст</span>
	</div>

	<div class="ipsSpoiler_contents">
		<p>
			Благодаря статической типизации, редактор кода может подсказывать методы и поля объекта.
		</p>

		<p>
			<img alt="image.png.f2bb10226d369c05b792b6e659dfee3f.png" class="ipsImage ipsImage_thumbnailed" data-fileid="1809" data-ratio="19.61" width="872" src="https://computercraft.ru/uploads/monthly_2020_01/image.png.f2bb10226d369c05b792b6e659dfee3f.png">
		</p>

		<p>
			 
		</p>

		<p>
			Или показать параметры, которые принимает метод.
		</p>

		<p>
			<img alt="image.png.e05fe44e605ca1ca6b43ba5ae2aa6ea8.png" class="ipsImage ipsImage_thumbnailed" data-fileid="1810" data-ratio="42.16" width="657" src="https://computercraft.ru/uploads/monthly_2020_01/image.png.e05fe44e605ca1ca6b43ba5ae2aa6ea8.png">
		</p>

		<p>
			 
		</p>

		<p>
			Или текст документации.
		</p>

		<p>
			<img alt="image.png" class="ipsImage" data-ratio="30.63" height="196" width="640" src="https://i.ibb.co/wwx7HSq/image.png">
		</p>
	</div>
</div>

<p>
	 
</p>

<p>
	<strong><span style="font-size:18px;">3. ООП</span></strong>
</p>

<div class="ipsSpoiler" data-ipsspoiler="">
	<div class="ipsSpoiler_header">
		<span>Скрытый текст</span>
	</div>

	<div class="ipsSpoiler_contents">
		<p>
			<strong>3.1 Классы</strong>
		</p>

		<pre class="ipsCode prettyprint lang-javascript prettyprinted">

<span class="kwd">class</span><span class="pln"> </span><span class="typ">Player</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    username</span><span class="pun">:</span><span class="pln"> string</span><span class="pun">;</span><span class="pln">

    </span><span class="kwd">constructor</span><span class="pun">(</span><span class="pln">username</span><span class="pun">:</span><span class="pln"> string</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">username </span><span class="pun">=</span><span class="pln"> username</span><span class="pun">;</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">

    greet</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        print</span><span class="pun">(</span><span class="str">"Привет, "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">username </span><span class="pun">+</span><span class="pln"> </span><span class="str">"!"</span><span class="pun">);</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="kwd">let</span><span class="pln"> alex </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Player</span><span class="pun">(</span><span class="str">"alex"</span><span class="pun">);</span><span class="pln">
alex</span><span class="pun">.</span><span class="pln">greet</span><span class="pun">();</span><span class="pln"> </span><span class="com">// Привет, Alex!</span></pre>

		<p>
			 
		</p>

		<p>
			Сгенерированный lua код
		</p>

		<div class="ipsSpoiler" data-ipsspoiler="">
			<div class="ipsSpoiler_header">
				<span>Скрытый текст</span>
			</div>

			<div class="ipsSpoiler_contents">
				<pre class="ipsCode prettyprint lang-lua prettyprinted">


<span class="com">--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]</span><span class="pln">
Player </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{}</span><span class="pln">
Player</span><span class="pun">.</span><span class="pln">name </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Player"</span><span class="pln">
Player</span><span class="pun">.</span><span class="pln">__index </span><span class="pun">=</span><span class="pln"> Player
Player</span><span class="pun">.</span><span class="pln">prototype </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{}</span><span class="pln">
Player</span><span class="pun">.</span><span class="pln">prototype</span><span class="pun">.</span><span class="pln">__index </span><span class="pun">=</span><span class="pln"> Player</span><span class="pun">.</span><span class="pln">prototype
Player</span><span class="pun">.</span><span class="pln">prototype</span><span class="pun">.</span><span class="pln">constructor </span><span class="pun">=</span><span class="pln"> Player
</span><span class="kwd">function</span><span class="pln"> Player</span><span class="pun">.</span><span class="pln">new</span><span class="pun">(...)</span><span class="pln">
    </span><span class="kwd">local</span><span class="pln"> self </span><span class="pun">=</span><span class="pln"> setmetatable</span><span class="pun">({},</span><span class="pln"> Player</span><span class="pun">.</span><span class="pln">prototype</span><span class="pun">)</span><span class="pln">
    self</span><span class="pun">:</span><span class="pln">____constructor</span><span class="pun">(...)</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> self
</span><span class="kwd">end</span><span class="pln">
</span><span class="kwd">function</span><span class="pln"> Player</span><span class="pun">.</span><span class="pln">prototype</span><span class="pun">.</span><span class="pln">____constructor</span><span class="pun">(</span><span class="pln">self</span><span class="pun">,</span><span class="pln"> username</span><span class="pun">)</span><span class="pln">
    self</span><span class="pun">.</span><span class="pln">username </span><span class="pun">=</span><span class="pln"> username
</span><span class="kwd">end</span><span class="pln">
</span><span class="kwd">function</span><span class="pln"> Player</span><span class="pun">.</span><span class="pln">prototype</span><span class="pun">.</span><span class="pln">greet</span><span class="pun">(</span><span class="pln">self</span><span class="pun">)</span><span class="pln">
    print</span><span class="pun">(</span><span class="str">"Привет, "</span><span class="pln"> </span><span class="pun">..</span><span class="pln"> tostring</span><span class="pun">(</span><span class="pln">self</span><span class="pun">.</span><span class="pln">username</span><span class="pun">)</span><span class="pln"> </span><span class="pun">..</span><span class="pln"> </span><span class="str">"!"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">end</span><span class="pln">
</span><span class="kwd">local</span><span class="pln"> alex </span><span class="pun">=</span><span class="pln"> Player</span><span class="pun">.</span><span class="pln">new</span><span class="pun">(</span><span class="str">"alex"</span><span class="pun">)</span><span class="pln">
alex</span><span class="pun">:</span><span class="pln">greet</span><span class="pun">()</span></pre>

				<p>
					 
				</p>
			</div>
		</div>

		<p>
			 
		</p>

		<p>
			<strong>3.2 Модификаторы доступа</strong>
		</p>

		<p>
			<img alt="image.png" class="ipsImage" data-ratio="35.63" height="228" width="640" src="https://i.ibb.co/Y3992G4/image.png">
		</p>

		<p>
			 
		</p>

		<p>
			<strong>3.3 Наследование</strong>
		</p>

		<pre class="ipsCode prettyprint lang-javascript prettyprinted">

<span class="kwd">class</span><span class="pln"> </span><span class="typ">Player</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    username</span><span class="pun">:</span><span class="pln"> string</span><span class="pun">;</span><span class="pln">

    </span><span class="kwd">constructor</span><span class="pun">(</span><span class="pln">username</span><span class="pun">:</span><span class="pln"> string</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">username </span><span class="pun">=</span><span class="pln"> username</span><span class="pun">;</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="kwd">class</span><span class="pln"> </span><span class="typ">Alex</span><span class="pln"> extends </span><span class="typ">Player</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">constructor</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        super</span><span class="pun">(</span><span class="str">"Alex"</span><span class="pun">);</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="kwd">let</span><span class="pln"> alex </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Alex</span><span class="pun">();</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">alex</span><span class="pun">.</span><span class="pln">username</span><span class="pun">);</span><span class="pln"> </span><span class="com">// Alex</span></pre>

		<p>
			 
		</p>

		<p>
			Сгенерированный lua код
		</p>

		<div class="ipsSpoiler" data-ipsspoiler="">
			<div class="ipsSpoiler_header">
				<span>Скрытый текст</span>
			</div>

			<div class="ipsSpoiler_contents">
				<pre class="ipsCode prettyprint lang-lua prettyprinted">


<span class="com">--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]</span><span class="pln">
Player </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{}</span><span class="pln">
Player</span><span class="pun">.</span><span class="pln">name </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Player"</span><span class="pln">
Player</span><span class="pun">.</span><span class="pln">__index </span><span class="pun">=</span><span class="pln"> Player
Player</span><span class="pun">.</span><span class="pln">prototype </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{}</span><span class="pln">
Player</span><span class="pun">.</span><span class="pln">prototype</span><span class="pun">.</span><span class="pln">__index </span><span class="pun">=</span><span class="pln"> Player</span><span class="pun">.</span><span class="pln">prototype
Player</span><span class="pun">.</span><span class="pln">prototype</span><span class="pun">.</span><span class="pln">constructor </span><span class="pun">=</span><span class="pln"> Player
</span><span class="kwd">function</span><span class="pln"> Player</span><span class="pun">.</span><span class="pln">new</span><span class="pun">(...)</span><span class="pln">
    </span><span class="kwd">local</span><span class="pln"> self </span><span class="pun">=</span><span class="pln"> setmetatable</span><span class="pun">({},</span><span class="pln"> Player</span><span class="pun">.</span><span class="pln">prototype</span><span class="pun">)</span><span class="pln">
    self</span><span class="pun">:</span><span class="pln">____constructor</span><span class="pun">(...)</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> self
</span><span class="kwd">end</span><span class="pln">
</span><span class="kwd">function</span><span class="pln"> Player</span><span class="pun">.</span><span class="pln">prototype</span><span class="pun">.</span><span class="pln">____constructor</span><span class="pun">(</span><span class="pln">self</span><span class="pun">,</span><span class="pln"> username</span><span class="pun">)</span><span class="pln">
    self</span><span class="pun">.</span><span class="pln">username </span><span class="pun">=</span><span class="pln"> username
</span><span class="kwd">end</span><span class="pln">
Alex </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{}</span><span class="pln">
Alex</span><span class="pun">.</span><span class="pln">name </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Alex"</span><span class="pln">
Alex</span><span class="pun">.</span><span class="pln">__index </span><span class="pun">=</span><span class="pln"> Alex
Alex</span><span class="pun">.</span><span class="pln">prototype </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{}</span><span class="pln">
Alex</span><span class="pun">.</span><span class="pln">prototype</span><span class="pun">.</span><span class="pln">__index </span><span class="pun">=</span><span class="pln"> Alex</span><span class="pun">.</span><span class="pln">prototype
Alex</span><span class="pun">.</span><span class="pln">prototype</span><span class="pun">.</span><span class="pln">constructor </span><span class="pun">=</span><span class="pln"> Alex
Alex</span><span class="pun">.</span><span class="pln">____super </span><span class="pun">=</span><span class="pln"> Player
setmetatable</span><span class="pun">(</span><span class="pln">Alex</span><span class="pun">,</span><span class="pln"> Alex</span><span class="pun">.</span><span class="pln">____super</span><span class="pun">)</span><span class="pln">
setmetatable</span><span class="pun">(</span><span class="pln">Alex</span><span class="pun">.</span><span class="pln">prototype</span><span class="pun">,</span><span class="pln"> Alex</span><span class="pun">.</span><span class="pln">____super</span><span class="pun">.</span><span class="pln">prototype</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">function</span><span class="pln"> Alex</span><span class="pun">.</span><span class="pln">new</span><span class="pun">(...)</span><span class="pln">
    </span><span class="kwd">local</span><span class="pln"> self </span><span class="pun">=</span><span class="pln"> setmetatable</span><span class="pun">({},</span><span class="pln"> Alex</span><span class="pun">.</span><span class="pln">prototype</span><span class="pun">)</span><span class="pln">
    self</span><span class="pun">:</span><span class="pln">____constructor</span><span class="pun">(...)</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> self
</span><span class="kwd">end</span><span class="pln">
</span><span class="kwd">function</span><span class="pln"> Alex</span><span class="pun">.</span><span class="pln">prototype</span><span class="pun">.</span><span class="pln">____constructor</span><span class="pun">(</span><span class="pln">self</span><span class="pun">)</span><span class="pln">
    Player</span><span class="pun">.</span><span class="pln">prototype</span><span class="pun">.</span><span class="pln">____constructor</span><span class="pun">(</span><span class="pln">self</span><span class="pun">,</span><span class="pln"> </span><span class="str">"Alex"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">end</span><span class="pln">
</span><span class="kwd">local</span><span class="pln"> alex </span><span class="pun">=</span><span class="pln"> Alex</span><span class="pun">.</span><span class="pln">new</span><span class="pun">()</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">alex</span><span class="pun">.</span><span class="pln">username</span><span class="pun">)</span></pre>

				<p>
					 
				</p>
			</div>
		</div>

		<p>
			 
		</p>
	</div>
</div>

<p>
	 
</p>

<p>
	<strong><span style="font-size:18px;">4. Стандартная библиотека и возможности языка</span></strong>
</p>

<div class="ipsSpoiler" data-ipsspoiler="">
	<div class="ipsSpoiler_header">
		<span>Скрытый текст</span>
	</div>

	<div class="ipsSpoiler_contents">
		<p>
			Многие методы стандартных типов TypeScript (такие как массивы и строки) также могут быть транслированы в lua.
		</p>

		<p>
			 
		</p>

		<p>
			<strong>4.1 Получение всех четных чисел массива, возведение в квадрат и соединение в строку через запятую</strong>
		</p>

		<pre class="ipsCode prettyprint lang-javascript prettyprinted">

<span class="kwd">const</span><span class="pln"> items </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="lit">4</span><span class="pun">,</span><span class="pln"> </span><span class="lit">5</span><span class="pun">];</span><span class="pln">

items</span><span class="pun">.</span><span class="pln">push</span><span class="pun">(</span><span class="lit">6</span><span class="pun">);</span><span class="pln">

</span><span class="kwd">const</span><span class="pln"> result </span><span class="pun">=</span><span class="pln"> items
    </span><span class="pun">.</span><span class="pln">filter</span><span class="pun">(</span><span class="pln">x </span><span class="pun">=&gt;</span><span class="pln"> x </span><span class="pun">%</span><span class="pln"> </span><span class="lit">2</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln">
    </span><span class="pun">.</span><span class="pln">map</span><span class="pun">(</span><span class="pln">x </span><span class="pun">=&gt;</span><span class="pln"> x </span><span class="pun">**</span><span class="pln"> </span><span class="lit">2</span><span class="pun">)</span><span class="pln">
    </span><span class="pun">.</span><span class="pln">join</span><span class="pun">(</span><span class="str">", "</span><span class="pun">);</span><span class="pln">

print</span><span class="pun">(</span><span class="pln">result</span><span class="pun">);</span><span class="pln"> </span><span class="com">// 4, 16, 36</span></pre>

		<p>
			 
		</p>

		<p>
			Сгенерированный lua код
		</p>

		<div class="ipsSpoiler" data-ipsspoiler="">
			<div class="ipsSpoiler_header">
				<span>Скрытый текст</span>
			</div>

			<div class="ipsSpoiler_contents">
				<pre class="ipsCode prettyprint lang-lua prettyprinted">


<span class="com">--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]</span><span class="pln">
</span><span class="com">-- Lua Library inline imports</span><span class="pln">
</span><span class="kwd">function</span><span class="pln"> __TS__ArrayPush</span><span class="pun">(</span><span class="pln">arr</span><span class="pun">,</span><span class="pln"> </span><span class="pun">...)</span><span class="pln">
    </span><span class="kwd">local</span><span class="pln"> items </span><span class="pun">=</span><span class="pln"> </span><span class="pun">({...})</span><span class="pln">
    </span><span class="kwd">for</span><span class="pln"> ____</span><span class="pun">,</span><span class="pln"> item </span><span class="kwd">in</span><span class="pln"> ipairs</span><span class="pun">(</span><span class="pln">items</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">do</span><span class="pln">
        arr</span><span class="pun">[#</span><span class="pln">arr </span><span class="pun">+</span><span class="pln"> </span><span class="lit">1</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> item
    </span><span class="kwd">end</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> </span><span class="pun">#</span><span class="pln">arr
</span><span class="kwd">end</span><span class="pln">

</span><span class="kwd">function</span><span class="pln"> __TS__ArrayFilter</span><span class="pun">(</span><span class="pln">arr</span><span class="pun">,</span><span class="pln"> callbackfn</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">local</span><span class="pln"> result </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{}</span><span class="pln">
    </span><span class="kwd">do</span><span class="pln">
        </span><span class="kwd">local</span><span class="pln"> i </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pln">
        </span><span class="kwd">while</span><span class="pln"> i </span><span class="pun">&lt;</span><span class="pln"> </span><span class="pun">#</span><span class="pln">arr </span><span class="kwd">do</span><span class="pln">
            </span><span class="kwd">if</span><span class="pln"> callbackfn</span><span class="pun">(</span><span class="pln">_G</span><span class="pun">,</span><span class="pln"> arr</span><span class="pun">[</span><span class="pln">i </span><span class="pun">+</span><span class="pln"> </span><span class="lit">1</span><span class="pun">],</span><span class="pln"> i</span><span class="pun">,</span><span class="pln"> arr</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">then</span><span class="pln">
                result</span><span class="pun">[#</span><span class="pln">result </span><span class="pun">+</span><span class="pln"> </span><span class="lit">1</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> arr</span><span class="pun">[</span><span class="pln">i </span><span class="pun">+</span><span class="pln"> </span><span class="lit">1</span><span class="pun">]</span><span class="pln">
            </span><span class="kwd">end</span><span class="pln">
            i </span><span class="pun">=</span><span class="pln"> i </span><span class="pun">+</span><span class="pln"> </span><span class="lit">1</span><span class="pln">
        </span><span class="kwd">end</span><span class="pln">
    </span><span class="kwd">end</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> result
</span><span class="kwd">end</span><span class="pln">

</span><span class="kwd">function</span><span class="pln"> __TS__ArrayMap</span><span class="pun">(</span><span class="pln">arr</span><span class="pun">,</span><span class="pln"> callbackfn</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">local</span><span class="pln"> newArray </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{}</span><span class="pln">
    </span><span class="kwd">do</span><span class="pln">
        </span><span class="kwd">local</span><span class="pln"> i </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pln">
        </span><span class="kwd">while</span><span class="pln"> i </span><span class="pun">&lt;</span><span class="pln"> </span><span class="pun">#</span><span class="pln">arr </span><span class="kwd">do</span><span class="pln">
            newArray</span><span class="pun">[</span><span class="pln">i </span><span class="pun">+</span><span class="pln"> </span><span class="lit">1</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> callbackfn</span><span class="pun">(</span><span class="pln">_G</span><span class="pun">,</span><span class="pln"> arr</span><span class="pun">[</span><span class="pln">i </span><span class="pun">+</span><span class="pln"> </span><span class="lit">1</span><span class="pun">],</span><span class="pln"> i</span><span class="pun">,</span><span class="pln"> arr</span><span class="pun">)</span><span class="pln">
            i </span><span class="pun">=</span><span class="pln"> i </span><span class="pun">+</span><span class="pln"> </span><span class="lit">1</span><span class="pln">
        </span><span class="kwd">end</span><span class="pln">
    </span><span class="kwd">end</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> newArray
</span><span class="kwd">end</span><span class="pln">

</span><span class="kwd">local</span><span class="pln"> items </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="lit">1</span><span class="pun">,</span><span class="pln">
    </span><span class="lit">2</span><span class="pun">,</span><span class="pln">
    </span><span class="lit">3</span><span class="pun">,</span><span class="pln">
    </span><span class="lit">4</span><span class="pun">,</span><span class="pln">
    </span><span class="lit">5</span><span class="pun">,</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
__TS__ArrayPush</span><span class="pun">(</span><span class="pln">items</span><span class="pun">,</span><span class="pln"> </span><span class="lit">6</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">local</span><span class="pln"> result </span><span class="pun">=</span><span class="pln"> table</span><span class="pun">.</span><span class="pln">concat</span><span class="pun">(</span><span class="pln">__TS__ArrayMap</span><span class="pun">(</span><span class="pln">__TS__ArrayFilter</span><span class="pun">(</span><span class="pln">items</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">function</span><span class="pun">(</span><span class="pln">____</span><span class="pun">,</span><span class="pln"> x</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">return</span><span class="pln"> x </span><span class="pun">%</span><span class="pln"> </span><span class="lit">2</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> </span><span class="lit">0</span><span class="pln"> </span><span class="kwd">end</span><span class="pun">),</span><span class="pln"> </span><span class="kwd">function</span><span class="pun">(</span><span class="pln">____</span><span class="pun">,</span><span class="pln"> x</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">return</span><span class="pln"> x </span><span class="pun">^</span><span class="pln"> </span><span class="lit">2</span><span class="pln"> </span><span class="kwd">end</span><span class="pun">),</span><span class="pln"> </span><span class="str">", "</span><span class="pun">)</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">result</span><span class="pun">)</span></pre>

				<p>
					 
				</p>
			</div>
		</div>

		<p>
			 
		</p>

		<p>
			<strong>4.2 Модули</strong>
		</p>

		<pre class="ipsCode prettyprint lang-javascript prettyprinted">

<span class="com">// main.ts</span><span class="pln">
</span><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> myFunction </span><span class="pun">}</span><span class="pln"> from </span><span class="str">"./myLibrary"</span><span class="pun">;</span><span class="pln">

myFunction</span><span class="pun">();</span><span class="pln">

</span><span class="com">// myLibrary.ts</span><span class="pln">
</span><span class="kwd">export</span><span class="pln"> </span><span class="kwd">function</span><span class="pln"> myFunction</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    print</span><span class="pun">(</span><span class="str">"Hi from myLibrary"</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span></pre>

		<p>
			Сгенерированный lua код
		</p>

		<div class="ipsSpoiler" data-ipsspoiler="">
			<div class="ipsSpoiler_header">
				<span>Скрытый текст</span>
			</div>

			<div class="ipsSpoiler_contents">
				<pre class="ipsCode prettyprint lang-lua prettyprinted">


<span class="com">-- main.lua</span><span class="pln">
</span><span class="com">--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]</span><span class="pln">
</span><span class="kwd">local</span><span class="pln"> ____exports </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{}</span><span class="pln">
</span><span class="kwd">local</span><span class="pln"> ____myLibrary </span><span class="pun">=</span><span class="pln"> require</span><span class="pun">(</span><span class="str">"myLibrary"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">local</span><span class="pln"> myFunction </span><span class="pun">=</span><span class="pln"> ____myLibrary</span><span class="pun">.</span><span class="pln">myFunction
myFunction</span><span class="pun">(</span><span class="kwd">nil</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">return</span><span class="pln"> ____exports

</span><span class="com">-- myLibrary.lua</span><span class="pln">
</span><span class="com">--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]</span><span class="pln">
</span><span class="kwd">local</span><span class="pln"> ____exports </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{}</span><span class="pln">
</span><span class="kwd">function</span><span class="pln"> ____exports</span><span class="pun">.</span><span class="pln">myFunction</span><span class="pun">(</span><span class="pln">self</span><span class="pun">)</span><span class="pln">
    print</span><span class="pun">(</span><span class="str">"Hi from myLibrary"</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">end</span><span class="pln">
</span><span class="kwd">return</span><span class="pln"> ____exports</span></pre>

				<p>
					 
				</p>
			</div>
		</div>

		<p>
			 
		</p>

		<p>
			<strong>4.3 Форматирование строк</strong>
		</p>

		<pre class="ipsCode prettyprint lang-javascript prettyprinted">

<span class="kwd">const</span><span class="pln"> text </span><span class="pun">=</span><span class="pln"> </span><span class="pun">`</span><span class="lit">2</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="lit">2</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> $</span><span class="pun">{</span><span class="lit">2</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="lit">2</span><span class="pun">}`;</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">text</span><span class="pun">);</span><span class="pln"> </span><span class="com">// 2 + 2 = 4</span></pre>

		<p>
			Сгенерированный lua код
		</p>

		<pre class="ipsCode prettyprint lang-lua prettyprinted">

<span class="com">--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]</span><span class="pln">
</span><span class="kwd">local</span><span class="pln"> text </span><span class="pun">=</span><span class="pln"> </span><span class="str">"2 + 2 = "</span><span class="pln"> </span><span class="pun">..</span><span class="pln"> tostring</span><span class="pun">(</span><span class="lit">2</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="lit">2</span><span class="pun">)</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">text</span><span class="pun">)</span></pre>
	</div>
</div>

<p>
	 
</p>

<p>
	<span style="font-size:22px;"><strong># Как это работает?</strong></span>
</p>

<p>
	Конечно же все не так просто. Компилятор просто так не узнает типы методов и полей объектов, с которыми мы будем работать. Для того, чтобы описать наше окружение необходимо написать так называемые файлы декларации или <a href="https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html" rel="external nofollow">тайпинги</a>. Хочу сразу вас обрадовать - это не ваша задача. Существует <a href="https://github.com/Exeteres/opc-types" rel="external nofollow">репозиторий</a> с такими декларациями, в котором, на данный момент, существуют типы для большинства API и компонентов OpenOS и библиотеки <a href="https://github.com/IgorTimofeev/gui" rel="external nofollow">GUI</a>.
</p>

<p>
	От вас требуется только установить все необходимые инструменты и правильно их настроить.
</p>

<p>
	 
</p>

<p>
	<span style="font-size:22px;"><strong># Установка</strong></span>
</p>

<p>
	<strong>Редактор кода</strong>
</p>

<p>
	Вы можете использовать любой редактор кода с поддержкой TypeScript. Я рекомендую <a href="https://code.visualstudio.com" rel="external nofollow">VSCode</a>, который поддерживает его из коробки.
</p>

<p>
	 
</p>

<p>
	<strong>NodeJS</strong>
</p>

<p>
	Он необходим нам для установки необходимых пакетов (он поставляется с пакетным менеджером npm) и для запуска транспилера. Вы можете скачать последнюю стабильную версию с <a href="https://nodejs.org/en/" rel="external nofollow">официального сайта</a>.
</p>

<p>
	 
</p>

<p>
	<strong>Использование плагина для VSCode (рекомендуется):</strong>
</p>

<div class="ipsSpoiler" data-ipsspoiler="">
	<div class="ipsSpoiler_header">
		<span>Скрытый текст</span>
	</div>

	<div class="ipsSpoiler_contents">
		<p>
			Вы можете установить плагин <strong>OpenComputersTS</strong>. В нем есть две команды:
		</p>

		<ul>
			<li>
				<strong>OC-TS: Init </strong>- Создание нового проекта в пустой папке.
			</li>
			<li>
				<strong>OC-TS: Mount </strong>- Подключение дисков из сохранений minecraft или эмулятора OCEmu в папку <strong>dist</strong>.
			</li>
		</ul>

		<p>
			Для открытия окна с командами используйте сочетание <strong>Ctrl + Shift + P</strong>.
		</p>

		<p>
			 
		</p>

		<p>
			<img alt="ici-RMCx-RWf.gif" class="ipsImage" data-ratio="75.00" height="750" width="1000" src="https://i.ibb.co/2FzX537/ici-RMCx-RWf.gif">
		</p>
	</div>
</div>

<p>
	 
</p>

<p>
	<strong>Создание проекта вручную:</strong>
</p>

<div class="ipsSpoiler" data-ipsspoiler="">
	<div class="ipsSpoiler_header">
		<span>Скрытый текст</span>
	</div>

	<div class="ipsSpoiler_contents">
		<p>
			После установки NodeJS у вас должны появится команды <span style="color:#111;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#f1f1f1;padding:0 4px;border:1px solid #d6d6d6;margin:2px 2px 2px 0;">npm</span>  и <span style="color:#111;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#f1f1f1;padding:0 4px;border:1px solid #d6d6d6;margin:2px 2px 2px 0;">node</span>.
		</p>

		<ol>
			<li>
				Создайте новую папку для своего первого проекта
			</li>
			<li>
				Переключитесь в нее, используя терминал и все дальнешие действия выполняйте в ней
			</li>
			<li>
				Создайте npm пакет: <span style="color:#111;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#f1f1f1;padding:0 4px;border:1px solid #d6d6d6;margin:2px 2px 2px 0;">npm init</span>. После выполнения этой команды в папке появится файл <strong>package.json</strong>
			</li>
			<li>
				Добавьте в объект <strong>"scripts"</strong> в <strong>package.json </strong>строку <span style="color:#111;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#f1f1f1;padding:0 4px;border:1px solid #d6d6d6;margin:2px 2px 2px 0;">"build": "tstl",</span>
			</li>
			<li>
				Установите транспилер <span style="color:#111;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#f1f1f1;padding:0 4px;border:1px solid #d6d6d6;margin:2px 2px 2px 0;">npm install --dev typescript-to-lua</span>. После установки первого пакета у вас появится папка <strong>node_modules</strong>
			</li>
			<li>
				Установите тайпинги <span style="color:#111;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#f1f1f1;padding:0 4px;border:1px solid #d6d6d6;margin:2px 2px 2px 0;">npm install --dev @opct/openos</span>
			</li>
			<li>
				Создайте папку <strong>src </strong>для исходных файлов
			</li>
			<li>
				Создайте файл <strong>tsconfig.json </strong>со следующим содержимым:
			</li>
		</ol>

		<pre class="ipsCode prettyprint lang-javascript prettyprinted">

<span class="pun">{</span><span class="pln">
    </span><span class="str">"compilerOptions"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="str">"target"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"esnext"</span><span class="pun">,</span><span class="pln">
        </span><span class="str">"outDir"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"dist"</span><span class="pun">,</span><span class="pln">
        </span><span class="str">"module"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"commonjs"</span><span class="pun">,</span><span class="pln">
        </span><span class="str">"lib"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="str">"esnext"</span><span class="pun">],</span><span class="pln">
        </span><span class="str">"strict"</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">,</span><span class="pln">
        </span><span class="str">"moduleResolution"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"node"</span><span class="pun">,</span><span class="pln">
        </span><span class="str">"rootDir"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"src"</span><span class="pun">,</span><span class="pln">
        </span><span class="str">"types"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">[</span><span class="str">"lua-types/jit"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"@opct/openos"</span><span class="pun">]</span><span class="pln">
    </span><span class="pun">},</span><span class="pln">
    </span><span class="str">"tstl"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        </span><span class="str">"luaTarget"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"JIT"</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

		<p>
			Теперь вы можете размещать в <strong>src </strong>исходный код, например, <strong>main.ts </strong>со следующим содержимым:
		</p>

		<pre class="ipsCode prettyprint lang-javascript prettyprinted">

<span class="kwd">import</span><span class="pln"> </span><span class="pun">*</span><span class="pln"> as component from </span><span class="str">"component"</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> front </span><span class="pun">}</span><span class="pln"> from </span><span class="str">"sides"</span><span class="pun">;</span><span class="pln">

component</span><span class="pun">.</span><span class="pln">redstone</span><span class="pun">.</span><span class="pln">setOutput</span><span class="pun">(</span><span class="pln">front</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">);</span></pre>

		<p>
			 
		</p>

		<p>
			<strong>Как запустить сгенерированный код в OpenComputers?</strong>
		</p>

		<p>
			<span style="font-size:16px;">Самый удобный способ для доставки полученного кода - символическая ссылка. Вы можете заменить каталог dist ссылкой на папку диска.</span>
		</p>

		<pre class="ipsCode">

# Создание ссылки через терминал
# linux / macos
ln -s /path/to/disk/home dist

# windows (cmd)
mklink /j dist C:\path\to\disk\home</pre>

		<p>
			Диски располагаются в папке <strong>.minecraft\saves\<em>{сохранение}</em>\opencomputers</strong>. Вам также необходимо отключить параметр <strong>filesystem.bufferChanges </strong>в файле <strong>.minecraft\config\opencomputers\settings.conf</strong>
		</p>

		<p>
			После этого вы сможете запускать сгенерированный код прямо в игре.
		</p>
	</div>
</div>

<p>
	 
</p>

<p>
	Для компиляции используйте команду <span style="color:#111;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#f1f1f1;padding:0 4px;border:1px solid #d6d6d6;margin:2px 2px 2px 0;">npm run build</span>. Сгенерированные lua файлы появятся в папке <strong>dist</strong>.
</p>

<p>
	 
</p>

<p>
	<span style="font-size:22px;"><strong># Особенности работы транспилера</strong></span>
</p>

<p>
	В этой секции я подробно раскажу про недостатки этого подхода, возможные проблемы и способы их решения.
</p>

<p>
	 
</p>

<p>
	<strong><span style="font-size:18px;">1. Параметр self</span></strong>
</p>

<div class="ipsSpoiler" data-ipsspoiler="">
	<div class="ipsSpoiler_header">
		<span>Скрытый текст</span>
	</div>

	<div class="ipsSpoiler_contents">
		<p>
			<strong>Объявление функций</strong>
		</p>

		<p>
			Одно из первых, что вы скорее всего попробуете сделать - объявить функцию:
		</p>

		<pre class="ipsCode prettyprint lang-javascript prettyprinted">

<span class="kwd">function</span><span class="pln"> test</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{}</span><span class="pln">
test</span><span class="pun">();</span></pre>

		<p>
			Однако результат может быть неожиданным:
		</p>

		<pre class="ipsCode prettyprint lang-lua prettyprinted">

<span class="com">--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]</span><span class="pln">
</span><span class="kwd">function</span><span class="pln"> test</span><span class="pun">(</span><span class="pln">self</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">end</span><span class="pln">
test</span><span class="pun">(</span><span class="kwd">nil</span><span class="pun">)</span></pre>

		<p>
			Зачем-то появился параметр <strong>self</strong>, который тут казалось бы не нужен.
		</p>

		<p>
			А теперь попробуйте сделать так:
		</p>

		<pre class="ipsCode prettyprint lang-javascript prettyprinted">

<span class="kwd">const</span><span class="pln"> obj </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    a</span><span class="pun">:</span><span class="pln"> </span><span class="lit">5</span><span class="pun">,</span><span class="pln">
    b</span><span class="pun">:</span><span class="pln"> </span><span class="lit">10</span><span class="pun">,</span><span class="pln">
    sum</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
        print</span><span class="pun">(</span><span class="kwd">this</span><span class="pun">.</span><span class="pln">a </span><span class="pun">+</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">b</span><span class="pun">);</span><span class="pln">
    </span><span class="pun">},</span><span class="pln">
</span><span class="pun">};</span><span class="pln">

obj</span><span class="pun">.</span><span class="pln">sum</span><span class="pun">();</span></pre>

		<p>
			Результат:
		</p>

		<pre class="ipsCode prettyprint lang-lua prettyprinted">

<span class="com">--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]</span><span class="pln">
obj </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    a </span><span class="pun">=</span><span class="pln"> </span><span class="lit">5</span><span class="pun">,</span><span class="pln">
    b </span><span class="pun">=</span><span class="pln"> </span><span class="lit">10</span><span class="pun">,</span><span class="pln">
    sum </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">function</span><span class="pun">(</span><span class="pln">self</span><span class="pun">)</span><span class="pln">
        print</span><span class="pun">(</span><span class="pln">self</span><span class="pun">.</span><span class="pln">a </span><span class="pun">+</span><span class="pln"> self</span><span class="pun">.</span><span class="pln">b</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">end</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
obj</span><span class="pun">:</span><span class="pln">sum</span><span class="pun">()</span></pre>

		<p>
			У функции все еще есть <strong>self</strong>, но в этот раз он необходим для доступа к полям obj.
		</p>

		<p>
			Если мы теперь попробуем оторвать метод sum от объекта и вызвать отдельно:
		</p>

		<pre class="ipsCode prettyprint lang-javascript prettyprinted">

<span class="kwd">const</span><span class="pln"> sum </span><span class="pun">=</span><span class="pln"> obj</span><span class="pun">.</span><span class="pln">sum</span><span class="pun">;</span><span class="pln">
sum</span><span class="pun">();</span></pre>

		<p>
			то увидем, что транспилер все еще передает nil вместо self:
		</p>

		<pre class="ipsCode prettyprint lang-lua prettyprinted">

<span class="pln">sum </span><span class="pun">=</span><span class="pln"> obj</span><span class="pun">.</span><span class="pln">sum
sum</span><span class="pun">(</span><span class="kwd">nil</span><span class="pun">)</span></pre>

		<p>
			Такое поведение связано с тем, что в JavaScript (для которого изначально был создан TypeScript) <strong>this (self) </strong>есть у любой функции (кроме стрелочных) и для сохранения совместимости с этой особенностью транспилер автоматически генерирует <strong>self </strong>параметр для любой функции. Если вы считаете такое поведение по умолчанию недопустимым, то можете отключить его:
		</p>

		<pre class="ipsCode prettyprint lang-javascript prettyprinted">

<span class="com">// tsconfig.json</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="str">"compilerOptions"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">...</span><span class="pln"> </span><span class="pun">},</span><span class="pln">
    </span><span class="str">"tstl"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
      	</span><span class="pun">...,</span><span class="pln">
        </span><span class="str">"noImplicitSelf"</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">false</span><span class="pun">,</span><span class="pln">
        </span><span class="pun">...</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

		<p>
			<strong>Тип self параметра</strong>
		</p>

		<p>
			Вы также можете явно задать тип <strong>this </strong>так же как и тип любого другого параметра, например, назначить ему <strong>void</strong>:
		</p>

		<pre class="ipsCode prettyprint lang-javascript prettyprinted">

<span class="kwd">function</span><span class="pln"> test</span><span class="pun">(</span><span class="kwd">this</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">void</span><span class="pun">):</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> </span><span class="pun">{}</span><span class="pln">
test</span><span class="pun">();</span></pre>

		<p>
			И тогда транспилер уберет self параметр:
		</p>

		<pre class="ipsCode prettyprint lang-lua prettyprinted">

<span class="com">--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]</span><span class="pln">
</span><span class="kwd">function</span><span class="pln"> test</span><span class="pun">()</span><span class="pln">
</span><span class="kwd">end</span><span class="pln">
test</span><span class="pun">()</span></pre>

		<p>
			Особенно это важно при работе с декларациями. Например, мы хотим описать экземпляр некоторого класса:
		</p>

		<pre class="ipsCode prettyprint lang-javascript prettyprinted">

<span class="pln">declare </span><span class="kwd">interface</span><span class="pln"> </span><span class="typ">Person</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    say</span><span class="pun">(</span><span class="pln">text</span><span class="pun">:</span><span class="pln"> string</span><span class="pun">):</span><span class="pln"> </span><span class="kwd">void</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

declare </span><span class="kwd">const</span><span class="pln"> person</span><span class="pun">:</span><span class="pln"> </span><span class="typ">Person</span><span class="pun">;</span><span class="pln">

person</span><span class="pun">.</span><span class="pln">say</span><span class="pun">(</span><span class="str">"hi"</span><span class="pun">);</span></pre>

		<p>
			И ожидаемо получим:
		</p>

		<pre class="ipsCode prettyprint lang-lua prettyprinted">

<span class="com">--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]</span><span class="pln">
person</span><span class="pun">:</span><span class="pln">say</span><span class="pun">(</span><span class="str">"hi"</span><span class="pun">)</span></pre>

		<p>
			Но если нам понадобится описать какую-либо библиотеку (таблицу с функциями), то такое поведение может быть недопустимо, ведь эти функции не принимают self параметр. Можно вручную задать каждой функции <strong>this:void</strong>, а можно использовать директиву <strong>@noSelf</strong>:
		</p>

		<pre class="ipsCode prettyprint lang-javascript prettyprinted">

<span class="com">/** @noSelf */</span><span class="pln">
declare </span><span class="kwd">interface</span><span class="pln"> </span><span class="typ">MyLibrary</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    method1</span><span class="pun">(</span><span class="pln">text</span><span class="pun">:</span><span class="pln"> string</span><span class="pun">):</span><span class="pln"> </span><span class="kwd">void</span><span class="pun">;</span><span class="pln">
    method2</span><span class="pun">(</span><span class="pln">num</span><span class="pun">:</span><span class="pln"> number</span><span class="pun">):</span><span class="pln"> </span><span class="kwd">void</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

declare </span><span class="kwd">const</span><span class="pln"> lib</span><span class="pun">:</span><span class="pln"> </span><span class="typ">MyLibrary</span><span class="pun">;</span><span class="pln">

lib</span><span class="pun">.</span><span class="pln">method1</span><span class="pun">(</span><span class="str">"text"</span><span class="pun">);</span><span class="pln">
lib</span><span class="pun">.</span><span class="pln">method2</span><span class="pun">(</span><span class="lit">123</span><span class="pun">);</span></pre>

		<p>
			И тогда эти функции будут вызваны без двоеточия:
		</p>

		<pre class="ipsCode prettyprint lang-lua prettyprinted">

<span class="com">--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]</span><span class="pln">
lib</span><span class="pun">.</span><span class="pln">method1</span><span class="pun">(</span><span class="str">"text"</span><span class="pun">)</span><span class="pln">
lib</span><span class="pun">.</span><span class="pln">method2</span><span class="pun">(</span><span class="lit">123</span><span class="pun">)</span></pre>

		<p>
			 
		</p>
	</div>
</div>

<p>
	 
</p>

<p>
	<strong><span style="font-size:18px;">2. Множественные значения</span></strong>
</p>

<div class="ipsSpoiler" data-ipsspoiler="">
	<div class="ipsSpoiler_header">
		<span>Скрытый текст</span>
	</div>

	<div class="ipsSpoiler_contents">
		<p>
			В TypeScript не поддерживаются множественные значения. Вместо этого используются кортежи.
		</p>

		<p>
			Например, объявим функцию, которая возвращает несколько значений:
		</p>

		<pre class="ipsCode prettyprint lang-javascript prettyprinted">

<span class="kwd">function</span><span class="pln"> getValues</span><span class="pun">():</span><span class="pln"> </span><span class="pun">[</span><span class="pln">string</span><span class="pun">,</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> boolean</span><span class="pun">]</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> </span><span class="pun">[</span><span class="str">"text"</span><span class="pun">,</span><span class="pln"> </span><span class="lit">123</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">];</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="kwd">const</span><span class="pln"> </span><span class="pun">[</span><span class="pln">str</span><span class="pun">,</span><span class="pln"> num</span><span class="pun">,</span><span class="pln"> bool</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> getValues</span><span class="pun">();</span></pre>

		<p>
			Этот подход сильно напоминает множественные возвращаемые значения и множественное присваивание в Lua. Тем не менее, сейчас кортежи просто превращаются в таблицы:
		</p>

		<pre class="ipsCode prettyprint lang-lua prettyprinted">

<span class="com">--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]</span><span class="pln">
</span><span class="kwd">function</span><span class="pln"> getValues</span><span class="pun">(</span><span class="pln">self</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> </span><span class="pun">{</span><span class="str">"text"</span><span class="pun">,</span><span class="pln"> </span><span class="lit">123</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">}</span><span class="pln">
</span><span class="kwd">end</span><span class="pln">
str</span><span class="pun">,</span><span class="pln"> num</span><span class="pun">,</span><span class="pln"> bool </span><span class="pun">=</span><span class="pln"> unpack</span><span class="pun">(</span><span class="pln">
    getValues</span><span class="pun">(</span><span class="kwd">nil</span><span class="pun">)</span><span class="pln">
</span><span class="pun">)</span></pre>

		<p>
			Чтобы заставить транспилер возвращать множественные значения, необходимо использовать директиву <strong>@tupleReturn</strong><span>:</span>
		</p>

		<pre class="ipsCode prettyprint lang-javascript prettyprinted">

<span class="com">/** @tupleReturn */</span><span class="pln">
</span><span class="kwd">function</span><span class="pln"> getValues</span><span class="pun">():</span><span class="pln"> </span><span class="pun">[</span><span class="pln">string</span><span class="pun">,</span><span class="pln"> number</span><span class="pun">,</span><span class="pln"> boolean</span><span class="pun">]</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> </span><span class="pun">[</span><span class="str">"text"</span><span class="pun">,</span><span class="pln"> </span><span class="lit">123</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">];</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="kwd">const</span><span class="pln"> </span><span class="pun">[</span><span class="pln">str</span><span class="pun">,</span><span class="pln"> num</span><span class="pun">,</span><span class="pln"> bool</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> getValues</span><span class="pun">();</span></pre>

		<p>
			И тогда все будет красиво:
		</p>

		<pre class="ipsCode prettyprint lang-lua prettyprinted">

<span class="com">--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]</span><span class="pln">
</span><span class="kwd">function</span><span class="pln"> getValues</span><span class="pun">(</span><span class="pln">self</span><span class="pun">)</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> </span><span class="str">"text"</span><span class="pun">,</span><span class="pln"> </span><span class="lit">123</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">true</span><span class="pln">
</span><span class="kwd">end</span><span class="pln">
str</span><span class="pun">,</span><span class="pln"> num</span><span class="pun">,</span><span class="pln"> bool </span><span class="pun">=</span><span class="pln"> getValues</span><span class="pun">(</span><span class="kwd">nil</span><span class="pun">)</span></pre>

		<p>
			 
		</p>
	</div>
</div>

<p>
	 
</p>

<p>
	<strong><span style="font-size:18px;">3. Индексы</span></strong>
</p>

<div class="ipsSpoiler" data-ipsspoiler="">
	<div class="ipsSpoiler_header">
		<span>Скрытый текст</span>
	</div>

	<div class="ipsSpoiler_contents">
		<p>
			Числовые индексы в таблицах Lua начинаются с 1, в то время как в TypeScript с 0. Транспилер сам выполняет преобразование индексов TypeScript в Lua, например:
		</p>

		<pre class="ipsCode prettyprint lang-javascript prettyprinted">

<span class="kwd">const</span><span class="pln"> arr </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">3</span><span class="pun">];</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">arr</span><span class="pun">[</span><span class="lit">1</span><span class="pun">]);</span></pre>

		<p>
			будет преобразовано в:
		</p>

		<pre class="ipsCode prettyprint lang-lua prettyprinted">

<span class="com">--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]</span><span class="pln">
arr </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">3</span><span class="pun">}</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">arr</span><span class="pun">[</span><span class="lit">2</span><span class="pun">])</span></pre>

		<p>
			И мы в обоих случаях получим на экране второй элемент массива.
		</p>

		<p>
			 
		</p>

		<p>
			<strong>arr.length</strong><strong> </strong>является полным аналогом оператора <span><strong>#</strong>:</span>
		</p>

		<pre class="ipsCode prettyprint lang-javascript prettyprinted">

<span class="kwd">const</span><span class="pln"> arr </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">3</span><span class="pun">];</span><span class="pln">
print</span><span class="pun">(</span><span class="pln">arr</span><span class="pun">.</span><span class="pln">length</span><span class="pun">);</span></pre>

		<p>
			Результат:
		</p>

		<pre class="ipsCode prettyprint lang-lua prettyprinted">

<span class="com">--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]</span><span class="pln">
arr </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">3</span><span class="pun">}</span><span class="pln">
print</span><span class="pun">(#</span><span class="pln">arr</span><span class="pun">)</span></pre>

		<p>
			 
		</p>
	</div>
</div>

<p>
	 
</p>

<p>
	<span style="font-size:22px;"><strong># Ссылки</strong></span>
</p>

<ul>
	<li>
		<a href="https://www.typescriptlang.org/index.html" rel="external nofollow">Официальный сайт и документация TypeScript (англ)</a>
	</li>
	<li>
		<a href="https://metanit.com/web/typescript/" rel="external nofollow">Серия русских статей по TypeScript</a>
	</li>
	<li>
		<a href="https://typescripttolua.github.io/" rel="external nofollow">Документация TypeScriptToLua (англ)</a>
	</li>
	<li>
		<a href="https://github.com/Exeteres/opc-types" rel="external nofollow">Тайпинги</a>
	</li>
</ul>

<p>
	 
</p>

]]></description><guid isPermaLink="false">3028</guid><pubDate>Sun, 05 Jan 2020 16:10:50 +0000</pubDate></item><item><title>&#x414;&#x440;&#x443;&#x433;&#x43E;&#x439; &#x441;&#x43F;&#x43E;&#x441;&#x43E;&#x431; &#x440;&#x435;&#x430;&#x43B;&#x438;&#x437;&#x430;&#x446;&#x438;&#x438; &#x41E;&#x431;&#x44A;&#x435;&#x43A;&#x442;&#x43D;&#x43E;-&#x41E;&#x440;&#x438;&#x435;&#x43D;&#x442;&#x438;&#x440;&#x43E;&#x432;&#x430;&#x43D;&#x43D;&#x43E;&#x433;&#x43E; &#x41F;&#x440;&#x43E;&#x433;&#x440;&#x430;&#x43C;&#x43C;&#x438;&#x440;&#x43E;&#x432;&#x430;&#x43D;&#x438;&#x44F;</title><link>https://computercraft.ru/topic/813-drugoy-sposob-realizatsii-obektno-orientirovannogo-programmirovaniya/</link><description><![CDATA[
<p>Я видел статью про ООП (Объектно-Ориентированного Программирования), написанную на этом форуме, и вот, что могу сказать, он может быть немного непонятен новичкам в Lua. Я всегда пользовался другим способом создания "классов".</p>
<p>Сначала следует разобраться со значениями. Класс - это набор методов (в нашем случае функций), процедур и переменных которые дальше будут наследоваться объектом или другим классом. Объектами называют сущности, обладающие набором свойств и операций над ними. Объект - это производное класса.</p>
<p> </p>
<p>В Lua классов как таковых нет, но если <em>пофантазировать, </em>то можно представить функцию как класс, а объект как таблицу.</p>
<p> </p>
<p><span style="font-family:'comic sans ms', cursive;"><span style="font-size:18px;"><span style="color:#0000ff;">Создание простого псевдо-класса</span></span></span></p>
<p> </p>
<div class="ipsSpoiler" data-ipsspoiler="">
<div class="ipsSpoiler_header"><span></span></div>
<div class="ipsSpoiler_contents">
<p> </p>
<p><strong>1</strong>. И так создаем новую функцию и называем её к примеру class.</p>
<pre class="ipsCode prettyprint">
function class() --Объявление класса
	--Тело класса
end --Конец класса
</pre>
<p>Пока это просто пустая функция.</p>
<p> </p>
<p><strong>2</strong>.Теперь пропишем в теле класса следующее:</p>
<pre class="ipsCode prettyprint">
function class() --Объявление класса
	local Me = { } --Создание объекта
	return Me --Возвращение объекта (производного класса)
end --Конец класса
</pre>
<p>Теперь мы создали пустую таблицу и заставили функцию вернуть её. Для создания полноценного объекта нам не хватает заполнить его свойствами и методами. Таблица будущего объекта должна быть <strong>локальной</strong>.</p>
<p> </p>
<p><strong>3</strong>.Создадим свойства и методы к нему:</p>
<pre class="ipsCode prettyprint">
function class() --Объявление класса
	local Me = {  --Таблица для методов и переменных
		["Var"] = "HelloWorld"; --Публичная переменная
	}
	local Secret = "Cake = Lie"  --Скрытая переменная
	function Me.PrintVar()
		print(Me.Var)
	end
	function Me.PrintSecret()
		print(Secret)
	end
	return Me --Возвращение объекта (производного класса)
end --Конец класса
</pre>
<p>Мы создали два свойства одно скрытое (Secret), а второе публичное (Me.Var) и два метода один для вывода на экран свойства Me.Var, а второй для вывода свойства Secret. Скрытые свойства обязательно должны быть локальными, а публичные находиться в таблице объекта. Также вы можете создать локальную функцию, которую смогут использовать только методы этого объекта.</p>
<p> </p>
<p><strong>5</strong>.Вы можете хранить этот класс в отдельном файле и вызывать его с помощью функции <span style="font-family:'courier new', courier, monospace;">require(), </span>таким образом, чувствовать себя программистом на C, где обычно каждый класс находится в отдельном файле <img src="https://computercraft.ru/uploads/emoticons/default_wink.png" alt=";)"><span style="font-family:arial, helvetica, sans-serif;"> . Выглядит это примерно так:</span></p>
<pre class="ipsCode prettyprint">
local class = require("имя_библиотеки").class -- загрузили класс из другого файла (если его нет в этом)
local Object = class() -- Создание объекта на основе класса
Object.PrintVar() --Вызов первого метода
--&gt; HelloWorld

Object.PrintSecret() --Вызов второго метода
--&gt; Cake = Lie

Object.Var = "BuyWorld" --Изменение значения свойства Var
Object.PrintVar() --Вызов первого метода
--&gt; BuyWorld
</pre>
<p>Здесь же я вызвал все методы объекта, поменял значение свойства Var и снова вызвал. Попробуйте сами, всё должно работать и с несколькими объектами тоже.</p>
<p> </p>
</div>
</div>
<p> </p>
<p></p>
<hr>
<p> </p>
<p><span style="font-family:'comic sans ms', cursive;"><span style="font-size:18px;"><span style="color:#0000ff;">Наследование</span></span></span></p>
<p> </p>
<div class="ipsSpoiler" data-ipsspoiler="">
<div class="ipsSpoiler_header"><span></span></div>
<div class="ipsSpoiler_contents">
<p> </p>
<p>Сначала необходимо познакомиться с самим термином. Наследование - это перенимание всех свойств и методов одного класса другим.</p>
<p> </p>
<p>Давайте напишем новый класс и назовём его <span style="font-family:'courier new', courier, monospace;">parent</span>.</p>
<pre class="ipsCode prettyprint">
function parent() --Класс предок для будущего класса наследника
	local Me = { }
        local private = {
            ["Secret"] = 42
        }
	Me.Var = "HelloWorld"
	function Me.PrintVar()
		print(Me.Var)
	end
	return Me
end </pre>
<p>В этом классе есть свойство <span style="font-family:'courier new', courier, monospace;">Var</span> и метод <span style="font-family:'courier new', courier, monospace;">PrintVar()<span style="font-family:arial, helvetica, sans-serif;">, а также скрытое свойство в таблице</span> private</span>.</p>
<p> </p>
<p>Теперь пишем класс наследник:</p>
<pre class="ipsCode prettyprint">
function class()
	local Me = parent() --Перенимаем таблицу объекта из класса parent(), то есть наследуем.
	return Me
end </pre>
<p><strike>Всё! Поздравляю, вы наследовали класс!</strike> <img src="https://computercraft.ru/uploads/emoticons/default_biggrin.png" alt=":D">  Но на самом деле не полностью, т. к. остаётся наше скрытое свойство. Я не просто так засунул его в таблицу. Мы можем передать эту таблицу как и сам объект, но отдельно.</p>
<pre class="ipsCode prettyprint">
function parent()--Класс предок
	local Me = {
		["Var"] = "HelloWorld" --Публичное свойство
	}
	local private = {
		["Secret"] = 42 --Скрытое свойство
	}
	function Me.PrintVar() --Метод
		print(Me.Var)
	end
	return Me, private --Возвращение объекта, а затем таблицы со скрытыми переменными
end
function class() --Класс наследник
	local Me, private = parent() --Наследование
	function Me.getVar() --Функция, возвращающая свойство Var из класса parent
		return Me.Var
	end
	function Me.getSecret()
		return private.Secret --Функция, возвращающая скрытое свойство Secret класса parent
	end
	return Me, private --Этот класс можно наследовать тоже, таким образом, получится двойное наследование
end </pre>
<p>Теперь тестим:</p>
<pre class="ipsCode prettyprint">
local class = require("filename").class --Нужно, если вы разместили класс в другом файле
--[[
Если вы разместили классы в разных файлах, то следует загружать каждый отдельно, но так как они у меня в одном файле, я вызову только наследника, и это всё равно будет работать.
]]

local object = class() --Создаём объект
object.PrintVar() --Тестим метод из класса предка
--&gt; HelloWorld

print(object.getVar()) --Тестим метод класса class, работающий с Var
--&gt; HelloWorld

print(Me.getSecret()) --Получаем значение скрытого свойства
--&gt; 42
</pre>
<p>Как видите, всё должно работать. Вы можете сами попробовать построить этот класс и вызывать его методы.</p>
<p>В принципе тут больше нечего объяснять, я думаю. Если что-то не понятно, спрашивайте, отвечу.</p>
<p> </p>
</div>
</div>
<p> </p>
<p></p>
<hr>
<p> </p>
<p><span style="font-family:'comic sans ms', cursive;"><span style="color:#0000ff;"><span style="font-size:18px;">Экономия оперативной памяти</span></span></span></p>
<p> </p>
<div class="ipsSpoiler" data-ipsspoiler="">
<div class="ipsSpoiler_header"><span></span></div>
<div class="ipsSpoiler_contents">
<p> </p>
<p>Представим класс:</p>
<pre class="ipsCode prettyprint">
function class()
    return {
        ["foo"] = function()
            --Здесь очень много кода, вычислений, инструкций и т.д.
        end;
        ["var"] = "какая-то переменная, для примера"
    }
    --Оформил тело объекта так, для разнообразия
end </pre>
<p>Главный минус таких "классов" в том, что они тратят оперативную память, бессмысленно создавая идентичные функции, которые сохраняются отдельно. Но этого можно избежать почти полностью. Почему почти, вы сейчас уведите.</p>
<p>Представим класс в несколько ином виде, как блок <span style="font-family:'courier new', courier, monospace;">do </span><strong>&lt;тело класса&gt;</strong> <span style="font-family:'courier new', courier, monospace;">end</span>.</p>
<pre class="ipsCode prettyprint">
do --Начало класса
    local function class_foo(self) --Наша "тяжёлая" функция
        --Здесь очень много кода, вычислений, инструкций и т.д.
    end
    function class() --Функция для вызова класса</pre>
<div>    return {<br>        ["foo"] = function()<br>            return class_foo(self) --Ссылаемся на локальную функцию<br>        end;<br>        ["var"] = "какая-то переменная, для примера"<br>    }</div>
<p>    end end --Конец класса </p>
<p>Вот и всё! Сложная функция записывается только один раз, а методы ссылаются на неё. Также вы можете не использовать блок <span style="font-family:'courier new', courier, monospace;">do</span>, но тогда функции будут доступны вне класса.</p>
<p> </p>
</div>
</div>
<p> </p>
<p></p>
<hr>
<p> </p>
<p><span style="color:#0000ff;"><span style="font-family:'comic sans ms', cursive;"><span style="font-size:18px;">Только читаемые свойства</span></span></span></p>
<p> </p>
<div class="ipsSpoiler" data-ipsspoiler="">
<div class="ipsSpoiler_header"><span></span></div>
<div class="ipsSpoiler_contents">
<p> </p>
<p>Это последнее, о чём стоит написать в этой теме. Только читаемые свойства могут понадобится для возвращения результатов объекта не используя функции, и при этом, не предоставляя возможность редактировать эти самые свойства. Это можно сделать используя магию <em>метатаблиц. </em>Не знаете, что это? Тогда бегом читать! Хотя сейчас можно обойтись и без этого  <img src="https://computercraft.ru/uploads/emoticons/default_wink.png" alt=";)">. Объяснить на словах, как это сделать, трудно, так что просто смотрите код:</p>
<pre class="ipsCode prettyprint">
function class()
    local private = { } --Таблица со скрытыми свойствами
    private.__index = { --Таблица внутри таблицы скрытых свойств с читаемыми переменными. !!!Важно! Таблица должна сохраняться под ключом __index!!!
        ReadOnly = true; --Читаемое свойство
        Set = function( var ) --Читаемый метод, который изменяет значение читаемого свойства
            private.__index.ReadOnly = var
        end;
    }
    private.secret = 42823 --Скрытое свойство
    private.__newindex = function() end --Метаметод, непозволяющий менять значение таблицы объекта, если приравняете не к функции, а к таблице будет выводить в неё все попытки замены свойств.
    local Me = { } --Сам объект, да он пуст
    setmetatable( Me, private ) --Магия метатаблиц: устанавливает метатаблицу private для объекта
    return Me, private --Зачем я возвращаю таблицу со скрытыми свойствами, смотрите в наследовании
end </pre>
<p>Надеюсь комментарии к коду выше вполне понятны и всё объясняют. Так что мы можем перейти к тестированию.</p>
<p>Тестируем:</p>
<pre class="ipsCode prettyprint">
local class = require 'class'.class --Загрузка класса, если он в другом файле.

local object = class() --Получаем объект на основе нашего класса
object.Set( "test" ) --Устанавливаем значение для читаемого свойства читаемой функцией. Напрямую мы это сделать не сможем.
print(object.ReadOnly) --Выводим значение ReadOnly
--&gt; test

object.ReadOnly = "He he!"
--Изменяем значение, надеясь, что это сработает

print(object.ReadOnly) --Но он выводит старое значение
--&gt; test</pre>
<p>На этом всё. Теперь вы можете использовать читаемые свойства для того, чтобы не создавать специальные для этого методы.</p>
<p> </p>
</div>
</div>
<p> </p>
<p> </p>
<p><strong>Вывод.</strong> Этот способ реализации ООП в Lua будет работать и в OC и в СС. "Классы" очень похожи на классы из других языков программирования. В моём варианте нет двоеточия, которое приносит странную возможность обработки одного объекта методом другого. Использовать ООП в игре можно для удобной разметки интерфейса в вашей программе (например для создания кнопок), и для экономии системных ресурсов в вашем компьютере внутри компьютера.</p>

]]></description><guid isPermaLink="false">813</guid><pubDate>Tue, 09 Jun 2015 18:10:38 +0000</pubDate></item><item><title>&#x41F;&#x43E;&#x43B;&#x443;&#x447;&#x435;&#x43D;&#x438;&#x435; &#x442;&#x43E;&#x447;&#x43D;&#x43E;&#x433;&#x43E; &#x440;&#x435;&#x430;&#x43B;&#x44C;&#x43D;&#x43E;&#x433;&#x43E; &#x432;&#x440;&#x435;&#x43C;&#x435;&#x43D;&#x438;</title><link>https://computercraft.ru/topic/688-poluchenie-tochnogo-realnogo-vremeni/</link><description><![CDATA[
<p>Так как GET запросы, например, к  <a data-ipb="nomediaparse" href="http://www.timeapi.org/utc/now" rel="external nofollow">http://www.timeapi.org/utc/now</a> , требуют на выполнение определенного времени, до нескольких секунд, наличия интернет карты и кучи телодвижений, есть еще один вариант получения астрономического времени. Точное оно настолько, насколько точно его настроил админ на хосте.</p>
<p> </p>
<p>Стандартные функции <strong>date +%s </strong> в консоли и в интерпретаторе os.date() выдают пока черти что, 1970 год и время с потолка.</p>
<p>Всякие счетчики работы Луа машины и ПК нам тоже не подходят, типа os.clock() и прочих.</p>
<p> </p>
<p>Но есть один способ. В ОС можно получить дату модификации файла методом <strong>lastModified('filename')</strong> из библиотеки <strong>filesystem</strong> в формате <a data-ipb="nomediaparse" href="https://ru.wikipedia.org/wiki/UNIX-%D0%B2%D1%80%D0%B5%D0%BC%D1%8F" rel="external nofollow">UNIX</a></p>
<p>Ним и воспользуемся. Модифицируем вспомагательный файл и получим время модификации тут же.</p>
<p> </p>
<p> </p>
<p><strong>Вот функция получения времени:</strong></p>
<pre class="ipsCode prettyprint lang-xml">
-- ======машинное время (время хоста)=======

-- раскомментируйте библиотеку, если она не подключена в вашем коде
--local fs = require("filesystem")  

--(установить для своего часового пояса, -12 : +13, например: -2 или 6)
local TIME_ZONE = 2  

--(не изменять!)
local t_correction = TIME_ZONE * 3600 

local function getTimeHost()
    local file = io.open('/tmp/unix.tmp', 'w')
    file:write('')
    file:close()
    local lastmod = tonumber(string.sub(fs.lastModified('UNIX.tmp'), 1, -4)) + t_correction
    
    --print(lastmod)


    -- Вариант 1
    --local data = os.date('%x', lastmod)
    --local time = os.date('%X', lastmod)
    --return data, time

    -- Вариант 2, eсли нужно все по отдельности
    --local year = os.date('%Y', lastmod)
    --local month = os.date('%m', lastmod)
    --local day = os.date('%d', lastmod)
    --local weekday = os.date('%A', lastmod)
    --local hour = os.date('%H', lastmod)
    --local minute  = os.date('%M', lastmod)
    --local sec  = os.date('%S', lastmod)    
    --return year, month, day, weekday, hour, minute, sec

    -- Вариант 3, но есть нюанс, если число минут(часов) 5, то и будет выдано 5, а не 05!
    --local dt = os.date('*t', lastmod)
    --return dt.year, dt.month, dt.day, dt.hour, dt.min, dt.sec
    
    -- Вариант 4, все в куче, как мы привыкли, в правильном формате
    local dt = os.date('%Y.%m.%d %H:%M:%S', lastmod)
    return dt
end

print(getTimeHost())
</pre>
<p>Вот выдержка из Советской Энциклопедии о <a data-ipb="nomediaparse" href="https://ru.wikipedia.org/wiki/UNIX-%D0%B2%D1%80%D0%B5%D0%BC%D1%8F" rel="external nofollow">UNIX </a>времени. </p>
<p> </p>
<p>Часовой пояс установите, как Вам угодно (например, сейчас 2 на ИТ - это время Киев, 3 - МСК). Формат, который возвращает функция, тоже выберите, какой Вам удобно. Лишние закомментированные строки (--)  удалите.</p>
<p>Теперь легко можно в лог записать любое событие и приписать ему время. Так же можно легко узнать дату и день недели через 234 часов, 36 мин, 40 сек, например, предварительно переведя временной интервал в секунды и потом вернуть астрономическое время. Например вы хотите узнать, через сколько на ИТ вы скрафтите 100К ведер жидкой материи. Это например, 2256 год, 1 апреля, 12:50:12, если не останавливать "генмат" не на секунду <img src="https://computercraft.ru/uploads/emoticons/default_wink.png" alt=";)"></p>
<p> </p>
<p><u>Вот ретурн функции:</u></p>
<p><strong>Вариант 1:</strong> string, string     <strong>04/22/15  09:05:56</strong></p>
<p><strong>Вариант 2:</strong> number, number, number, string, number, number, number     <strong>2015 04 22   Wednesday 09   05  56</strong></p>
<p><strong>Вариант 3: </strong>number, number, number, number, number, number     <strong>2015 04  22    9   5  56</strong></p>
<p><a data-ipb="nomediaparse" href="http://puu.sh/hn1Oh/6ecd41b4f7.jpg" rel="external nofollow"><strong>Вариант 4:</strong> string     <strong>2015.04.22 09:05:56</strong></a></p>
<p>и т.п.</p>
<p> </p>
<p>По сути вся функция, это 7 строчек. Не нужно никаких гетзапросов выполнять, библ всяких и интернет карт.</p>
<p> </p>
<p><a data-ipb="nomediaparse" href="http://www.lua.org/pil/22.1.html" rel="external nofollow">Подробнее о форматах os.date() здесь. </a></p>

]]></description><guid isPermaLink="false">688</guid><pubDate>Wed, 22 Apr 2015 17:53:20 +0000</pubDate></item><item><title>&#x41A;&#x430;&#x43A; &#x443;&#x437;&#x43D;&#x430;&#x442;&#x44C; &#x43C;&#x435;&#x442;&#x43E;&#x434;&#x44B; &#x43A;&#x43E;&#x43C;&#x43F;&#x43E;&#x43D;&#x435;&#x43D;&#x442;&#x43E;&#x432; &#x432; &#x41E;&#x421;</title><link>https://computercraft.ru/topic/951-kak-uznat-metody-komponentov-v-os/</link><description><![CDATA[
<p>Очень часто, почти каждый день кто-то спрашивает в чате, как узнать методы компонентов, какие есть методы для работы с МФСУ, реакторами и пр. </p>
<p> </p>
<p>Написал простенькую функцию для листинга методов на экран или на страничку веб сайта, если у Вас имеется интернет карта в ПК.</p>
<p> </p>
<p><a data-ipb="nomediaparse" href="http://pastebin.com/5nQnM3ED" rel="external nofollow">http://pastebin.com/5nQnM3ED</a></p>
<p><em><strong>pastebin get 5nQnM3ED viewmethods.lua</strong></em></p>
<pre class="ipsCode prettyprint lang-">
local component = require("component")
local term = require('term')
local text = require("text")
local components = {}
local methods = {}
local offset = 0
term.clear()
for address, name in component.list() do
    if name:len() &gt; offset then
      offset = name:len()
    end
    components[address] = name
end

offset = offset + 2
print(' -------- Найденные компоненты --------')
for address, name in pairs(components) do
  io.write(text.padRight(name, offset) .. address .. '\n')
end
print(' --------------------------------------')
io.write('Введите имя компонента, методы которого нужно узнать: \n&gt;&gt; ')
local name = io.read()
if component.isAvailable(name) then
	t = component.getPrimary(name)
	local filename = name..'_doc.tmp'
	local file = io.open(filename, 'w')
	for k,v in pairs(t) do
		table.insert(methods,'&gt;&gt; Метод: '..k..'\nДокументация: '..tostring(v))
    	file:write('&gt;&gt; Метод: '..k..'\nДокументация: '..tostring(v)..'\n')
	end
	file:close()
	if component.isAvailable('internet') then
		print('Перейдите по ссылке на сайт для ознакомления!')
		require('shell').execute('pastebin put '..filename)
		else
			term.clear()
			print('Нажимайте ENTER для продолжения')
			for k,v in pairs(methods) do
				print('['..k..'] '..v)
				io.read()
			end
	end
else
	print('Ошибка. Компонента '..name..' не существует!')
end

</pre>
<p><img src="http://i.imgur.com/UEQIhml.png" alt="UEQIhml.png"></p>
<p> </p>
<p><img src="http://i.imgur.com/6U7BTv5.png" alt="6U7BTv5.png"></p>
<p> </p>
<p><img src="http://i.imgur.com/9I75NYX.png" alt="9I75NYX.png"></p>
<p> </p>
<p><img src="http://i.imgur.com/QXf3kpb.png" alt="QXf3kpb.png"></p>

]]></description><guid isPermaLink="false">951</guid><pubDate>Thu, 09 Jul 2015 08:15:46 +0000</pubDate></item><item><title>&#x41F;&#x43E;&#x434;&#x43C;&#x435;&#x43D;&#x430; computer.pullSignal &#x438;&#x43B;&#x438; &#x43C;&#x435;&#x442;&#x43E;&#x434;&#x438;&#x43A;&#x430; &#x43F;&#x43E;&#x441;&#x442;&#x440;&#x43E;&#x435;&#x43D;&#x438;&#x44F; &#x440;&#x435;&#x437;&#x438;&#x434;&#x435;&#x43D;&#x442;&#x43D;&#x44B;&#x445; &#x43F;&#x440;&#x43E;&#x433;&#x440;&#x430;&#x43C;&#x43C; &#x432; OpenOS</title><link>https://computercraft.ru/topic/868-podmena-computerpullsignal-ili-metodika-postroeniya-rezidentnyh-programm-v-openos/</link><description><![CDATA[
<p>Подмена computer.pullSignal или методика построения резидентных программ в OpenOS</p>
<p>Допустим, захотелось нам иметь резидентную программу, которая будет работать на фоне OpenOS и, периодически, или по какому либо событию, что-то полезное делать.</p>
<p> </p>
<p>Воспользуемся <a href="https://computercraft.ru/topic/866-bibi-ili-udobstvo-razrabotki-eeprom-koda-i-operatcionnykh/" rel="">нашим маленьким <strong>bibi</strong></a>, а в качестве <strong>boot.lua</strong> напишем такой код:</p>
<p></p>
<pre class="ipsCode prettyprint lang-auto">local cl=component.list
local gp=component.proxy(cl("gpu")())

--сохраняем исходные функции из _G.computer, для внутреннего пользования
local cp={} for k,v in pairs(computer) do cp[k]=v end

--подменяем функцию computer.pullSignal
computer.pullSignal = function (...)
  local e={cp.pullSignal(...)}
 --для примера, по тильде (~) будем ребутать компьютер
  if e[1]=='key_down' and e[4]==41 then cp.shutdown(true) end
  --а по lAlt будем выводить список компонентов используя определенную в OpenOS функцию print и сохраненную cl
  if e[1]=='key_down' and e[4]==56 then
    for k,v in cl() do print(k,v) end
  end
  --OpenOS периодически сама дергает эвенты (чтобы курсор мигал и прочее) подробнее смотрите в lib/event.lua
  --поэтому мы можем выводить свои часики, куда-ж без них то ) и прочие полезности, например инфу о памяти
  local s=tostring(math.floor(cp.freeMemory()/1024))..'/'..tostring(cp.totalMemory()/1024)..' kb free '..os.date('!%R')
  local w,h = gp.maxResolution()
  gp.set(w-#s+1,1,s)
  --в конце мы должны вернуть событие ничего не подозревающей OpenOS
  return table.unpack(e)
end

--функцию мы подменили, теперь загружаем, компилируем и выполняем init.lua
local fs=component.proxy(computer.getBootAddress())
local h=fs.open('init.lua')
local s,r='',''
while r do
  r=fs.read(h,math.huge)
  s=s..(r or "")
end
fs.close(h)
load(s)()
</pre>Запускаем компьютер, bibi пискнув и подождав секундочку, выполняет наш boot.lua, который хитро подменив pullSignal выполнит init.lua и после загрузки OpenOS в углу экрана радостно затикают часики.<p> </p>
<p><img src="http://storage3.static.itmages.ru/i/15/0621/h_1434887575_1643213_5ca46d9108.png" alt="h_1434887575_1643213_5ca46d9108.png"></p>
<p> </p>
<p>Теперь мы можем нажать lAlt и лицезреть список компонентов, или нажать тильду, и компьютер перезапустится.</p>
<p>--==--</p>
<p>Конечно, вы можете сказать, что вывод списка компонентов портит экран, что перед выводом хорошо бы сохранять состояние экрана каким-нибудь gpu.get, вывод делать в свой интерфейс, а после, восстанавливать экран. И часики у меня никудышние. При скролле вниз (например в редакторе edit.lua) скроллируются вместе с текстом, вместо того, чтобы оставаться там где им положено. Но моя задача, показать метод на простейших примерах, а не переопределяя gpu строить интерфейсы.</p>
<p> </p>
<p>На основе этого метода можно построить API для TSR программ, а комбинируя его с перехватом component.proxy, component.invoke и последующей подменой gpu на виртуальный терминал, и вовсе, написать свою операционную систему. Для которой, кстати говоря, было бы неплохо уметь запускать OpenOS в окошке, но самое главное, в изолированной среде, чтобы труд программистов писавших ПО под OpenOS не пропадал зря.</p>
<p> </p>
<p>Я бы даже сказал, что изоляция OpenOS, на данном этапе, более важная задача, чем построение интерфейсов. Поэтому мы попробуем разобрать эту проблему в следующей статье.</p>
<p> </p>
<p>Посмотрим что выйдет.</p>
<p>--==--</p>
<p><strong>Небольшое дополнение:</strong></p>
<p>Если вам не охота играть с bibi, но нужно запустить резидентную программу прямо из-под <span style="color:#282828;"><span style="font-family:helvetica, arial, sans-serif;">OpenOS, то это сделать еще проще. </span></span></p>
<p></p>
<pre class="ipsCode prettyprint lang-auto">local component = require("component")
local cp = require("computer")
local gpu = component.gpu
local pullSignal = cp.pullSignal

cp.pullSignal = function (...)
  local e={pullSignal(...)}
  if e[1]=='key_down' and e[4]==41 then cp.shutdown(true) end
  if e[1]=='key_down' and e[4]==56 then for k,v in component.list() do print(k,v) end end
  local s=' '..math.floor(cp.freeMemory()/1024)..'/'..(cp.totalMemory()/1024)..' kb free  '..os.date('!%R')
  local w,h = gpu.maxResolution() gpu.set(w-#s+1,1,s)  
  return table.unpack(e)
end
</pre>Сохраняем этот код в файл, допустим <strong>tsr.lua</strong> и запускаем его <strong>под <span style="color:#282828;"><span style="font-family:helvetica, arial, sans-serif;">OpenOS</span></span></strong><p>Программа выполнится, завершится, а резидентный участок останется в памяти.</p>
<p>--==--</p>
<p>Если выбросить все что относится к демонстрации работы, у нас останется маленькая обертка</p>
<p></p>
<pre class="ipsCode prettyprint lang-auto">local cp = require("computer")
local pullSignal = cp.pullSignal
cp.pullSignal = function (...)
  local e={pullSignal(...)}

  --код TSR программы

  return table.unpack(e)
end
</pre>Заключив в которую код своей TSR программы мы получим резидента, который будет выполнять TSR-код, где-то раз в пол секунды.
]]></description><guid isPermaLink="false">868</guid><pubDate>Sun, 21 Jun 2015 12:39:54 +0000</pubDate></item><item><title>MoonScript</title><link>https://computercraft.ru/topic/1655-moonscript/</link><description><![CDATA[
<p>Итак, устройтесь поудобнее у ваших голубых экранов.<br>Сегодня я научу вас програмировать во Имя Луны!</p>
<p style="text-align:center;"><img src="http://i.imgur.com/oG22WCq.png" alt="oG22WCq.png"></p>
<p>Мы привыкли писать программы для OpenComputers на Луа. И при этом не задумываемся о том, что язык Луа в OpenComputers - это по сути "язык низкого уровня".<br>На нем мы пишем все - начиная от прошивок BIOS и операционных систем, и заканчивая чатиками для OpenGlasses.<br> <br>Однако, когда объем кода не имеет решающей роли, и есть время для медитации, программист может дать душе отдохнуть, используя красивые конструкции высокоуровневых языков.<br>И таким языком сегодня станет <a href="http://moonscript.org/" rel="external nofollow">MoonScript</a>.<br> <br> <br><strong><span style="font-size:18px;"># Что это такое?</span></strong><br>MoonScript - это язык с интересным и лаконичным синтаксисом. Он позволяет использовать привычные конструкции ООП (объектно-ориентированное программирование) и ФП (функциональное программирование) в сеттинге Луа.<br>Сам автор называет его "CoffeeScript for Lua".<br> <br>Код на MoonScript хранится в файликах с расширением <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">*.moon</span> и транслируется в обычный код Lua. Который может затем быть выполнен на компьютерах или роботах OpenComputers.<br> <br><strong>Плюсы:</strong><br>* краткий и красивый код (субъективно)<br>* изучение нового, интересного (объективно)<br> <br><strong>Минусы:</strong><br>* Транслированный код хуже читаем, и немного объемнее, чем аналогичный код, написанный изначально на Луа<br> <br> <br><span style="font-size:18px;"><strong># Установка</strong></span><br>Приведу пример установки для Debian + Lua5.3. Если у вас другая OS - смотрите соответствующие инструкции по ссылкам.<br> <br>1) Lua (<a href="https://www.lua.org/start.html" rel="external nofollow">https://www.lua.org/start.html</a>)</p>
<pre class="ipsCode prettyprint lang-auto">
$ sudo apt-get install lua5.3</pre>
<p>2) Пакетный менеджер LuaRocks (<a href="https://luarocks.org/#quick-start" rel="external nofollow">https://luarocks.org/#quick-start</a>)<br>Для его установки возможно потребуется пакет liblua5.3-dev.<br>Установим его командой:</p>
<pre class="ipsCode prettyprint lang-auto">
$ sudo apt-get install liblua5.3-dev</pre>
<p>Далее следуем инструкциям с официального сайта:</p>
<pre class="ipsCode prettyprint lang-auto">
$ wget http://luarocks.org/releases/luarocks-2.3.0.tar.gz
$ tar zxpf luarocks-2.3.0.tar.gz
$ cd luarocks-2.3.0
$ ./configure; sudo make bootstrap
</pre>
<p>3) Ставим пакеты MoonScript (<a href="http://moonscript.org/#installation" rel="external nofollow">http://moonscript.org/#installation</a>)</p>
<pre class="ipsCode prettyprint lang-auto">
$ sudo luarocks install moonscript</pre>
<p>Теперь в системе появятся программы <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">moon</span> и <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">moonc</span>. Ура!<br> <br>К слову, при их запуске может вылетать ошибка типа</p>
<pre class="ipsCode prettyprint lang-auto">
/usr/local/share/lua/5.3/alt_getopt.lua:24: attempt to call a nil value (global 'module')</pre>
<p>Это происходит потому, что moonscript давненько уже не обновлялся, и использует устаревшее ключевое слово <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">module</span>.<br><br>Фиксится при помощи правки файликов <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">alt_getopt.lua</span> и <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">moon</span>.<br> <br>В файле <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">alt_getopt.lua</span> необходимо закомментировать 24 строку (<span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">module ("alt_getopt")</span>) и дописать в самый конец строку</p>
<pre class="ipsCode prettyprint lang-auto">
return {get_opts = get_opts, get_ordered_opts = get_ordered_opts}</pre>
<p>В файле <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">moon</span> исправляем вторую строку на</p>
<pre class="ipsCode prettyprint lang-auto">
local alt_getopt = require("alt_getopt")</pre>
<p>Все это в нашем случае можно сделать командами:</p>
<pre class="ipsCode prettyprint lang-auto">
$ sudo gedit /usr/local/share/lua/5.3/alt_getopt.lua
$ sudo gedit /usr/local/lib/luarocks/rocks/moonscript/0.4.0-1/bin/moon</pre>
<p>Все! MoonScript установлен, пропатчен и готов к работе.<br> <br> <br><span style="font-size:18px;"><strong># Подсветка синтаксиса</strong></span><br>Очень рекомендую писать код в редакторе заточенном под код. Чертовски удобно, поверьте.<br>Для MoonScript существуют пакеты подсветки синтаксиса для разных редакторов.<br> <br>1) <strong>Sublime Text</strong> / <strong>Text Mate</strong> - <a href="https://github.com/leafo/moonscript-tmbundle" rel="external nofollow">https://github.com/leafo/moonscript-tmbundle</a><br>2) <strong>vim</strong> - <a href="https://github.com/leafo/moonscript-vim" rel="external nofollow">https://github.com/leafo/moonscript-vim</a><br>3) <strong>Atom</strong> - <a href="https://atom.io/packages/language-moonscript" rel="external nofollow">https://atom.io/packages/language-moonscript</a><br>4)<strong> Textadept</strong> - <a href="https://github.com/leafo/moonscript-textadept" rel="external nofollow">https://github.com/leafo/moonscript-textadept</a><br> <br> <br><span style="font-size:18px;"><strong># А теперь - магия!</strong></span><br>Для примера, я переписал код библиотечки <a href="https://computercraft.ru/topic/1454-braille-bicycle-monokhromnye-pikseli-opencomputers/?hl=braille" rel="">Braille Bicycle</a> с использованием MoonScript.<br>Теперь она использует ООП подход (привет, <a contenteditable="false" data-ipshover="" href="https://computercraft.ru/profile/33-krutoy/" data-ipshover-target="http://computercraft.ru/profile/33-krutoy/?do=hovercard" data-mentionid="33" rel="">@Krutoy</a> <img src="https://computercraft.ru/uploads/emoticons/default_smile.png" alt=":)"> ).<br><a href="http://pastebin.com/NQc7JCH3" rel="external nofollow"><span style="font-size:18px;">http://pastebin.com/NQc7JCH3</span></a><br> <br>Этот файлик я потом "откомпилировал" в Lua простой командой:</p>
<pre class="ipsCode prettyprint lang-auto">
$ moonc braille.moon</pre>
<p>И получил на выходе рабочую библиотеку <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">braille.lua</span>.<br>Далее, заливаем ее в OC и пишем простой тестовый код:</p>
<pre class="ipsCode prettyprint lang-auto">
local gpu = require('component').gpu
local braille = require('braille')


local matrix = braille.Matrix(8, 8)
matrix:line(1, 1, 8, 1)
matrix:set(1, 2); matrix:line(4, 2, 5, 2); matrix:set(8, 2)
matrix:set(1, 3); matrix:line(4, 3, 5, 3); matrix:set(8, 3)
matrix:line(1, 4, 3, 4); matrix:line(6, 4, 8, 4)
matrix:line(1, 5, 2, 5); matrix:line(7, 5, 8, 5)
matrix:line(1, 6, 2, 6); matrix:line(7, 6, 8, 6)
matrix:line(1, 7, 2, 7); matrix:line(4, 7, 5, 7); matrix:line(7, 7, 8, 7)
matrix:line(1, 8, 8, 8)


gpu.setForeground(0xC61331)
matrix:render(gpu, 14, 12)
matrix:render(gpu, 46, 12)
gpu.setForeground(0xFFFFFF)
matrix:render(gpu, 30, 12)
matrix:render(gpu, 62, 12)
</pre>
<p>И вуаля! Работает. <br> </p>
<p style="text-align:center;"><img src="http://i.imgur.com/hlQkzSy.png" alt="hlQkzSy.png"></p>
<p> <br><span style="font-size:18px;"><strong># Игровая трансляция</strong></span><br>Все это хорошо, но иногда может быть полезна возможность использовать <span style="color:#0a0a0a;font-family:'Ubuntu Mono', 'Source Code Pro', monospace;background-color:#eaeaea;padding:.15em .2em;border:1px solid #cccccc;">*.moon</span> исходники прямо из OC, без предварительной компиляции.<br>Уже поздно, поэтому расскажу об этом как-нибудь в другой раз.  <img src="https://computercraft.ru/uploads/emoticons/default_biggrin.png" alt=":D"></p>
<p> </p>
<p>Скажу лишь, что помимо всего прочего, у MoonScript есть такая любопытная тулза, как онлайн "компилятор". Его можно найти вот здесь:</p>
<p><span style="font-size:18px;"><a href="http://moonscript.org/compiler/" rel="external nofollow">http://moonscript.org/compiler/</a></span></p>
<p> </p>
<p> </p>
<p><strong><span style="font-size:18px;"># UPD</span></strong></p>
<p>Товарищи <a contenteditable="false" data-ipshover="" href="https://computercraft.ru/profile/33-krutoy/" data-ipshover-target="http://computercraft.ru/profile/33-krutoy/?do=hovercard" data-mentionid="33" rel="">@Krutoy</a> и <a contenteditable="false" data-ipshover="" href="https://computercraft.ru/profile/11134-evgkul/" data-ipshover-target="http://computercraft.ru/profile/11134-evgkul/?do=hovercard" data-mentionid="11134" rel="">@evgkul</a> выпустили транслятор MoonScript на чистом Луа, что позволяет запускать и "компилировать" программы MoonScript прямо из OpenOS.</p>
<p>Заценить и потестить можно по этой ссылке:</p>
<p><span style="font-size:18px;"><a href="https://github.com/evgkul/moonscript-opencomputers" rel="external nofollow">https://github.com/evgkul/moonscript-opencomputers</a></span></p>
<p> </p>
<p>Пишите багрепорты (сюда или на GitHub), и отправляйте свои пуллреквесты, чтобы улучшить программу.</p>
<p> </p>
<p><span style="font-size:18px;"># <strong>UPD 3</strong></span></p>
<p> </p>
<p>Добавил MoonScript в <a href="https://computercraft.ru/topic/1855-repozitorii-programm-hel/" rel="">репозиторий</a>. Теперь можно установить его и потестить всего одной командой:</p>
<pre class="ipsCode prettyprint">
hpm install moon
</pre>

]]></description><guid isPermaLink="false">1655</guid><pubDate>Thu, 09 Jun 2016 00:28:23 +0000</pubDate></item></channel></rss>
