Перейти к содержимому

Рекомендуемые сообщения

Маловероятно, что сейчас кто либо продолжает использовать компьютеркрафт, но вдруг.

В процессе игры мне понадобилось осуществлять связь между компьютером OC и CC. Так как я не нашёл адекватного способа передачи данных, то придумал костыль. Костыль заключается в передаче данных (на данный момент — строк, если нужно будет передавать что-то другое, то допишу) через... установку и чтение цвета золотого монитора. Код: 

Скрытый текст

local CCOCB = {}
local tochar = string.char
local tobyte = string.byte
local monitor = peripheral and peripheral.find("monitor") or (require("component").isAvailable("computercraft_advanced_monitor") and require("component").computercraft_advanced_monitor or error("Для работы моста требуется подключить золотой монитор."))
local Charset = {
  ["0"] = 0x1,
  ["1"] = 0x2,
  ["2"] = 0x4,
  ["3"] = 0x8,
  ["4"] = 0x10,
  ["5"] = 0x20,
  ["6"] = 0x40,
  ["7"] = 0x80,
  ["8"] = 0x100,
  ["9"] = 0x200,
  ["a"] = 0x400,
  ["b"] = 0x800,
  ["c"] = 0x1000,
  ["d"] = 0x2000,
  ["e"] = 0x4000,
  ["f"] = 0x8000,
}
local BackCharset = {
  [0x8000] = "f",
  [0x4000] = "e",
  [0x2000] = "d",
  [0x1000] = "c",
  [0x800] = "b",
  [0x400] = "a",
  [0x200] = "9",
  [0x100] = "8",
  [0x80] = "7",
  [0x40] = "6",
  [0x20] = "5",
  [0x10] = "4",
  [0x8] = "3",
  [0x4] = "2",
  [0x2] = "1",
  [0x1] = "0",
}
local function DecToHex(value)
    local hex = ''
    while(value > 0)do
      local index = math.fmod(value, 16) + 1
      value = math.floor(value / 16)
      hex = string.sub('0123456789ABCDEF', index, index) .. hex
    end
  return (string.len((hex~="" and hex or 0))==2) and string.lower((hex~="" and hex or 0)) or "0"..string.lower((hex~="" and hex or 0))
end
local function HexToColor(hexchar)
  return Charset[hexchar]
end
local function ColorToHex(color)
  return BackCharset[color]
end
local function getFGHex()
  return ColorToHex(monitor.getTextColor())
end
local function setFGHex(hex)
  monitor.setTextColor(HexToColor(hex))
end
local function getBGHex()
  return ColorToHex(monitor.getBackgroundColor())
end
local function setBGHex(hex)
  monitor.setBackgroundColor(HexToColor(hex))
end
local function pair()
  setFGHex("c")
  setBGHex("c")
  os.sleep(0.1)
  if getFGHex()=="e" then
    mfg = false
  else
    mfg = true
  end
  local canskip = false
  repeat
    if mfg then
      setFGHex("e")
      if getBGHex()=="e" or getBGHex()=="2" then
        canskip = true
      end
    else
      setBGHex("e")
      if getFGHex()=="e" or getFGHex()=="2" then
        canskip = true
      end
    end
    os.sleep(0)
  until canskip
end
function CCOCB.WriteChar(char, isByte)
  local bytecode
  if not isByte then
    bytecode = tobyte(char)
  else
    bytecode = char
  end
  local hexcode = DecToHex(bytecode)
  monitor.setBackgroundColor(HexToColor(string.sub(hexcode, 1,1)))
  monitor.setTextColor(HexToColor(string.sub(hexcode, 2,2)))
end
function CCOCB.ReadChar(isByte)
  local hexcode = ColorToHex(monitor.getBackgroundColor())..ColorToHex(monitor.getTextColor())
  local bytecode = tonumber("0x"..hexcode)
  return (not isByte) and tochar(bytecode) or bytecode
end
function CCOCB.WriteString(str)
  pair()
  repeat
    if str~="" then
      local hexcode = DecToHex(tobyte(string.sub(str, 1, 1)))
      repeat
        if ColorToHex(monitor.getBackgroundColor())=="2" then
          monitor.setTextColor(HexToColor(string.sub(hexcode, 1, 1)))
          monitor.setBackgroundColor(HexToColor("1"))
          hexcode = string.sub(hexcode, 2)
        end
        os.sleep(0)
      until hexcode==""
      str = string.sub(str, 2)
    end
  until str=="" and ColorToHex(monitor.getBackgroundColor())=="2"
  CCOCB.WriteChar(255, true)
end
function CCOCB.ReadString()
  local buscode = 0
  local char_buffer = ""
  local buffer = ""
  pair()
  monitor.setBackgroundColor(HexToColor("2"))
  repeat
    buscode = CCOCB.ReadChar(true)
    if ColorToHex(monitor.getBackgroundColor())=="1" then
      char_buffer = char_buffer .. ColorToHex(monitor.getTextColor())
      monitor.setBackgroundColor(HexToColor("2"))
      if string.len(char_buffer)==2 then
        buffer = buffer .. tochar(tonumber("0x"..char_buffer))
        char_buffer = ""
      end
    end
    os.sleep(0)
  until buscode == 255
  return buffer
end
if peripheral then
  OCBUS = CCOCB
else
  return CCOCB
end

 

Использование:

Скрытый текст

Для OpenComputers: require(path)
Для Computercraft: dofile(path)
  будет доступно как OCBUS

.WriteChar(string sym)
.ReadChar() : string sym

.WriteString(string data)
.ReadString() : string data

 

Последовательность вызова WriteString и ReadString не важна, они не завершатся пока не выполнят свою задачу

Демонстрация:

Скрытый текст
Скачать видео
Скачать видео
Скачать видео
Скачать видео

 

Надеюсь, что кому-то это может пригодиться.

Изменено пользователем Asummonster
tab 4 > 2 spaces

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Золотой компьютер CC + интернет карта ОС + мост Тоторо значительно упростят передачу, без лишних проблем.

 

Второй вариант - переводить все что нужно в serialized форму и передавать так, если не получится - накрывать это в base16 и передавать в урезанном виде через показанную @Asummonster реализацию. В таком случае можно передать все и не теряя при этом кодировку или структуру метатаблички

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
8 часов назад, Asummonster сказал:

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

Интересный костыль, необычный. Я в давние времена, когда OpenComputers ещё был диковинкой, не найдя других способов обмена сообщениями с ComputerCraft, костылил его с помощью ванильного редстоуна.

 

Но сейчас существует и бескостыльнй способ обмена сообщениями между OpenComputers и ComputerCraft с помощью блока коммутатора.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
1 час назад, eu_tomat сказал:

Интересный костыль, необычный. Я в давние времена, когда OpenComputers ещё был диковинкой, не найдя других способов обмена сообщениями с ComputerCraft, костылил его с помощью ванильного редстоуна.

 

Но сейчас существует и бескостыльнй способ обмена сообщениями между OpenComputers и ComputerCraft с помощью блока коммутатора.

Кхех, спасибо)

Кто бы знал. Я думал, что раз кк модем к ок адаптеру не подключается, то шансов на передачу данных по сети нет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в тему...

×   Вы вставили отформатированное содержимое.   Удалить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


×
×
  • Создать...