/* ----------------------------------------------------------------------------- This source file is part of OpenSpace3D For the latest info, see http://www.openspace3d.com Copyright (c) 2018 I-maginer This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, or go to http://www.gnu.org/copyleft/lesser.txt ----------------------------------------------------------------------------- */ struct PlugTelnetClient = [ PTC_inst : PInstance, PTC_telnet : TELNET, PTC_sDstAddr : S, PTC_iDstport : I, PTC_trmConnect : Timer, PTC_trmTimeout : Timer, PTC_bEnable : I, PTC_bState : I, PTC_lKeywords : [S r1] ]mkPlugTelnetClient;; proto cbRetryTelnetConnection = fun [Timer PlugTelnetClient] I;; proto delayRetryTcpConnection = fun [PlugTelnetClient] I;; var iTelnetTimeOut = 30000;; var iTelnetRecoInterval = 10000;; fun cbTimeOutTelnet(timer, obstr)= _deltimer timer; set obstr.PTC_trmTimeout = nil; _TELNETClose obstr.PTC_telnet; set obstr.PTC_telnet = nil; set obstr.PTC_bState = 0; addLogMessage (loc "OS3DTELNETCLIENT_0026"); delayRetryTcpConnection obstr; 0;; fun cbTelnetClientWrite(tel, obstr)= 0;; fun cbTelnetClientRead(tel, obstr)= let _TELNETGetBuffer tel -> echo in ( if (obstr.PTC_trmTimeout == nil) then nil else ( _deltimer obstr.PTC_trmTimeout; set obstr.PTC_trmTimeout = nil; ); if (echo == nil) || (!strcmp echo "") then nil else ( let strlen echo -> echolen in let obstr.PTC_lKeywords -> l in let 0 -> found in while (l != nil && !found) do ( let hd l -> key in let strlen key -> keylenght in let substr echo keylenght 1 -> sp in if ((!strcmp key (substr echo 0 keylenght)) && ((!strcmp sp "") || (!strcmp sp " "))) then ( set found = 1; let substr echo (keylenght + 1) (echolen - keylenght) -> np in SendPluginEvent obstr.PTC_inst (strcat key " message") np nil; ) else nil; set l = tl l; ); ); ); 0;; fun cbTelnetClientConnect(tel, obstr)= addLogMessage strcatn (loc "OS3DTELNETCLIENT_0014")::" "::obstr.PTC_sDstAddr::":"::(itoa obstr.PTC_iDstport)::nil; set obstr.PTC_bState = 1; _TELNETrflRead tel @cbTelnetClientRead obstr; _TELNETrflWrite tel @cbTelnetClientWrite obstr; SendPluginEvent obstr.PTC_inst "Connected" nil nil; 0;; fun cbTelnetClientClosed(tel, obstr)= set obstr.PTC_bState = 0; set obstr.PTC_telnet = nil; addLogMessage strcatn (loc "OS3DTELNETCLIENT_0025")::" "::obstr.PTC_sDstAddr::":"::(itoa obstr.PTC_iDstport)::nil; SendPluginEvent obstr.PTC_inst "Disconnected" nil nil; delayRetryTcpConnection obstr; 0;; fun cbRetryTelnetConnection(trm, obstr)= if (obstr.PTC_trmConnect == nil) then nil else ( _deltimer obstr.PTC_trmConnect; set obstr.PTC_trmConnect = nil; ); if (obstr.PTC_trmTimeout == nil) then nil else ( _deltimer obstr.PTC_trmTimeout; set obstr.PTC_trmTimeout = nil; ); if (obstr.PTC_telnet != nil) then nil else ( let (strcatn obstr.PTC_sDstAddr::":"::(itoa obstr.PTC_iDstport)::nil) -> host in ( addLogMessage strcatn (loc "OS3DTELNETCLIENT_0016")::" "::obstr.PTC_sDstAddr::":"::(itoa obstr.PTC_iDstport)::nil; set obstr.PTC_telnet = _TELNETConnect _channel host; ); _TELNETrflConnect obstr.PTC_telnet @cbTelnetClientConnect obstr; _TELNETrflClose obstr.PTC_telnet @cbTelnetClientClosed obstr; set obstr.PTC_trmTimeout = _rfltimer _starttimer _channel iTelnetTimeOut @cbTimeOutTelnet obstr; ); 0;; fun delayRetryTcpConnection(obstr)= if (!obstr.PTC_bEnable) then nil else ( if (obstr.PTC_trmConnect == nil) then nil else ( _deltimer obstr.PTC_trmConnect; set obstr.PTC_trmConnect = nil; ); addLogMessage strcatn (loc "OS3DTELNETCLIENT_0015")::" "::obstr.PTC_sDstAddr::":"::(itoa obstr.PTC_iDstport)::" "::(loc "OS3DTELNETCLIENT_0024")::nil; set obstr.PTC_trmConnect = _rfltimer _starttimer thisplug.PLUG_channel iTelnetRecoInterval @cbRetryTelnetConnection obstr; ); 0;; fun cbSendMessage(inst, from, action, param, rep, obstr, keyword)= if (!obstr.PTC_bState) then nil else ( if (obstr.PTC_trmTimeout == nil) then nil else ( _deltimer obstr.PTC_trmTimeout; set obstr.PTC_trmTimeout = nil; ); _TELNETSend strcatn keyword::" "::param::"\n"::nil obstr.PTC_telnet; ); 0;; fun cbEnable(inst, from, action, param, rep, obstr)= if (obstr.PTC_bEnable) then nil else ( set obstr.PTC_bState = 0; set obstr.PTC_bEnable = 1; cbRetryTelnetConnection nil obstr; ); 0;; fun cbDisable(inst, from, action, param, rep, obstr)= if (obstr.PTC_trmConnect == nil) then nil else ( _deltimer obstr.PTC_trmConnect; set obstr.PTC_trmConnect = nil; ); if (obstr.PTC_trmTimeout == nil) then nil else ( _deltimer obstr.PTC_trmTimeout; set obstr.PTC_trmTimeout = nil; ); if (!obstr.PTC_bEnable) then nil else ( set obstr.PTC_bEnable = 0; if (obstr.PTC_telnet == nil) then nil else ( _TELNETClose obstr.PTC_telnet; set obstr.PTC_telnet = nil; if (!obstr.PTC_bState) then nil else SendPluginEvent obstr.PTC_inst "Disconnected" nil nil; set obstr.PTC_bState = 0; ); ); 0;; fun cbChangeHostAddr(inst, from, action, param, rep, obstr)= let strToListSep param ":" -> [ip [port _]] in let (atoi port) -> port in if (ip == nil || port == nil) then nil else ( if (obstr.PTC_trmConnect == nil) then nil else ( _deltimer obstr.PTC_trmConnect; set obstr.PTC_trmConnect = nil; ); if (obstr.PTC_trmTimeout == nil) then nil else ( _deltimer obstr.PTC_trmTimeout; set obstr.PTC_trmTimeout = nil; ); set obstr.PTC_sDstAddr = ip; set obstr.PTC_iDstport = port; if (obstr.PTC_telnet == nil) then nil else ( _TELNETClose obstr.PTC_telnet; set obstr.PTC_telnet = nil; if (!obstr.PTC_bState) then nil else SendPluginEvent obstr.PTC_inst "Disconnected" nil nil; set obstr.PTC_bState = 0; set obstr.PTC_bEnable = 1; cbRetryTelnetConnection nil obstr; 0; ); ); 0;; fun deleteOb(inst, obstr)= cbDisable inst nil nil nil nil obstr; 0;; fun cbLoaded(inst, obstr, init)= if !init then nil else cbEnable inst nil nil nil nil obstr; 0;; fun newOb(inst)= let (getPluginInstanceParam inst "dstaddress") -> dstaddress in let atoi (getPluginInstanceParam inst "dstport") -> dstport in let atoi (getPluginInstanceParam inst "init") -> init in let getPluginInstanceUserEvents inst -> levent in let mkPlugTelnetClient [inst nil dstaddress dstport nil nil 0 0 nil] -> obstr in ( while (levent != nil) do ( let hd levent -> evt in let strToWordList evt -> line in let strcatnSep (revertlist tl (revertlist line)) " " -> keyword in ( PluginRegisterAction inst (strcat "Send " keyword) mkfun6 mkfun7 @cbSendMessage keyword obstr; set obstr.PTC_lKeywords = keyword::obstr.PTC_lKeywords; ); set levent = tl levent; ); if inst.INST_groupstr.GRP_project.PRJ_bPluginsLoaded then ( cbLoaded inst obstr init; 0; ) else ( setPluginInstanceCbAllPluginsLoaded inst mkfun2 mkfun3 @cbLoaded init obstr; 0; ); PluginRegisterAction inst "Enable" mkfun6 @cbEnable obstr; PluginRegisterAction inst "Disable" mkfun6 @cbDisable obstr; PluginRegisterAction inst "Change connection address" mkfun6 @cbChangeHostAddr obstr; setPluginInstanceCbDel inst mkfun2 @deleteOb obstr; ); 0;; fun IniPlug(file)= PlugRegister @newOb nil; setPluginEditor @dynamicedit; 0;;