refactored player code

This commit is contained in:
amit bezalel 2017-07-19 00:23:45 +03:00
parent 2038848b8e
commit 662e8393e9
17 changed files with 423 additions and 208 deletions

View File

@ -80,11 +80,9 @@
<file leaf-file-name="fbs-reader.go" pinned="false" current-in-tab="false"> <file leaf-file-name="fbs-reader.go" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/player/fbs-reader.go"> <entry file="file://$PROJECT_DIR$/player/fbs-reader.go">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="285"> <state relative-caret-position="165">
<caret line="19" column="0" lean-forward="false" selection-start-line="19" selection-start-column="0" selection-end-line="19" selection-end-column="0" /> <caret line="19" column="0" lean-forward="false" selection-start-line="19" selection-start-column="0" selection-end-line="19" selection-end-column="0" />
<folding> <folding />
<element signature="e#16#126#0" expanded="true" />
</folding>
</state> </state>
</provider> </provider>
</entry> </entry>
@ -92,19 +90,11 @@
<file leaf-file-name="player_test.go" pinned="false" current-in-tab="true"> <file leaf-file-name="player_test.go" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/player/player_test.go"> <entry file="file://$PROJECT_DIR$/player/player_test.go">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="372"> <state relative-caret-position="75">
<caret line="45" column="36" lean-forward="true" selection-start-line="45" selection-start-column="36" selection-end-line="45" selection-end-column="36" /> <caret line="5" column="10" lean-forward="false" selection-start-line="5" selection-start-column="10" selection-end-line="5" selection-end-column="10" />
<folding /> <folding>
</state> <element signature="n#!!block;n#loadFbsFile#0" expanded="false" />
</provider> </folding>
</entry>
</file>
<file leaf-file-name="multiListener.go" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/common/multiListener.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="270">
<caret line="18" column="0" lean-forward="false" selection-start-line="18" selection-start-column="0" selection-end-line="18" selection-end-column="0" />
<folding />
</state> </state>
</provider> </provider>
</entry> </entry>
@ -132,11 +122,14 @@
<file leaf-file-name="proxy.go" pinned="false" current-in-tab="false"> <file leaf-file-name="proxy.go" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/proxy/proxy.go"> <entry file="file://$PROJECT_DIR$/proxy/proxy.go">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="2130"> <state relative-caret-position="345">
<caret line="154" column="0" lean-forward="false" selection-start-line="154" selection-start-column="0" selection-end-line="154" selection-end-column="0" /> <caret line="180" column="0" lean-forward="true" selection-start-line="180" selection-start-column="0" selection-end-line="180" selection-end-column="0" />
<folding> <folding>
<element signature="n#!!block;n#createClientConnection#0" expanded="false" />
<element signature="n#!!block;n#getTargetServerFromSession#0" expanded="false" />
<element signature="n#!!block;n#newServerConnHandler#0" expanded="false" />
<element signature="n#!!block;n#StartListening#0" expanded="false" />
<marker date="1500386875000" expanded="false" signature="22:26" ph="..." /> <marker date="1500386875000" expanded="false" signature="22:26" ph="..." />
<marker date="1500386875000" expanded="true" signature="4939:5453" ph="{...}" />
<marker date="1500386875000" expanded="true" signature="5091:5092" ph="{...}" /> <marker date="1500386875000" expanded="true" signature="5091:5092" ph="{...}" />
<marker date="1500386875000" expanded="true" signature="5091:5096" ph="{...}" /> <marker date="1500386875000" expanded="true" signature="5091:5096" ph="{...}" />
</folding> </folding>
@ -144,16 +137,12 @@
</provider> </provider>
</entry> </entry>
</file> </file>
<file leaf-file-name="write-to.go" pinned="false" current-in-tab="false"> <file leaf-file-name="proxy_test.go" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/tee-listeners/write-to.go"> <entry file="file://$PROJECT_DIR$/proxy/proxy_test.go">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="450"> <state relative-caret-position="315">
<caret line="34" column="12" lean-forward="false" selection-start-line="34" selection-start-column="12" selection-end-line="34" selection-end-column="12" /> <caret line="21" column="5" lean-forward="true" selection-start-line="21" selection-start-column="5" selection-end-line="21" selection-end-column="5" />
<folding> <folding />
<marker date="1500088058000" expanded="false" signature="26:30" ph="..." />
<marker date="1500088058000" expanded="true" signature="189:257" ph="{...}" />
<marker date="1500088058000" expanded="true" signature="1040:1041" ph="{...}" />
</folding>
</state> </state>
</provider> </provider>
</entry> </entry>
@ -245,6 +234,7 @@
<option value="$PROJECT_DIR$/server/server-conn.go" /> <option value="$PROJECT_DIR$/server/server-conn.go" />
<option value="$PROJECT_DIR$/server/ws-server-go.go" /> <option value="$PROJECT_DIR$/server/ws-server-go.go" />
<option value="$PROJECT_DIR$/player/fbs-reader.go" /> <option value="$PROJECT_DIR$/player/fbs-reader.go" />
<option value="$PROJECT_DIR$/player/FBSPlayListener.go" />
<option value="$PROJECT_DIR$/player/player_test.go" /> <option value="$PROJECT_DIR$/player/player_test.go" />
</list> </list>
</option> </option>
@ -457,6 +447,20 @@
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" /> <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT> </PATH_ELEMENT>
</PATH> </PATH>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="vncproxy" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="vncproxy" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="proxy" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
<PATH> <PATH>
<PATH_ELEMENT> <PATH_ELEMENT>
<option name="myItemId" value="vncproxy" /> <option name="myItemId" value="vncproxy" />
@ -1072,7 +1076,7 @@
<workItem from="1499416701375" duration="1802000" /> <workItem from="1499416701375" duration="1802000" />
<workItem from="1499522471716" duration="431000" /> <workItem from="1499522471716" duration="431000" />
<workItem from="1499965517741" duration="5709000" /> <workItem from="1499965517741" duration="5709000" />
<workItem from="1500411167182" duration="560000" /> <workItem from="1500411167182" duration="1498000" />
</task> </task>
<servers /> <servers />
</component> </component>
@ -1109,7 +1113,7 @@
</history-entry> </history-entry>
</component> </component>
<component name="TimeTrackingManager"> <component name="TimeTrackingManager">
<option name="totallyTimeSpent" value="63915000" /> <option name="totallyTimeSpent" value="64853000" />
</component> </component>
<component name="TodoView"> <component name="TodoView">
<todo-panel id="selected-file"> <todo-panel id="selected-file">
@ -1130,7 +1134,7 @@
<window_info id="Palette&#9;" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" /> <window_info id="Palette&#9;" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Image Layers" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" /> <window_info id="Image Layers" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
<window_info id="Capture Analysis" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" /> <window_info id="Capture Analysis" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.35068494" sideWeight="0.31260097" order="8" side_tool="true" content_ui="tabs" /> <window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.13972603" sideWeight="0.31260097" order="8" side_tool="true" content_ui="tabs" />
<window_info id="Maven Projects" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32956383" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" /> <window_info id="Maven Projects" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32956383" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.30136988" sideWeight="0.49676898" order="3" side_tool="false" content_ui="tabs" /> <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.30136988" sideWeight="0.49676898" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Version Control" active="false" anchor="bottom" auto_hide="true" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32876712" sideWeight="0.4676898" order="10" side_tool="false" content_ui="tabs" /> <window_info id="Version Control" active="false" anchor="bottom" auto_hide="true" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32876712" sideWeight="0.4676898" order="10" side_tool="false" content_ui="tabs" />
@ -1290,24 +1294,14 @@
</line-breakpoint> </line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint"> <line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/player/player_test.go</url> <url>file://$PROJECT_DIR$/player/player_test.go</url>
<line>77</line> <line>13</line>
<option name="timeStamp" value="133" /> <option name="timeStamp" value="133" />
</line-breakpoint> </line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/player/player_test.go</url>
<line>81</line>
<option name="timeStamp" value="134" />
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/player/player_test.go</url>
<line>45</line>
<option name="timeStamp" value="135" />
</line-breakpoint>
</breakpoints> </breakpoints>
<breakpoints-dialog> <breakpoints-dialog>
<breakpoints-dialog /> <breakpoints-dialog />
</breakpoints-dialog> </breakpoints-dialog>
<option name="time" value="136" /> <option name="time" value="137" />
</breakpoint-manager> </breakpoint-manager>
<watches-manager> <watches-manager>
<configuration name="GoApplicationRunConfiguration"> <configuration name="GoApplicationRunConfiguration">
@ -1323,14 +1317,6 @@
<option name="FILTER_TARGETS" value="false" /> <option name="FILTER_TARGETS" value="false" />
</component> </component>
<component name="editorHistoryManager"> <component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/client/client-conn.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="270">
<caret line="27" column="27" lean-forward="true" selection-start-line="27" selection-start-column="27" selection-end-line="27" selection-end-column="27" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/server/security.go"> <entry file="file://$PROJECT_DIR$/server/security.go">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0"> <state relative-caret-position="0">
@ -1512,13 +1498,6 @@
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/proxy/proxy_test.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="270">
<caret line="15" column="43" lean-forward="true" selection-start-line="15" selection-start-column="43" selection-end-line="15" selection-end-column="43" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/main.go"> <entry file="file://$PROJECT_DIR$/main.go">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="414"> <state relative-caret-position="414">
@ -1597,19 +1576,6 @@
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/proxy/proxy.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="2130">
<caret line="154" column="0" lean-forward="false" selection-start-line="154" selection-start-column="0" selection-end-line="154" selection-end-column="0" />
<folding>
<marker date="1500386875000" expanded="false" signature="22:26" ph="..." />
<marker date="1500386875000" expanded="true" signature="4939:5453" ph="{...}" />
<marker date="1500386875000" expanded="true" signature="5091:5092" ph="{...}" />
<marker date="1500386875000" expanded="true" signature="5091:5096" ph="{...}" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/tee-listeners/write-to.go"> <entry file="file://$PROJECT_DIR$/tee-listeners/write-to.go">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="450"> <state relative-caret-position="450">
@ -1670,21 +1636,53 @@
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/proxy/proxy.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="345">
<caret line="180" column="0" lean-forward="true" selection-start-line="180" selection-start-column="0" selection-end-line="180" selection-end-column="0" />
<folding>
<element signature="n#!!block;n#createClientConnection#0" expanded="false" />
<element signature="n#!!block;n#getTargetServerFromSession#0" expanded="false" />
<element signature="n#!!block;n#newServerConnHandler#0" expanded="false" />
<element signature="n#!!block;n#StartListening#0" expanded="false" />
<marker date="1500386875000" expanded="false" signature="22:26" ph="..." />
<marker date="1500386875000" expanded="true" signature="5091:5092" ph="{...}" />
<marker date="1500386875000" expanded="true" signature="5091:5096" ph="{...}" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/proxy/proxy_test.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="315">
<caret line="21" column="5" lean-forward="true" selection-start-line="21" selection-start-column="5" selection-end-line="21" selection-end-column="5" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/player/fbs-reader.go"> <entry file="file://$PROJECT_DIR$/player/fbs-reader.go">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="285"> <state relative-caret-position="165">
<caret line="19" column="0" lean-forward="false" selection-start-line="19" selection-start-column="0" selection-end-line="19" selection-end-column="0" /> <caret line="19" column="0" lean-forward="false" selection-start-line="19" selection-start-column="0" selection-end-line="19" selection-end-column="0" />
<folding> <folding />
<element signature="e#16#126#0" expanded="true" /> </state>
</folding> </provider>
</entry>
<entry file="file://$PROJECT_DIR$/player/FBSPlayListener.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="180">
<caret line="12" column="0" lean-forward="true" selection-start-line="12" selection-start-column="0" selection-end-line="12" selection-end-column="0" />
<folding />
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/player/player_test.go"> <entry file="file://$PROJECT_DIR$/player/player_test.go">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="372"> <state relative-caret-position="75">
<caret line="45" column="36" lean-forward="true" selection-start-line="45" selection-start-column="36" selection-end-line="45" selection-end-column="36" /> <caret line="5" column="10" lean-forward="false" selection-start-line="5" selection-start-column="10" selection-end-line="5" selection-end-column="10" />
<folding /> <folding>
<element signature="n#!!block;n#loadFbsFile#0" expanded="false" />
</folding>
</state> </state>
</provider> </provider>
</entry> </entry>

