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

OpenViewer - Удалённый рабочий стол, работающий на сети OpenNet

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

Всем привет! В этой теме я расскажу моей программе ---Удалённом рабочем столе на сети OpenNet и моде OpenComputers.
Первым делом расскажу как ей пользоваться.
Ввод данных:
Всё очень просто=)
Жмёте на кнопку на клавиатуре, и её нажатие эмитируется на удалённом компьютере.
Для обновления экрана --- F5
Для выхода из программы на удалённом компьютере --- F2
Для выхода из программы на локальном компьютере ---F1
Ну....Вроде всё по управлению=)
Запуск,настройка и подключение:
Подготовка к запуску удалённого терминала: 
Установить библиотеку thread: 


local computer = require("computer")
computer.SingleThread = computer.pullSignal
local thread = {}

local mainThread
local timeouts

local function MultiThread( _timeout )
  if coroutine.running()==mainThread then
    local mintime = _timeout or math.huge
    local co=next(timeouts)
    while co do
      if coroutine.status( co ) == "dead" then
        timeouts[co],co=nil,next(timeouts,co)
      else
        if timeouts[co] < mintime then mintime=timeouts[co] end
        co=next(timeouts,co)
      end
    end
    if not next(timeouts) then
      computer.pullSignal=computer.SingleThread
      computer.pushSignal("AllThreadsDead")
    end
    local event={computer.SingleThread(mintime)}
    local ok, param
    for co in pairs(timeouts) do
      ok, param = coroutine.resume( co, table.unpack(event) )
      if not ok then timeouts={} error( param )
      else timeouts[co] = param or math.huge end
    end
    return table.unpack(event)
  else
    return coroutine.yield( _timeout )
  end
end

function thread.init()
  mainThread=coroutine.running()
  timeouts={}
end

function thread.create(f,...)
  computer.pullSignal=MultiThread
  local co=coroutine.create(f)
  timeouts[co]=math.huge
  local ok, param = coroutine.resume( co, ... )
  if not ok then timeouts={} error( param )
  else timeouts[co] = param or '' end
  return co
end

function thread.kill(co)
  timeouts[co]=nil
end

function thread.killAll()
  timeouts={}
  computer.pullSignal=computer.SingleThread
end

function thread.waitForAll()
  repeat
  until MultiThread()=="AllThreadsDead"
end
-------------------------------------------------------------------------------
return thread 

(Только на сервер,на клиенте она не нужна)
Установить OpenNet и находится в зоне его покрытия.
Установить на сервер его часть:



local event= require("event")
local thread= require("thread")
local opennet= require("opennet")
local computer= require("computer")
local gpu= require("component").gpu
local unicode= require("unicode")
local keyboard= require("component").keyboard.address
local IP, dis2serv = opennet.getIP()
print("Local IP: "..IP)
args={...}
if args[1]==nil then
  print("Использование: openviewerS <opennet_ip>")
  os.exit()
end

--[[
_, result, reason = opennet.sendrec(args[1], "connecting...")
if result==false then
  print(reason); os.exit()
end
if args[1]==IP then
  print("Невозможно инициализировать удалённый доступ со своим устройством.")
  os.exit()
end
]]--

initial=args[1]
local function getScreen()
  screen=""
  for y=1, 25 do
    for x=1, 80 do
      symbol = gpu.get(x, y)
      screen=screen..symbol
    end
  end
  return screen
end
local function sendScreen()
  opennet.send(initial, getScreen())
end
function runShell()
  os.execute("sh")
end
function reInitial()
  thread.killAll()
  thread.init()
  thread.create(runShell)
  thread.create(EmulateSignal)
  thread.waitForAll()
end
event.listen("Screen", sendScreen)
event.listen("Exit", reInitial)
function EmulateSignal()
  while true do
    opennetIP, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 = opennet.receive()
    if opennetIP==initial then
      computer.pushSignal(arg1, keyboard, tonumber(arg3), tonumber(arg4), arg5)
    end
  end
