refactor client main loop, etc