View File

@ -506,7 +506,7 @@ func (c *ClientConn) mainLoop() {
// Unsupported message type! Bad! // Unsupported message type! Bad!
break break
} }
logger.Debugf("ClientConn.MainLoop: got ServerMessage:%s", common.ServerMessageType(messageType)) logger.Infof("ClientConn.MainLoop: got ServerMessage:%s", common.ServerMessageType(messageType))
reader.SendMessageSeparator(common.ServerMessageType(messageType)) reader.SendMessageSeparator(common.ServerMessageType(messageType))
reader.PublishBytes([]byte{byte(messageType)}) reader.PublishBytes([]byte{byte(messageType)})

View File

@ -19,9 +19,13 @@ type FramebufferUpdateMessage struct {
} }
func (m *FramebufferUpdateMessage) String() string { func (m *FramebufferUpdateMessage) String() string {
str := fmt.Sprintf("FramebufferUpdateMessage (type=%d) Rects: \n", m.Type()) str := fmt.Sprintf("FramebufferUpdateMessage (type=%d) Rects: ", m.Type())
for _, rect := range m.Rectangles { for _, rect := range m.Rectangles {
str += rect.String() + "\n" str += rect.String() + "\n"
//if this is the last rect, break the loop
if rect.Enc.Type() == int32(common.EncLastRectPseudo) {
break
}
} }
return str return str
} }
@ -60,11 +64,11 @@ func (fbm *FramebufferUpdateMessage) Read(c common.IClientConn, r *common.RfbRea
// We must always support the raw encoding // We must always support the raw encoding
rawEnc := new(encodings.RawEncoding) rawEnc := new(encodings.RawEncoding)
encMap[rawEnc.Type()] = rawEnc encMap[rawEnc.Type()] = rawEnc
logger.Debugf("numrects= %d", numRects) logger.Infof("FrameBufferUpdateMessage.Read: numrects= %d", numRects)
rects := make([]common.Rectangle, numRects) rects := make([]common.Rectangle, numRects)
for i := uint16(0); i < numRects; i++ { for i := uint16(0); i < numRects; i++ {
logger.Debugf("###############rect################: %d\n", i) logger.Debugf("FrameBufferUpdateMessage.Read: ###############rect################: %d", i)
var encodingTypeInt int32 var encodingTypeInt int32
r.SendRectSeparator(-1) r.SendRectSeparator(-1)
@ -87,7 +91,7 @@ func (fbm *FramebufferUpdateMessage) Read(c common.IClientConn, r *common.RfbRea
encType := common.EncodingType(encodingTypeInt) encType := common.EncodingType(encodingTypeInt)
logger.Debugf("rect hdr data: enctype=%s, data: %s\n", encType, string(jBytes)) logger.Infof("FrameBufferUpdateMessage.Read: rect# %d, rect hdr data: enctype=%s, data: %s", i, encType, string(jBytes))
enc, supported := encMap[encodingTypeInt] enc, supported := encMap[encodingTypeInt]
if supported { if supported {
var err error var err error
@ -98,9 +102,14 @@ func (fbm *FramebufferUpdateMessage) Read(c common.IClientConn, r *common.RfbRea
} else { } else {
if strings.Contains(encType.String(), "Pseudo") { if strings.Contains(encType.String(), "Pseudo") {
rect.Enc = &encodings.PseudoEncoding{encodingTypeInt} rect.Enc = &encodings.PseudoEncoding{encodingTypeInt}
//if this is the last rect, break the for loop
if rect.Enc.Type() == int32(common.EncLastRectPseudo) {
break
}
} else { } else {
logger.Errorf("unsupported encoding type: %d, %s", encodingTypeInt, encType) logger.Errorf("FrameBufferUpdateMessage.Read: unsupported encoding type: %d, %s", encodingTypeInt, encType)
return nil, fmt.Errorf("unsupported encoding type: %d, %s", encodingTypeInt, encType) return nil, fmt.Errorf("FrameBufferUpdateMessage.Read: unsupported encoding type: %d, %s", encodingTypeInt, encType)
} }
} }
} }
@ -194,6 +203,42 @@ func (*BellMessage) Read(common.IClientConn, *common.RfbReadHelper) (common.Serv
return new(BellMessage), nil return new(BellMessage), nil
} }
type ServerFenceMessage byte
func (fbm *ServerFenceMessage) CopyTo(r io.Reader, w io.Writer, c common.IClientConn) error {
return nil
}
func (m *ServerFenceMessage) String() string {
return fmt.Sprintf("ServerFenceMessage (type=%d)", m.Type())
}
func (*ServerFenceMessage) Type() uint8 {
return uint8(common.ServerFence)
}
func (sf *ServerFenceMessage) Read(info common.IClientConn, c *common.RfbReadHelper) (common.ServerMessage, error) {
bytes := make([]byte, 3)
c.Read(bytes)
if _, err := c.Read(bytes); err != nil {
return nil, err
}
var flags uint32
if err := binary.Read(c, binary.BigEndian, &flags); err != nil {
return nil, err
}
var length uint8
if err := binary.Read(c, binary.BigEndian, &length); err != nil {
return nil, err
}
bytes = make([]byte, length)
if _, err := c.Read(bytes); err != nil {
return nil, err
}
return sf, nil
}
// ServerCutTextMessage indicates the server has new text in the cut buffer. // ServerCutTextMessage indicates the server has new text in the cut buffer.
// //
// See RFC 6143 Section 7.6.4 // See RFC 6143 Section 7.6.4

View File

@ -2,7 +2,6 @@ package common
import ( import (
"io" "io"
) )
type ClientMessageType uint8 type ClientMessageType uint8
@ -18,6 +17,7 @@ const (
KeyEventMsgType KeyEventMsgType
PointerEventMsgType PointerEventMsgType
ClientCutTextMsgType ClientCutTextMsgType
ClientFenceMsgType = 248
) )
// Color represents a single color in a color map. // Color represents a single color in a color map.

View File

@ -71,8 +71,8 @@ func (enct EncodingType) String() string {
return "EncJPEGQualityLevelPseudo2" return "EncJPEGQualityLevelPseudo2"
case EncJPEGQualityLevelPseudo1: case EncJPEGQualityLevelPseudo1:
return "EncJPEGQualityLevelPseudo1" return "EncJPEGQualityLevelPseudo1"
case EncColorPseudo: case EncCursorPseudo:
return "EncColorPseudo" return "EncCursorPseudo"
case EncDesktopSizePseudo: case EncDesktopSizePseudo:
return "EncDesktopSizePseudo" return "EncDesktopSizePseudo"
case EncLastRectPseudo: case EncLastRectPseudo:
@ -164,7 +164,7 @@ const (
EncJPEGQualityLevelPseudo3 EncodingType = -30 EncJPEGQualityLevelPseudo3 EncodingType = -30
EncJPEGQualityLevelPseudo2 EncodingType = -31 EncJPEGQualityLevelPseudo2 EncodingType = -31
EncJPEGQualityLevelPseudo1 EncodingType = -32 EncJPEGQualityLevelPseudo1 EncodingType = -32
EncColorPseudo EncodingType = -239 EncCursorPseudo EncodingType = -239
EncDesktopSizePseudo EncodingType = -223 EncDesktopSizePseudo EncodingType = -223
EncLastRectPseudo EncodingType = -224 EncLastRectPseudo EncodingType = -224
EncCompressionLevel10 EncodingType = -247 EncCompressionLevel10 EncodingType = -247

View File

@ -23,6 +23,7 @@ const (
SetColourMapEntries SetColourMapEntries
Bell Bell
ServerCutText ServerCutText
ServerFence = 248
) )
func (typ ServerMessageType) String() string { func (typ ServerMessageType) String() string {

View File

@ -0,0 +1,28 @@
package encodings
import (
"io"
"math"
"vncproxy/common"
)
type EncCursorPseudo struct {
}
func (pe *EncCursorPseudo) Type() int32 {
return int32(common.EncCursorPseudo)
}
func (z *EncCursorPseudo) WriteTo(w io.Writer) (n int, err error) {
return 0, nil
}
func (pe *EncCursorPseudo) Read(pf *common.PixelFormat, rect *common.Rectangle, r *common.RfbReadHelper) (common.Encoding, error) {
if rect.Width*rect.Height == 0 {
return pe, nil
}
bytesPixel := int(pf.BPP / 8) //calcTightBytePerPixel(pf)
r.ReadBytes(int(rect.Width*rect.Height) * bytesPixel)
mask := ((rect.Width + 7) / 8) * rect.Height
r.ReadBytes(int(math.Floor(float64(mask))))
return pe, nil
}

View File

@ -14,39 +14,109 @@ type Logger interface {
Fatal(v ...interface{}) Fatal(v ...interface{})
Fatalf(format string, v ...interface{}) Fatalf(format string, v ...interface{})
} }
type LogLevel int
func Debug(v ...interface{}) { const (
LogLevelDebug LogLevel = iota
LogLevelInfo
LogLevelWarn
LogLevelError
LogLevelFatal
)
type SimpleLogger struct {
level LogLevel
}
func (sl *SimpleLogger) Debug(v ...interface{}) {
if sl.level <= LogLevelDebug {
fmt.Print("[Debug] ") fmt.Print("[Debug] ")
fmt.Println(v...) fmt.Println(v...)
}
} }
func Debugf(format string, v ...interface{}) { func (sl *SimpleLogger) Debugf(format string, v ...interface{}) {
if sl.level <= LogLevelDebug {
fmt.Printf("[Debug] "+format+"\n", v...) fmt.Printf("[Debug] "+format+"\n", v...)
}
} }
func Info(v ...interface{}) { func (sl *SimpleLogger) Info(v ...interface{}) {
if sl.level <= LogLevelInfo {
fmt.Print("[Info] ") fmt.Print("[Info] ")
fmt.Println(v...) fmt.Println(v...)
}
} }
func Infof(format string, v ...interface{}) { func (sl *SimpleLogger) Infof(format string, v ...interface{}) {
if sl.level <= LogLevelInfo {
fmt.Printf("[Info] "+format+"\n", v...) fmt.Printf("[Info] "+format+"\n", v...)
}
} }
func Warn(v ...interface{}) { func (sl *SimpleLogger) Warn(v ...interface{}) {
if sl.level <= LogLevelWarn {
fmt.Print("[Warn] ") fmt.Print("[Warn] ")
fmt.Println(v...) fmt.Println(v...)
}
} }
func Warnf(format string, v ...interface{}) { func (sl *SimpleLogger) Warnf(format string, v ...interface{}) {
if sl.level <= LogLevelWarn {
fmt.Printf("[Warn] "+format+"\n", v...) fmt.Printf("[Warn] "+format+"\n", v...)
}
} }
func Error(v ...interface{}) { func (sl *SimpleLogger) Error(v ...interface{}) {
if sl.level <= LogLevelError {
fmt.Print("[Error] ") fmt.Print("[Error] ")
fmt.Println(v...) fmt.Println(v...)
}
} }
func Errorf(format string, v ...interface{}) { func (sl *SimpleLogger) Errorf(format string, v ...interface{}) {
if sl.level <= LogLevelError {
fmt.Printf("[Error] "+format+"\n", v...) fmt.Printf("[Error] "+format+"\n", v...)
}
} }
func Fatal(v ...interface{}) { func (sl *SimpleLogger) Fatal(v ...interface{}) {
if sl.level <= LogLevelFatal {
fmt.Print("[Fatal] ") fmt.Print("[Fatal] ")
fmt.Println(v...) fmt.Println(v...)
}
}
func (sl *SimpleLogger) Fatalf(format string, v ...interface{}) {
if sl.level <= LogLevelFatal {
fmt.Printf("[Fatal] "+format+"\n", v)
}
}
var simpleLogger = SimpleLogger{LogLevelInfo}
func Debug(v ...interface{}) {
simpleLogger.Debug(v...)
}
func Debugf(format string, v ...interface{}) {
simpleLogger.Debugf(format, v...)
}
func Info(v ...interface{}) {
simpleLogger.Info(v...)
}
func Infof(format string, v ...interface{}) {
simpleLogger.Infof(format, v...)
}
func Warn(v ...interface{}) {
simpleLogger.Warn(v...)
}
func Warnf(format string, v ...interface{}) {
simpleLogger.Warnf(format, v...)
}
func Error(v ...interface{}) {
simpleLogger.Error(v...)
}
func Errorf(format string, v ...interface{}) {
simpleLogger.Errorf(format, v...)
}
func Fatal(v ...interface{}) {
simpleLogger.Fatal(v...)
} }
func Fatalf(format string, v ...interface{}) { func Fatalf(format string, v ...interface{}) {
fmt.Printf("[Fatal] "+format+"\n", v) simpleLogger.Fatalf(format, v...)
} }

View File

@ -23,8 +23,12 @@ func main() {
//vncSrvMessagesChan := make(chan common.ServerMessage) //vncSrvMessagesChan := make(chan common.ServerMessage)
//rec := listeners.NewRecorder("c:/Users/betzalel/recording.rbs") rec, err := listeners.NewRecorder("c:/Users/betzalel/recording.rbs")
rec := listeners.NewRecorder("/Users/amitbet/vncRec/recording.rbs") //rec, err := listeners.NewRecorder("/Users/amitbet/vncRec/recording.rbs")
if err != nil {
logger.Errorf("error creating recorder: %s", err)
return
}
clientConn, err := client.NewClientConn(nc, clientConn, err := client.NewClientConn(nc,
&client.ClientConfig{ &client.ClientConfig{
@ -37,6 +41,7 @@ func main() {
if err != nil { if err != nil {
logger.Errorf("error creating client: %s", err) logger.Errorf("error creating client: %s", err)
return
} }
// err = clientConn.FramebufferUpdateRequest(false, 0, 0, 1024, 768) // err = clientConn.FramebufferUpdateRequest(false, 0, 0, 1024, 768)
// if err != nil { // if err != nil {

View File

@ -0,0 +1,81 @@
package player
import (
"encoding/binary"
"time"
"vncproxy/client"
"vncproxy/common"
"vncproxy/logger"
"vncproxy/server"
)
type FBSPlayListener struct {
Conn *server.ServerConn
Fbs *FbsReader
serverMessageMap map[uint8]common.ServerMessage
firstSegDone bool
startTime int
}
func NewFBSPlayListener(conn *server.ServerConn, r *FbsReader) *FBSPlayListener {
h := &FBSPlayListener{Conn: conn, Fbs: r}
cm := client.BellMessage(0)
h.serverMessageMap = make(map[uint8]common.ServerMessage)
h.serverMessageMap[0] = &client.FramebufferUpdateMessage{}
h.serverMessageMap[1] = &client.SetColorMapEntriesMessage{}
h.serverMessageMap[2] = &cm
h.serverMessageMap[3] = &client.ServerCutTextMessage{}
return h
}
func (handler *FBSPlayListener) Consume(seg *common.RfbSegment) error {
switch seg.SegmentType {
case common.SegmentFullyParsedClientMessage:
clientMsg := seg.Message.(common.ClientMessage)
logger.Debugf("ClientUpdater.Consume:(vnc-server-bound) got ClientMessage type=%s", clientMsg.Type())
switch clientMsg.Type() {
case common.FramebufferUpdateRequestMsgType:
if !handler.firstSegDone {
handler.firstSegDone = true
handler.startTime = int(time.Now().UnixNano() / int64(time.Millisecond))
}
handler.sendFbsMessage()
}
// server.FramebufferUpdateRequest:
}
return nil
}
func (h *FBSPlayListener) sendFbsMessage() {
var messageType uint8
//messages := make(map[uint8]common.ServerMessage)
fbs := h.Fbs
//conn := h.Conn
err := binary.Read(fbs, binary.BigEndian, &messageType)
if err != nil {
logger.Error("TestServer.NewConnHandler: Error in reading FBS segment: ", err)
return
}
//common.IClientConn{}
binary.Write(h.Conn, binary.BigEndian, messageType)
msg := h.serverMessageMap[messageType]
if msg == nil {
logger.Error("TestServer.NewConnHandler: Error unknown message type: ", messageType)
return
}
timeSinceStart := int(time.Now().UnixNano()/int64(time.Millisecond)) - h.startTime
timeToSleep := fbs.currentTimestamp - timeSinceStart
if timeToSleep > 0 {
time.Sleep(time.Duration(timeToSleep) * time.Millisecond)
}
err = msg.CopyTo(fbs, h.Conn, fbs)
if err != nil {
logger.Error("TestServer.NewConnHandler: Error in reading FBS segment: ", err)
return
}
}

View File

@ -1,84 +1,16 @@
package player package player
import ( import (
"encoding/binary"
"testing" "testing"
"time" "time"
"vncproxy/client"
"vncproxy/common" "vncproxy/common"
"vncproxy/encodings" "vncproxy/encodings"
"vncproxy/logger" "vncproxy/logger"
"vncproxy/server" "vncproxy/server"
) )
type ServerMessageHandler struct {
Conn *server.ServerConn
Fbs *FbsReader
serverMessageMap map[uint8]common.ServerMessage
firstSegDone bool
startTime int
}
func NewServerMessageHandler(conn *server.ServerConn, r *FbsReader) *ServerMessageHandler {
h := &ServerMessageHandler{Conn: conn, Fbs: r}
cm := client.BellMessage(0)
h.serverMessageMap = make(map[uint8]common.ServerMessage)
h.serverMessageMap[0] = &client.FramebufferUpdateMessage{}
h.serverMessageMap[1] = &client.SetColorMapEntriesMessage{}
h.serverMessageMap[2] = &cm
h.serverMessageMap[3] = &client.ServerCutTextMessage{}
return h
}
func (handler *ServerMessageHandler) Consume(seg *common.RfbSegment) error {
switch seg.SegmentType {
case common.SegmentFullyParsedClientMessage:
clientMsg := seg.Message.(common.ClientMessage)
logger.Debugf("ClientUpdater.Consume:(vnc-server-bound) got ClientMessage type=%s", clientMsg.Type())
switch clientMsg.Type() {
case common.FramebufferUpdateRequestMsgType:
if !handler.firstSegDone {
handler.firstSegDone = true
handler.startTime = int(time.Now().UnixNano() / int64(time.Millisecond))
}
handler.sendFbsMessage()
}
// server.FramebufferUpdateRequest:
}
return nil
}
func (h *ServerMessageHandler) sendFbsMessage() {
var messageType uint8
//messages := make(map[uint8]common.ServerMessage)
fbs := h.Fbs
//conn := h.Conn
err := binary.Read(fbs, binary.BigEndian, &messageType)
if err != nil {
logger.Error("TestServer.NewConnHandler: Error in reading FBS segment: ", err)
return
}
//common.IClientConn{}
binary.Write(h.Conn, binary.BigEndian, messageType)
msg := h.serverMessageMap[messageType]
if msg == nil {
logger.Error("TestServer.NewConnHandler: Error unknown message type: ", messageType)
return
}
timeSinceStart := int(time.Now().UnixNano()/int64(time.Millisecond)) - h.startTime
timeToSleep := fbs.currentTimestamp - timeSinceStart
if timeToSleep > 0 {
time.Sleep(time.Duration(timeToSleep) * time.Millisecond)
}
err = msg.CopyTo(fbs, h.Conn, fbs)
if err != nil {
logger.Error("TestServer.NewConnHandler: Error in reading FBS segment: ", err)
return
}
}
func loadFbsFile(filename string, conn *server.ServerConn) (*FbsReader, error) { func loadFbsFile(filename string, conn *server.ServerConn) (*FbsReader, error) {
fbs, err := NewFbsReader(filename) fbs, err := NewFbsReader(filename)
@ -117,12 +49,15 @@ func TestServer(t *testing.T) {
} }
cfg.NewConnHandler = func(cfg *server.ServerConfig, conn *server.ServerConn) error { cfg.NewConnHandler = func(cfg *server.ServerConfig, conn *server.ServerConn) error {
fbs, err := loadFbsFile("/Users/amitbet/Dropbox/recording.rbs", conn) //fbs, err := loadFbsFile("/Users/amitbet/Dropbox/recording.rbs", conn)
//fbs, err := loadFbsFile("/Users/amitbet/vncRec/recording.rbs", conn)
fbs, err := loadFbsFile("/Users/amitbet/vncRec/recording1500411789.rbs", conn)
if err != nil { if err != nil {
logger.Error("TestServer.NewConnHandler: Error in loading FBS: ", err) logger.Error("TestServer.NewConnHandler: Error in loading FBS: ", err)
return err return err
} }
conn.Listeners.AddListener(NewServerMessageHandler(conn, fbs)) conn.Listeners.AddListener(NewFBSPlayListener(conn, fbs))
return nil return nil
} }

View File

@ -69,7 +69,12 @@ func (vp *VncProxy) newServerConnHandler(cfg *server.ServerConfig, sconn *server
recFile := "recording" + strconv.FormatInt(time.Now().Unix(), 10) + ".rbs" recFile := "recording" + strconv.FormatInt(time.Now().Unix(), 10) + ".rbs"
recPath := path.Join(vp.recordingDir, recFile) recPath := path.Join(vp.recordingDir, recFile)
rec := listeners.NewRecorder(recPath) rec, err := listeners.NewRecorder(recPath)
if err != nil {
logger.Errorf("Proxy.newServerConnHandler can't open recorder save path: %s", recPath)
return err
}
session, err := vp.getTargetServerFromSession(sconn.SessionId) session, err := vp.getTargetServerFromSession(sconn.SessionId)
if err != nil { if err != nil {
logger.Errorf("Proxy.newServerConnHandler can't get session: %d", sconn.SessionId) logger.Errorf("Proxy.newServerConnHandler can't get session: %d", sconn.SessionId)
@ -113,13 +118,14 @@ func (vp *VncProxy) newServerConnHandler(cfg *server.ServerConfig, sconn *server
encs := []common.Encoding{ encs := []common.Encoding{
&encodings.RawEncoding{}, &encodings.RawEncoding{},
&encodings.TightEncoding{}, &encodings.TightEncoding{},
&encodings.EncCursorPseudo{},
//encodings.TightPngEncoding{}, //encodings.TightPngEncoding{},
//encodings.RREEncoding{}, &encodings.RREEncoding{},
//encodings.ZLibEncoding{}, &encodings.ZLibEncoding{},
//encodings.ZRLEEncoding{}, &encodings.ZRLEEncoding{},
//encodings.CopyRectEncoding{}, &encodings.CopyRectEncoding{},
//encodings.CoRREEncoding{}, &encodings.CoRREEncoding{},
//encodings.HextileEncoding{}, &encodings.HextileEncoding{},
} }
cconn.Encs = encs cconn.Encs = encs
//err = cconn.SetEncodings(encs) //err = cconn.SetEncodings(encs)

View File

@ -8,6 +8,7 @@ func TestProxy(t *testing.T) {
proxy := &VncProxy{ proxy := &VncProxy{
wsListeningUrl: "http://localhost:7777/", // empty = not listening on ws wsListeningUrl: "http://localhost:7777/", // empty = not listening on ws
recordingDir: "/Users/amitbet/vncRec", // empty = no recording recordingDir: "/Users/amitbet/vncRec", // empty = no recording
//recordingDir: "C:\\vncRec", // empty = no recording
targetServersPassword: "Ch_#!T@8", //empty = no auth targetServersPassword: "Ch_#!T@8", //empty = no auth
SingleSession: &VncSession{ SingleSession: &VncSession{
TargetHostname: "localhost", TargetHostname: "localhost",

View File

@ -193,6 +193,40 @@ func (msg *PointerEvent) Write(c io.Writer) error {
return nil return nil
} }
type ClientFence struct {
}
func (*ClientFence) Type() common.ClientMessageType {
return common.ClientFenceMsgType
}
func (cf *ClientFence) Read(c io.Reader) (common.ClientMessage, error) {
bytes := make([]byte, 3)
c.Read(bytes)
if _, err := c.Read(bytes); err != nil {
return nil, err
}
var flags uint32
if err := binary.Read(c, binary.BigEndian, &flags); err != nil {
return nil, err
}
var length uint8
if err := binary.Read(c, binary.BigEndian, &length); err != nil {
return nil, err
}
bytes = make([]byte, length)
if _, err := c.Read(bytes); err != nil {
return nil, err
}
return cf, nil
}
func (msg *ClientFence) Write(c io.Writer) error {
panic("not implemented!")
}
// ClientCutText holds the wire format message, sans the text field. // ClientCutText holds the wire format message, sans the text field.
type ClientCutText struct { type ClientCutText struct {
_ [3]byte // padding _ [3]byte // padding

View File

@ -197,7 +197,11 @@ func (c *ServerConn) handle() error {
return err return err
} }
logger.Debugf("ServerConn.Handle got ClientMessage: %s, %v", parsedMsg.Type(), parsedMsg) logger.Infof("ServerConn.Handle got ClientMessage: %s, %v", parsedMsg.Type(), parsedMsg)
//TODO: treat set encodings by allowing only supported encoding in proxy configurations
//// if parsedMsg.Type() == common.SetEncodingsMsgType{
//// c.cfg.Encodings
//// }
seg := &common.RfbSegment{ seg := &common.RfbSegment{
SegmentType: common.SegmentFullyParsedClientMessage, SegmentType: common.SegmentFullyParsedClientMessage,

View File

@ -88,6 +88,14 @@ func attachNewServerConn(c io.ReadWriter, cfg *ServerConfig, sessionId string) e
return err return err
} }
//run the handler for this new incoming connection from a vnc-client
//this is done before the init sequence to allow listening to server-init messages (and maybe even interception in the future)
err = cfg.NewConnHandler(cfg, conn)
if err != nil {
conn.Close()
return err
}
if err := ServerClientInitHandler(cfg, conn); err != nil { if err := ServerClientInitHandler(cfg, conn); err != nil {
conn.Close() conn.Close()
return err return err
@ -102,7 +110,6 @@ func attachNewServerConn(c io.ReadWriter, cfg *ServerConfig, sessionId string) e
if cfg.UseDummySession { if cfg.UseDummySession {
conn.SessionId = "dummySession" conn.SessionId = "dummySession"
} }
cfg.NewConnHandler(cfg, conn)
//go here will kill ws connections //go here will kill ws connections
conn.handle() conn.handle()

View File

@ -27,7 +27,7 @@ func getNowMillisec() int {
return int(time.Now().UnixNano() / int64(time.Millisecond)) return int(time.Now().UnixNano() / int64(time.Millisecond))
} }
func NewRecorder(saveFilePath string) *Recorder { func NewRecorder(saveFilePath string) (*Recorder, error) {
//delete file if it exists //delete file if it exists
if _, err := os.Stat(saveFilePath); err == nil { if _, err := os.Stat(saveFilePath); err == nil {
os.Remove(saveFilePath) os.Remove(saveFilePath)
@ -41,7 +41,7 @@ func NewRecorder(saveFilePath string) *Recorder {
rec.writer, err = os.OpenFile(saveFilePath, os.O_RDWR|os.O_CREATE, 0755) rec.writer, err = os.OpenFile(saveFilePath, os.O_RDWR|os.O_CREATE, 0755)
if err != nil { if err != nil {
logger.Errorf("unable to open file: %s, error: %v", saveFilePath, err) logger.Errorf("unable to open file: %s, error: %v", saveFilePath, err)
return nil return nil, err
} }
//buffer the channel so we don't halt the proxying flow for slow writes when under pressure //buffer the channel so we don't halt the proxying flow for slow writes when under pressure
@ -53,7 +53,7 @@ func NewRecorder(saveFilePath string) *Recorder {
} }
}() }()
return &rec return &rec, nil
} }
const versionMsg_3_3 = "RFB 003.003\n" const versionMsg_3_3 = "RFB 003.003\n"
@ -114,8 +114,8 @@ func (r *Recorder) Consume(data *common.RfbSegment) error {
//using async writes so if chan buffer overflows, proxy will not be affected //using async writes so if chan buffer overflows, proxy will not be affected
select { select {
case r.segmentChan <- data: case r.segmentChan <- data:
default: // default:
logger.Error("error: recorder queue is full") // logger.Error("error: recorder queue is full")
} }
return nil return nil