end
thread.init()
thread.create(runShell)
thread.create(EmulateSignal)
thread.waitForAll()

Установить на клиент клиентскую часть:



local opennet= require("opennet")
local term= require("term")
local unicode= require("unicode")
local event= require("event")
args={...}
if args[1]==nil then
  print("Использование: openviewerC <opennet_ip>")
  os.exit()
end
initial=args[1]
function getScreen()
  repeat
    ip, screenRaw=opennet.receive()
  until ip==initial
  for sym=1, #screenRaw-160 do
    io.write(unicode.sub(screenRaw, sym, sym))
  end
end
term.clear()
opennet.send(initial, "Screen")
getScreen()
while true do
  arg1, arg2, arg3, arg4, arg5 = event.pull()
  if arg1=="key_down" and arg3==0 and arg4==63 then
    term.clear()
    opennet.send(initial, "Screen")
    getScreen()
  elseif arg1=="key_down" and arg3==0 and arg4==59 then
    os.exit()
  elseif arg1=="key_down" and arg3==0 and arg4==60 then
    opennet.send(initial, "Exit")
  else
    opennet.send(initial, arg1, arg2, arg3, arg4, arg5)
  end
end

 
Для запуска программы надо написать на сервере: openviewerS <IP Адрес клиента>
ВНИМАНИЕ!!! Надо ввести именно IP, а не DNS; Единственное поддерживаемое разрешение - 80x25
На клиенте же пишем: openviewerC <IP Адрес сервера>
Вот и всё=)
Надеюсь,эта программа вам будет полезна !
Неплохо было-бы попасть в вайт-лист ;) 

Изменено пользователем Fingercomp
Пишите код по-человечески!

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


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

 

 

 
function getScreen()
 ip, screenRaw=opennet.receive()
 if ip~=initial then getScreen()
 end
 for sym=1, #screenRaw-160 do
   io.write(unicode.sub(screenRaw, sym, sym))
 end
end

 

 

Рекурсия, в данном случае не самое лучшее решение. Используй repeat until

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


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

 

Рекурсия, в данном случае не самое лучшее решение. Используй repeat until

 

Рад бы,но как?=)Научишь?

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


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

Ты так и не научился код правильно и читабельно писать. Подправил ОП, поставил отступы в 2 пробела (!!!), а не в 4 (ты не на Си кодить пришёл), поставил нормально конструкцию if/then(/else)/end, сделал место с кодом красивым. Учись:

if yourConditionGoesHere then
  -- 2 отступа, ДВА! И не лепи в одну строку!
else
  -- Тут то же самое.
end

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


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

А где картинки? И кстати, какая разница сколько отсупов?

Изменено пользователем LeshaInc

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


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

А где картинки?

Картинки дублирования экрана?

Могу добавить=)

 

Ты так и не научился код правильно и читабельно писать. Подправил ОП, поставил отступы в 2 пробела (!!!), а не в 4 (ты не на Си кодить пришёл), поставил нормально конструкцию if/then(/else)/end, сделал место с кодом красивым. Учись:

if yourConditionGoesHere then
  -- 2 отступа, ДВА! И не лепи в одну строку!
else
  -- Тут то же самое.
end

N++ 4 делает

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


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

И кстати, какая разница сколько отсупов?

Что приятнее: читать код с 2 отступами, с миллионом тысяч оступов или вообще без таковых? На Луа делают 2 пробела.

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


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

N++ 4 делает

Notepad++/Опции/Настройки/Настройки табуляции/

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


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

Ну да ладно, не будем же мы спорить кому сколько отступов удобней.

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


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

Рад бы,но как?=)Научишь?

function getScreen()
  repeat
    ip, screenRaw=opennet.receive()
  until ip==initial
  for sym=1, #screenRaw-160 do
    io.write(unicode.sub(screenRaw, sym, sym))
  end
end

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


