Минюст США заявил об обезвреживании используемого ФСБ программного обеспечения
Федеральное бюро расследований обнаружило и обезвредило вредоносную программу под названием Snake («Змея»), которая, по его версии, использовалась ФСБ для кибершпионажа, говорится в заявлении американского Минюста. По сообщению ведомства, программа использовалась на протяжении почти 20 лет, чтобы похищать документы с сотен компьютерных систем как минимум в 50 странах
Федеральное бюро расследований (ФБР) обнаружило и обезвредило вредоносную программу под названием Snake («Змея»), которая, по его версии, использовалась российской ФСБ для кибершпионажа, говорится в сообщении американского Минюста.
Ведомство заявило о завершении операции, целью которой было разрушение глобальной пиринговой сети компьютеров, зараженных вредоносной программой Snake. Ее созданием, как считает правительство США, занималось подразделение 16-го Центра ФСБ, которое в документах называется Turla.
На протяжении почти 20 лет Turla использовала различные версии программы Snake, чтобы похищать документы с сотен компьютерных систем как минимум в 50 странах, в том числе у государств-членов НАТО, журналистов и других целей, интересующих власти России, утверждается в сообщении Минюста.
Чтобы обезвредить Snake, ФБР создало программу под названием PERSEUS, которая «направила работу российской вредоносной программы против нее самой», отмечает ведомство. Минюст США назвал Snake «одним из самых сложных инструментов для кибершпионажа, созданных Россией».
Как написать свою змейку на Java за 15 минут
В предыдущей статье мы писали сапёра за 15 минут, теперь займёмся классической змейкой.
В этот раз нам снова понадобятся:
- 15 минут свободного времени;
- Настроенная рабочая среда, т.е. JDK и IDE (например Eclipse);
- Библиотека LWJGL (версии 2.x.x) для работы с Open GL. Обратите внимание, что для LWJGL версий выше 3 потребуется написать код, отличающийся от того, что приведён в статье;
- Спрайты, т.е. картинки самой змеи и фрукта, который она будет есть. Можно чисто символически нарисовать самому, или скачать использовавшиеся при написании статьи.
Подключение библиотек
В прошлый раз у многих возникли с этим вопросом проблемы, поэтому мне показалось уместным посвятить этому немного времени. Во-первых, выше я дал ссылку на скачивание архива с библиотеками, которые использую я, чтобы не было путаницы с версиями и вопросов, где найти что-то. Папку из архива требуется поместить в папку проекта и подключить через вашу IDE.
Во-вторых, у многих пользователей InteliJ IDEA возникли проблемы как раз с их подключением. Я нашёл в сети следующий видеогайд:
После того, как я сделал всё в точности по нему, у меня библиотеки подключились корректно и всё заработало.
Работа с графикой
С этой стороны наша задача мало отличается от той, что мы выполняли при написании Сапёра. Снова создаём класс GUI, который будет хранить и обновлять состояние всех графических элементов. Если точнее:
- Класс будет выполнять инициализацию OpenGL:
initializeOpenGL()
///Class GUI private static void initializeOpenGL() < try < //Задаём размер будущего окна Display.setDisplayMode(new DisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT)); //Задаём имя будущего окна Display.setTitle(SCREEN_NAME); //Создаём окно Display.create(); >catch (LWJGLException e) < e.printStackTrace(); >glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0,SCREEN_WIDTH,0,SCREEN_HEIGHT,1,-1); glMatrixMode(GL_MODELVIEW); /* * Для поддержки текстур */ glEnable(GL_TEXTURE_2D); /* * Для поддержки прозрачности */ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* * Белый фоновый цвет */ glClearColor(1,1,1,1); >
Как вы можете видеть, здесь я уже использовал несколько констант. Для них был создан отдельный класс Constants с public static полями. Вот он целиком:
public class Constants < ///Размер игровой ячейки public static final int CELL_SIZE = 32; ///Размеры игрового поля в ячейках public static final int CELLS_COUNT_X = 20; public static final int CELLS_COUNT_Y = 20; ///Шанс появления ягод на старте в процентах. ///При выставленном значении спавнится 3-5 ягод. ///Не беспокойтесь, что значение слишком низкое, как минимум одна ягода создаётся отдельно. public static final int INITIAL_SPAWN_CHANCE = 1;//% ///В нашем случае змея проходит одну клетку за один фрейм. ///Значение 5 мне показалось оптимальным, но вы можете экспериментировать. public static final int FPS = 5; ///Константы для создания окна, названия достаточно говорящие. public static final int SCREEN_WIDTH =CELLS_COUNT_X*CELL_SIZE; public static final int SCREEN_HEIGHT = CELLS_COUNT_Y*CELL_SIZE; public static final String SCREEN_NAME = "Tproger's Snake"; >
Enum Sprite , который отвечает за подгрузку текстур, полностью идентичен тому, что мы писали для Сапёра, за исключением того, что нам нужно только две текстуры — для змеи и для ягод. Вот код:
public enum Sprite < ///Файлы с именами circle и cherries должны лежать по адресу /// %папка проекта%/res/ в расширении .png BODY("circle"), CHERRIES("cherries"); private Texture texture; private Sprite(String texturename)< try < this.texture = TextureLoader.getTexture("PNG", new FileInputStream(new File("res/"+texturename+".png"))); >catch (IOException e) < e.printStackTrace(); >> public Texture getTexture() < return this.texture; >>
Механика игры
Самое время поговорить о том, как наша змея будет, собственно, перемещаться. Вам наверняка доводилось видеть вывески, вокруг которых по кругу бегают огоньки? Разумеется, сами лампочки в них не перемещаются, просто каждый тик последняя гаснет, а первая зажигается. Таким же образом будет перемещаться и наша змея.
Несложно подсчитать, что каждая лампочка должна гореть столько тиков, какова длина “змеи”. Значит, мы должны сообщить клетке, в которую попадает змея, что она должна гореть определённое количество секунд, а каждый тик уменьшать это число у каждой клетки с ненулевым таймером, и менять спрайт, если змея из клетки уже выползла (т.е. таймер стал равен нулю). В случае же необходимости удлинить цепочку, достаточно просто не уменьшать время “горения” клеток на каком-то тике. Именно поэтому метод update() у классов Cell и GUI принимает параметр — если он равен false , значит, змея что-то съела.
Пишем класс клетки
public class Cell < private int x; private int y; private int state;/* 0 ->ячейка пуста >0 -> в ячейке тело змеи, которое будет там ещё N фреймов Что-то необычное: -1: Ягоды */ ///Конструктор просто выставляет начальные значения координат и состояния public Cell (int x, int y, int state) < this.x=x; this.y=y; this.state=state; >///==== Ничем не примечательные геттеры и сеттеры public int getX() < return x; >public int getY() < return y; >public int getHeight() < return CELL_SIZE; >public int getWidth() < return CELL_SIZE; >public int getState() < return this.state; >public void setState(int state) < this.state = state; >///==== ///Метод обновления клетки. Уменьшаем время "горения", если это необходимо public void update(boolean have_to_decrease) < if (have_to_decrease && this.state >0) < this.state--; >> ///Ячейка "думает" как она должна выглядеть public Sprite getSprite() < if(this.state >0)< ///Если в ней тело змеи -- как змея return Sprite.BODY; >else if(this.state==0)< ///Если в ней нет ничего -- никак выглядеть и не должна return null; >else < ///Иначе проходимся свитчем по возможным объектам. ///Так как это демо -- я добавил только ягоды switch(this.state)< default: return Sprite.CHERRIES; >> > >
Добавляем геттер и сеттер для состояния клетки поля в GUI
getState(x,y) < return cells[x][y].getState(); >setState(x,y,state)
Добавляем метод, создающий начальное поле в GUI
Просто инициализируем OpenGL, затем массив Cell[][] cells и заполняем последний клетками со случайным полем state .
При подготовке материала использовались источники:
https://www.forbes.ru/society/489020-minust-ssa-zaavil-ob-obezvrezivanii-ispol-zuemogo-fsb-programmnogo-obespecenia
https://tproger.ru/articles/java-15-mins-snake/