Ссылка на сообщение
Поделиться на других сайтах
function getScreen()
  repeat
    ip, screenRaw=opennet.receive()
  until ip==initial
  for sym=1, #screenRaw-160 do
    io.write(unicode.sub(screenRaw, sym, sym))
  end
end

Спасибо,заменил

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


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

Очень забавно поднимать тему 3-летней давности.
Так вот, написал на обычном модеме или туннельная карта.
Сервер -
 

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

local component = require("component")
local serialization = require("serialization")
local event = require("event")
local term = require("term")
local gpu = component.gpu
local keyboardAddress = component.keyboard.address
local screenAddress = component.screen.address
local tunnelMode, port = true, 1

gpu.setResolution(80, 25)
if component.isAvailable("tunnel") and tunnelMode then
	tunnel = component.tunnel
else
	modem = component.modem
	modem.open(port)
end

local function saveScreen()
	local screen = ""
	for i = 1, 25 do 
		for j = 1, 80 do 
			local xCursor, yCursor = term.getCursor()
			if i == yCursor and j == xCursor then
				screen = screen .. "█" 
			else
				screen = screen .. gpu.get(j, i)
			end
		end
	end
	return screen
end

local function virtualEvents(_, _, _, _, _, evt)
	if evt == "updateScreen" then
		if tunnel then 
			tunnel.send(saveScreen())
		else
			modem.broadcast(1, saveScreen())
		end
	elseif evt == "shutdown" then
		event.ignore("modem_message", virtualEvents)
	else
		local evt = serialization.unserialize(evt)
		if evt[1] == "key_down" or evt[1] == "key_up" then
			event.push(evt[1], keyboardAddress, evt[3], evt[4], evt[5])
		elseif evt[1] == "clipboard" then 
			event.push("clipboard", evt[1], evt[2], evt[3])
		elseif evt[1] == "touch" or evt[1] == "drag" or evt[1] == "drop" or evt[1] == "scroll" then
			event.push(evt[1], screenAddress, evt[3], evt[4], evt[5])
		end
	end
end

event.listen("modem_message", virtualEvents)

 

Клиент - 
 

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

local component = require("component")
local serialization = require("serialization")
local event = require("event")
local term = require("term")
local work = true
local tunnelMode, port = true, 1

if component.isAvailable("tunnel") and tunnelMode then
	tunnel = component.tunnel
else
	modem = component.modem
	modem.open(port)
end

local function send(msg)
	if tunnel then
		tunnel.send(msg)
	else
		modem.broadcast(port, msg)
	end
end

while work do 
	local evt = {event.pull()}
	if evt[1] == "key_down" or evt[1] == "key_up" or evt[1] == "clipboard" or evt[1] == "touch" or evt[1] == "drag" or evt[1] == "drop" or evt[1] == "scroll" then
		if evt[1] == "key_down" and evt[4] == 63 then
			send("updateScreen")
			local screen = {event.pull("modem_message")}
			term.clear()
			io.write(screen[6])
		elseif evt[1] == "key_down" and evt[4] == 41 then
			term.clear()
			work = false
		elseif evt[1] == "key_down" and evt[4] == 59 then
			send("shutdown")
		else
			evt = serialization.serialize(evt)
			send(evt)
		end
	end
end

 

Управление почти тоже самое:
Тильда(Ё) - выход из программы на локальном компьютере
F1 - выход из программы на удалённом компьютере
F5 - обновление экрана.
У сервера и клиента есть 2 параметра - 
tunnelMode и port.
Первый параметр отвечает за  использование туннельной карты(если она есть) или использование модема. (true - использовать туннельную карту/false - не использовать)
Второй сам за себя говорит - за порт.
(Картинка чёрно-белая, само собой)

Очень важные картинки:
 

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

1a0617d0c51fcffb9647c4951fef19ab.png
eec5f53e80bd8cc1553a7bfc92017614.png

 

Изменено пользователем BrightYC

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


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

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

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

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

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

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

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

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

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


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